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.

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