diff options
author | 2016-05-03 14:52:39 +0000 | |
---|---|---|
committer | 2016-05-03 14:52:39 +0000 | |
commit | 72cad57c530700bc0ee61bd93860a3d2f898f8b0 (patch) | |
tree | 934dc9d745ddad6a604f0777250238c45937bcce | |
parent | support doas (diff) | |
download | wireguard-openbsd-72cad57c530700bc0ee61bd93860a3d2f898f8b0.tar.xz wireguard-openbsd-72cad57c530700bc0ee61bd93860a3d2f898f8b0.zip |
Stop using a soft-interrupt context to process incoming network packets.
Use a new task that runs holding the KERNEL_LOCK to execute mp-unsafe
code. Our current goal is to progressively move input functions to the
unlocked task.
This gives a small performance boost confirmed by Hrvoje Popovski's
IPv4 forwarding measurement:
before: after:
send receive send receive
400kpps 400kpps 400kpps 400kpps
500kpps 500kpps 500kpps 500kpps
600kpps 600kpps 600kpps 600kpps
650kpps 650kpps 650kpps 640kpps
700kpps 700kpps 700kpps 700kpps
720kpps 640kpps 720kpps 710kpps
800kpps 640kpps 800kpps 650kpps
1.4Mpps 570kpps 1.4Mpps 590kpps
14Mpps 570kpps 14Mpps 590kpps
ok kettenis@, bluhm@, dlg@
-rw-r--r-- | sys/conf/files | 3 | ||||
-rw-r--r-- | sys/kern/init_main.c | 3 | ||||
-rw-r--r-- | sys/net/if.c | 65 | ||||
-rw-r--r-- | sys/net/netisr.c | 74 | ||||
-rw-r--r-- | sys/net/netisr.h | 14 |
5 files changed, 65 insertions, 94 deletions
diff --git a/sys/conf/files b/sys/conf/files index d22604bc13b..a061c7f0a0e 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -1,4 +1,4 @@ -# $OpenBSD: files,v 1.618 2016/04/25 20:09:14 tedu Exp $ +# $OpenBSD: files,v 1.619 2016/05/03 14:52:39 mpi Exp $ # $NetBSD: files,v 1.87 1996/05/19 17:17:50 jonathan Exp $ # @(#)files.newconf 7.5 (Berkeley) 5/10/93 @@ -763,7 +763,6 @@ file net/if_spppsubr.c sppp file net/if_loop.c loop file net/if_media.c ifmedia file net/if_ppp.c ppp needs-count -file net/netisr.c file net/ppp_tty.c ppp file net/bsd-comp.c ppp_bsdcomp file net/ppp-deflate.c ppp_deflate diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c index 312bd87e1ea..61110b51abb 100644 --- a/sys/kern/init_main.c +++ b/sys/kern/init_main.c @@ -1,4 +1,4 @@ -/* $OpenBSD: init_main.c,v 1.249 2016/03/19 12:04:15 natano Exp $ */ +/* $OpenBSD: init_main.c,v 1.250 2016/05/03 14:52:39 mpi Exp $ */ /* $NetBSD: init_main.c,v 1.84.4.1 1996/06/02 09:08:06 mrg Exp $ */ /* @@ -394,7 +394,6 @@ main(void *framep) * until everything is ready. */ s = splnet(); - netisr_init(); domaininit(); splx(s); diff --git a/sys/net/if.c b/sys/net/if.c index fbe239d38a0..55cbda3382e 100644 --- a/sys/net/if.c +++ b/sys/net/if.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if.c,v 1.429 2016/03/16 12:08:09 dlg Exp $ */ +/* $OpenBSD: if.c,v 1.430 2016/05/03 14:52:39 mpi Exp $ */ /* $NetBSD: if.c,v 1.35 1996/05/07 05:26:04 thorpej Exp $ */ /* @@ -64,9 +64,12 @@ #include "bpfilter.h" #include "bridge.h" #include "carp.h" +#include "ether.h" #include "pf.h" +#include "pfsync.h" +#include "ppp.h" +#include "pppoe.h" #include "trunk.h" -#include "ether.h" #include <sys/param.h> #include <sys/systm.h> @@ -148,6 +151,7 @@ int if_group_egress_build(void); void if_watchdog_task(void *); void if_input_process(void *); +void if_netisr(void *); #ifdef DDB void ifa_print_all(void); @@ -216,13 +220,15 @@ void net_tick(void *); int net_livelocked(void); int ifq_congestion; -struct taskq *softnettq; +int netisr; +struct taskq *softnettq; + +struct mbuf_queue if_input_queue = MBUF_QUEUE_INITIALIZER(8192, IPL_NET); +struct task if_input_task = TASK_INITIALIZER(if_input_process, &if_input_queue); +struct task if_input_task_locked = TASK_INITIALIZER(if_netisr, NULL); /* * Network interface utility routines. - * - * Routines with ifa_ifwith* names take sockaddr *'s as - * parameters. */ void ifinit(void) @@ -590,9 +596,6 @@ if_enqueue(struct ifnet *ifp, struct mbuf *m) return (0); } -struct mbuf_queue if_input_queue = MBUF_QUEUE_INITIALIZER(8192, IPL_NET); -struct task if_input_task = TASK_INITIALIZER(if_input_process, &if_input_queue); - void if_input(struct ifnet *ifp, struct mbuf_list *ml) { @@ -806,6 +809,50 @@ if_input_process(void *xmq) } void +if_netisr(void *unused) +{ + int n, t = 0; + int s; + + KERNEL_LOCK(); + s = splsoftnet(); + + while ((n = netisr) != 0) { + sched_pause(); + + atomic_clearbits_int(&netisr, n); + + if (n & (1 << NETISR_IP)) + ipintr(); +#ifdef INET6 + if (n & (1 << NETISR_IPV6)) + ip6intr(); +#endif +#if NPPP > 0 + if (n & (1 << NETISR_PPP)) + pppintr(); +#endif +#if NBRIDGE > 0 + if (n & (1 << NETISR_BRIDGE)) + bridgeintr(); +#endif +#if NPPPOE > 0 + if (n & (1 << NETISR_PPPOE)) + pppoeintr(); +#endif + t |= n; + } + +#if NPFSYNC > 0 + if (t & (1 << NETISR_PFSYNC)) + pfsyncintr(); +#endif + + splx(s); + KERNEL_UNLOCK(); +} + +void if_deactivate(struct ifnet *ifp) { int s; diff --git a/sys/net/netisr.c b/sys/net/netisr.c deleted file mode 100644 index 7b6475be1b8..00000000000 --- a/sys/net/netisr.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2010 Owain G. Ainsworth <oga@openbsd.org> - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ -#include <sys/param.h> -#include <sys/systm.h> - -#include <net/netisr.h> - -#include <machine/intr.h> - -#include "ppp.h" -#include "bridge.h" -#include "pppoe.h" -#include "pfsync.h" - -void netintr(void *); - -int netisr; -void *netisr_intr; - -void -netintr(void *unused) -{ - int n, t = 0; - - while ((n = netisr) != 0) { - atomic_clearbits_int(&netisr, n); - - if (n & (1 << NETISR_IP)) - ipintr(); -#ifdef INET6 - if (n & (1 << NETISR_IPV6)) - ip6intr(); -#endif -#if NPPP > 0 - if (n & (1 << NETISR_PPP)) - pppintr(); -#endif -#if NBRIDGE > 0 - if (n & (1 << NETISR_BRIDGE)) - bridgeintr(); -#endif -#if NPPPOE > 0 - if (n & (1 << NETISR_PPPOE)) - pppoeintr(); -#endif - t |= n; - } - -#if NPFSYNC > 0 - if (t & (1 << NETISR_PFSYNC)) - pfsyncintr(); -#endif -} - -void -netisr_init(void) -{ - netisr_intr = softintr_establish(IPL_SOFTNET, netintr, NULL); - if (netisr_intr == NULL) - panic("can't establish softnet handler"); -} diff --git a/sys/net/netisr.h b/sys/net/netisr.h index 482c7c8ce00..5c709f5b76d 100644 --- a/sys/net/netisr.h +++ b/sys/net/netisr.h @@ -1,4 +1,4 @@ -/* $OpenBSD: netisr.h,v 1.44 2016/01/08 13:53:24 mpi Exp $ */ +/* $OpenBSD: netisr.h,v 1.45 2016/05/03 14:52:39 mpi Exp $ */ /* $NetBSD: netisr.h,v 1.12 1995/08/12 23:59:24 mycroft Exp $ */ /* @@ -61,7 +61,12 @@ #ifndef _LOCORE #ifdef _KERNEL + +#include <sys/task.h> +#include <sys/atomic.h> + extern int netisr; /* scheduling bits for network */ +extern struct task if_input_task_locked; void ipintr(void); void ip6intr(void); @@ -70,17 +75,12 @@ void bridgeintr(void); void pppoeintr(void); void pfsyncintr(void); -#include <machine/atomic.h> - -extern void *netisr_intr; #define schednetisr(anisr) \ do { \ atomic_setbits_int(&netisr, (1 << (anisr))); \ - softintr_schedule(netisr_intr); \ + task_add(softnettq, &if_input_task_locked); \ } while (/* CONSTCOND */0) -void netisr_init(void); - #endif /* _KERNEL */ #endif /*_LOCORE */ |