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

Reply via email to