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 <[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);
>
>