diff options
| author | Jesper Dangaard Brouer <brouer@redhat.com> | 2018-01-03 05:25:59 -0500 |
|---|---|---|
| committer | Alexei Starovoitov <ast@kernel.org> | 2018-01-05 18:21:22 -0500 |
| commit | 8bf5c4ee1889308ccd396fdfd40ac94129ee419f (patch) | |
| tree | f5ebb48e1047c44b97e6d650775699d019bd1324 | |
| parent | 27e95e3648910c81a0840aa10dde77323795519e (diff) | |
tun: setup xdp_rxq_info
Driver hook points for xdp_rxq_info:
* reg : tun_attach
* unreg: __tun_detach
I've done some manual testing of this tun driver, but I would
appriciate good review and someone else running their use-case tests,
as I'm not 100% sure I understand the tfile->detached semantics.
V2: Removed the skb_array_cleanup() call from V1 by request from Jason Wang.
Cc: Jason Wang <jasowang@redhat.com>
Cc: "Michael S. Tsirkin" <mst@redhat.com>
Cc: Willem de Bruijn <willemb@google.com>
Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com>
Reviewed-by: Jason Wang <jasowang@redhat.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
| -rw-r--r-- | drivers/net/tun.c | 24 |
1 files changed, 23 insertions, 1 deletions
diff --git a/drivers/net/tun.c b/drivers/net/tun.c index e367d6310353..e7c5f4b2a9a6 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c | |||
| @@ -180,6 +180,7 @@ struct tun_file { | |||
| 180 | struct list_head next; | 180 | struct list_head next; |
| 181 | struct tun_struct *detached; | 181 | struct tun_struct *detached; |
| 182 | struct skb_array tx_array; | 182 | struct skb_array tx_array; |
| 183 | struct xdp_rxq_info xdp_rxq; | ||
| 183 | }; | 184 | }; |
| 184 | 185 | ||
| 185 | struct tun_flow_entry { | 186 | struct tun_flow_entry { |
| @@ -687,8 +688,10 @@ static void __tun_detach(struct tun_file *tfile, bool clean) | |||
| 687 | tun->dev->reg_state == NETREG_REGISTERED) | 688 | tun->dev->reg_state == NETREG_REGISTERED) |
| 688 | unregister_netdevice(tun->dev); | 689 | unregister_netdevice(tun->dev); |
| 689 | } | 690 | } |
| 690 | if (tun) | 691 | if (tun) { |
| 691 | skb_array_cleanup(&tfile->tx_array); | 692 | skb_array_cleanup(&tfile->tx_array); |
| 693 | xdp_rxq_info_unreg(&tfile->xdp_rxq); | ||
| 694 | } | ||
| 692 | sock_put(&tfile->sk); | 695 | sock_put(&tfile->sk); |
| 693 | } | 696 | } |
| 694 | } | 697 | } |
| @@ -728,11 +731,13 @@ static void tun_detach_all(struct net_device *dev) | |||
| 728 | tun_napi_del(tun, tfile); | 731 | tun_napi_del(tun, tfile); |
| 729 | /* Drop read queue */ | 732 | /* Drop read queue */ |
| 730 | tun_queue_purge(tfile); | 733 | tun_queue_purge(tfile); |
| 734 | xdp_rxq_info_unreg(&tfile->xdp_rxq); | ||
| 731 | sock_put(&tfile->sk); | 735 | sock_put(&tfile->sk); |
| 732 | } | 736 | } |
| 733 | list_for_each_entry_safe(tfile, tmp, &tun->disabled, next) { | 737 | list_for_each_entry_safe(tfile, tmp, &tun->disabled, next) { |
| 734 | tun_enable_queue(tfile); | 738 | tun_enable_queue(tfile); |
| 735 | tun_queue_purge(tfile); | 739 | tun_queue_purge(tfile); |
| 740 | xdp_rxq_info_unreg(&tfile->xdp_rxq); | ||
| 736 | sock_put(&tfile->sk); | 741 | sock_put(&tfile->sk); |
| 737 | } | 742 | } |
| 738 | BUG_ON(tun->numdisabled != 0); | 743 | BUG_ON(tun->numdisabled != 0); |
| @@ -784,6 +789,22 @@ static int tun_attach(struct tun_struct *tun, struct file *file, | |||
| 784 | 789 | ||
| 785 | tfile->queue_index = tun->numqueues; | 790 | tfile->queue_index = tun->numqueues; |
| 786 | tfile->socket.sk->sk_shutdown &= ~RCV_SHUTDOWN; | 791 | tfile->socket.sk->sk_shutdown &= ~RCV_SHUTDOWN; |
| 792 | |||
| 793 | if (tfile->detached) { | ||
| 794 | /* Re-attach detached tfile, updating XDP queue_index */ | ||
| 795 | WARN_ON(!xdp_rxq_info_is_reg(&tfile->xdp_rxq)); | ||
| 796 | |||
| 797 | if (tfile->xdp_rxq.queue_index != tfile->queue_index) | ||
| 798 | tfile->xdp_rxq.queue_index = tfile->queue_index; | ||
| 799 | } else { | ||
| 800 | /* Setup XDP RX-queue info, for new tfile getting attached */ | ||
| 801 | err = xdp_rxq_info_reg(&tfile->xdp_rxq, | ||
| 802 | tun->dev, tfile->queue_index); | ||
| 803 | if (err < 0) | ||
| 804 | goto out; | ||
| 805 | err = 0; | ||
| 806 | } | ||
| 807 | |||
| 787 | rcu_assign_pointer(tfile->tun, tun); | 808 | rcu_assign_pointer(tfile->tun, tun); |
| 788 | rcu_assign_pointer(tun->tfiles[tun->numqueues], tfile); | 809 | rcu_assign_pointer(tun->tfiles[tun->numqueues], tfile); |
| 789 | tun->numqueues++; | 810 | tun->numqueues++; |
| @@ -1508,6 +1529,7 @@ static struct sk_buff *tun_build_skb(struct tun_struct *tun, | |||
| 1508 | xdp.data = buf + pad; | 1529 | xdp.data = buf + pad; |
| 1509 | xdp_set_data_meta_invalid(&xdp); | 1530 | xdp_set_data_meta_invalid(&xdp); |
| 1510 | xdp.data_end = xdp.data + len; | 1531 | xdp.data_end = xdp.data + len; |
| 1532 | xdp.rxq = &tfile->xdp_rxq; | ||
| 1511 | orig_data = xdp.data; | 1533 | orig_data = xdp.data; |
| 1512 | act = bpf_prog_run_xdp(xdp_prog, &xdp); | 1534 | act = bpf_prog_run_xdp(xdp_prog, &xdp); |
| 1513 | 1535 | ||
