On 18/04/16(Mon) 10:50, Martin Pieuchot wrote: > The current goal of the Network SMP effort is to have a single CPU > process the IP forwarding path in a process context without holding > the KERNEL_LOCK(). To achieve this goal we're progressively moving > code from the softnet interrupt context to the if_input_task. In > the end we'll completely get rid of this soft-interrupt. > > So now would be a good time to know if moving all the code currently > run in a soft-interrupt context to a task uncovers any bug. I'm > happily running the diff below on amd64 and macppc, it even gives me > a small performance boost. > > I'd appreciate more tests especially on exotic archs.
So far this has been tested on amd64, i386, powerpc, mips64 and sparc. So I'm looking for oks. > Index: net/if.c > =================================================================== > RCS file: /cvs/src/sys/net/if.c,v > retrieving revision 1.429 > diff -u -p -r1.429 if.c > --- net/if.c 16 Mar 2016 12:08:09 -0000 1.429 > +++ net/if.c 18 Apr 2016 08:00:08 -0000 > @@ -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 mbu > 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) > { > @@ -803,6 +806,50 @@ if_input_process(void *xmq) > if_put(ifp); > } > splx(s); > +} > + > +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 > Index: net/netisr.c > =================================================================== > RCS file: net/netisr.c > diff -N net/netisr.c > --- net/netisr.c 8 Jan 2016 13:53:24 -0000 1.10 > +++ /dev/null 1 Jan 1970 00:00:00 -0000 > @@ -1,74 +0,0 @@ > -/* > - * Copyright (c) 2010 Owain G. Ainsworth <o...@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"); > -} > Index: net/netisr.h > =================================================================== > RCS file: /cvs/src/sys/net/netisr.h,v > retrieving revision 1.44 > diff -u -p -r1.44 netisr.h > --- net/netisr.h 8 Jan 2016 13:53:24 -0000 1.44 > +++ net/netisr.h 18 Apr 2016 07:52:28 -0000 > @@ -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,16 +75,11 @@ 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 */ > Index: kern/init_main.c > =================================================================== > RCS file: /cvs/src/sys/kern/init_main.c,v > retrieving revision 1.249 > diff -u -p -r1.249 init_main.c > --- kern/init_main.c 19 Mar 2016 12:04:15 -0000 1.249 > +++ kern/init_main.c 18 Apr 2016 07:48:40 -0000 > @@ -394,7 +394,6 @@ main(void *framep) > * until everything is ready. > */ > s = splnet(); > - netisr_init(); > domaininit(); > splx(s); > >