aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorAndrey Konovalov <andreyknvl@google.com>2016-12-01 10:34:40 +0100
committerDavid S. Miller <davem@davemloft.net>2016-12-06 22:24:59 -0500
commitd4aea20d889e05575bb331a3dadf176176f7d631 (patch)
treeb70dc69799ec8cf5db0b5d2ad24e52901e57b815 /drivers
parentMerge branch 'w83977af_ir-neatening' (diff)
downloadlinux-dev-d4aea20d889e05575bb331a3dadf176176f7d631.tar.xz
linux-dev-d4aea20d889e05575bb331a3dadf176176f7d631.zip
tun: Use netif_receive_skb instead of netif_rx
This patch changes tun.c to call netif_receive_skb instead of netif_rx when a packet is received (if CONFIG_4KSTACKS is not enabled to avoid stack exhaustion). The difference between the two is that netif_rx queues the packet into the backlog, and netif_receive_skb proccesses the packet in the current context. This patch is required for syzkaller [1] to collect coverage from packet receive paths, when a packet being received through tun (syzkaller collects coverage per process in the process context). As mentioned by Eric this change also speeds up tun/tap. As measured by Peter it speeds up his closed-loop single-stream tap/OVS benchmark by about 23%, from 700k packets/second to 867k packets/second. A similar patch was introduced back in 2010 [2, 3], but the author found out that the patch doesn't help with the task he had in mind (for cgroups to shape network traffic based on the original process) and decided not to go further with it. The main concern back then was about possible stack exhaustion with 4K stacks. [1] https://github.com/google/syzkaller [2] https://www.spinics.net/lists/netdev/thrd440.html#130570 [3] https://www.spinics.net/lists/netdev/msg130570.html Signed-off-by: Andrey Konovalov <andreyknvl@google.com> Acked-by: Jason Wang <jasowang@redhat.com> Acked-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/tun.c6
1 files changed, 6 insertions, 0 deletions
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index a3ac8636f3ba..a569e61bc1d9 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -1286,7 +1286,13 @@ static ssize_t tun_get_user(struct tun_struct *tun, struct tun_file *tfile,
skb_probe_transport_header(skb, 0);
rxhash = skb_get_hash(skb);
+#ifndef CONFIG_4KSTACKS
+ local_bh_disable();
+ netif_receive_skb(skb);
+ local_bh_enable();
+#else
netif_rx_ni(skb);
+#endif
stats = get_cpu_ptr(tun->pcpu_stats);
u64_stats_update_begin(&stats->syncp);