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

Reply via email to