> Date: Mon, 2 May 2016 11:27:36 +0200
> From: Martin Pieuchot <[email protected]>
>
> 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.
And sparc64 (with em, vnet and bridge). No real performance testing
done, but I noticed no issues.
> So I'm looking for oks.
ok kettenis@
> > 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 <[email protected]>
> > - *
> > - * 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);
> >
> >
>
>