summaryrefslogtreecommitdiffstats
path: root/drivers/net/tun.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/tun.c')
-rw-r--r--drivers/net/tun.c23
1 files changed, 14 insertions, 9 deletions
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 729686babbf3..50e9cc19023a 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -181,6 +181,7 @@ struct tun_file {
181 }; 181 };
182 struct napi_struct napi; 182 struct napi_struct napi;
183 bool napi_enabled; 183 bool napi_enabled;
184 bool napi_frags_enabled;
184 struct mutex napi_mutex; /* Protects access to the above napi */ 185 struct mutex napi_mutex; /* Protects access to the above napi */
185 struct list_head next; 186 struct list_head next;
186 struct tun_struct *detached; 187 struct tun_struct *detached;
@@ -313,9 +314,10 @@ static int tun_napi_poll(struct napi_struct *napi, int budget)
313} 314}
314 315
315static void tun_napi_init(struct tun_struct *tun, struct tun_file *tfile, 316static void tun_napi_init(struct tun_struct *tun, struct tun_file *tfile,
316 bool napi_en) 317 bool napi_en, bool napi_frags)
317{ 318{
318 tfile->napi_enabled = napi_en; 319 tfile->napi_enabled = napi_en;
320 tfile->napi_frags_enabled = napi_en && napi_frags;
319 if (napi_en) { 321 if (napi_en) {
320 netif_napi_add(tun->dev, &tfile->napi, tun_napi_poll, 322 netif_napi_add(tun->dev, &tfile->napi, tun_napi_poll,
321 NAPI_POLL_WEIGHT); 323 NAPI_POLL_WEIGHT);
@@ -335,9 +337,9 @@ static void tun_napi_del(struct tun_file *tfile)
335 netif_napi_del(&tfile->napi); 337 netif_napi_del(&tfile->napi);
336} 338}
337 339
338static bool tun_napi_frags_enabled(const struct tun_struct *tun) 340static bool tun_napi_frags_enabled(const struct tun_file *tfile)
339{ 341{
340 return READ_ONCE(tun->flags) & IFF_NAPI_FRAGS; 342 return tfile->napi_frags_enabled;
341} 343}
342 344
343#ifdef CONFIG_TUN_VNET_CROSS_LE 345#ifdef CONFIG_TUN_VNET_CROSS_LE
@@ -792,7 +794,7 @@ static void tun_detach_all(struct net_device *dev)
792} 794}
793 795
794static int tun_attach(struct tun_struct *tun, struct file *file, 796static int tun_attach(struct tun_struct *tun, struct file *file,
795 bool skip_filter, bool napi) 797 bool skip_filter, bool napi, bool napi_frags)
796{ 798{
797 struct tun_file *tfile = file->private_data; 799 struct tun_file *tfile = file->private_data;
798 struct net_device *dev = tun->dev; 800 struct net_device *dev = tun->dev;
@@ -865,7 +867,7 @@ static int tun_attach(struct tun_struct *tun, struct file *file,
865 tun_enable_queue(tfile); 867 tun_enable_queue(tfile);
866 } else { 868 } else {
867 sock_hold(&tfile->sk); 869 sock_hold(&tfile->sk);
868 tun_napi_init(tun, tfile, napi); 870 tun_napi_init(tun, tfile, napi, napi_frags);
869 } 871 }
870 872
871 tun_set_real_num_queues(tun); 873 tun_set_real_num_queues(tun);
@@ -1708,7 +1710,7 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
1708 int err; 1710 int err;
1709 u32 rxhash = 0; 1711 u32 rxhash = 0;
1710 int skb_xdp = 1; 1712 int skb_xdp = 1;
1711 bool frags = tun_napi_frags_enabled(tun); 1713 bool frags = tun_napi_frags_enabled(tfile);
1712 1714
1713 if (!(tun->dev->flags & IFF_UP)) 1715 if (!(tun->dev->flags & IFF_UP))
1714 return -EIO; 1716 return -EIO;
@@ -2533,7 +2535,8 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
2533 return err; 2535 return err;
2534 2536
2535 err = tun_attach(tun, file, ifr->ifr_flags & IFF_NOFILTER, 2537 err = tun_attach(tun, file, ifr->ifr_flags & IFF_NOFILTER,
2536 ifr->ifr_flags & IFF_NAPI); 2538 ifr->ifr_flags & IFF_NAPI,
2539 ifr->ifr_flags & IFF_NAPI_FRAGS);
2537 if (err < 0) 2540 if (err < 0)
2538 return err; 2541 return err;
2539 2542
@@ -2631,7 +2634,8 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
2631 (ifr->ifr_flags & TUN_FEATURES); 2634 (ifr->ifr_flags & TUN_FEATURES);
2632 2635
2633 INIT_LIST_HEAD(&tun->disabled); 2636 INIT_LIST_HEAD(&tun->disabled);
2634 err = tun_attach(tun, file, false, ifr->ifr_flags & IFF_NAPI); 2637 err = tun_attach(tun, file, false, ifr->ifr_flags & IFF_NAPI,
2638 ifr->ifr_flags & IFF_NAPI_FRAGS);
2635 if (err < 0) 2639 if (err < 0)
2636 goto err_free_flow; 2640 goto err_free_flow;
2637 2641
@@ -2780,7 +2784,8 @@ static int tun_set_queue(struct file *file, struct ifreq *ifr)
2780 ret = security_tun_dev_attach_queue(tun->security); 2784 ret = security_tun_dev_attach_queue(tun->security);
2781 if (ret < 0) 2785 if (ret < 0)
2782 goto unlock; 2786 goto unlock;
2783 ret = tun_attach(tun, file, false, tun->flags & IFF_NAPI); 2787 ret = tun_attach(tun, file, false, tun->flags & IFF_NAPI,
2788 tun->flags & IFF_NAPI_FRAGS);
2784 } else if (ifr->ifr_flags & IFF_DETACH_QUEUE) { 2789 } else if (ifr->ifr_flags & IFF_DETACH_QUEUE) {
2785 tun = rtnl_dereference(tfile->tun); 2790 tun = rtnl_dereference(tfile->tun);
2786 if (!tun || !(tun->flags & IFF_MULTI_QUEUE) || tfile->detached) 2791 if (!tun || !(tun->flags & IFF_MULTI_QUEUE) || tfile->detached)