We're experimenting with 2 threads processing input packets.  That's
good enough to improve forwarding performance and finally run pf_test()
in parallel.  However IPsec is not ready for that.  Until somebody takes
care of IPsec here's the solution: stay with a single thread.

Diff below implements this hack.  Like for the previous release, as soon
as you enable IPsec all your traffic gets punished.

This is a no-op for the moment since we only have a single network
taskq, but it allows us to experiment with the PF_LOCK() and start
splitting the use upcoming diff.

While here I renamed the taskq to reflect the fact that it doesn't
grab the KERNEL_LOCK() by default, following the ``systqmq'' notation. 

ok?

Index: net/pfkeyv2.c
===================================================================
RCS file: /cvs/src/sys/net/pfkeyv2.c,v
retrieving revision 1.172
diff -u -p -r1.172 pfkeyv2.c
--- net/pfkeyv2.c       3 Nov 2017 16:23:20 -0000       1.172
+++ net/pfkeyv2.c       8 Nov 2017 09:54:13 -0000
@@ -1767,6 +1767,14 @@ pfkeyv2_send(struct socket *so, void *me
                        }
                        TAILQ_INSERT_HEAD(&ipsec_policy_head, ipo, ipo_list);
                        ipsec_in_use++;
+                       /*
+                        * XXXSMP IPsec data structures are not ready to be
+                        * accessed by multiple Network threads in parallel,
+                        * so force all packets to be processed by the first
+                        * one.
+                        */
+                       extern int nettaskqs;
+                       nettaskqs = 1;
                } else {
                        ipo->ipo_last_searched = ipo->ipo_flags = 0;
                }
Index: net/if.c
===================================================================
RCS file: /cvs/src/sys/net/if.c,v
retrieving revision 1.523
diff -u -p -r1.523 if.c
--- net/if.c    4 Nov 2017 16:58:46 -0000       1.523
+++ net/if.c    8 Nov 2017 09:50:39 -0000
@@ -227,8 +227,8 @@ int ifq_congestion;
 
 int             netisr;
 
-#define        SOFTNET_TASKS   1
-struct taskq   *softnettq[SOFTNET_TASKS];
+#define        NET_TASKQ       1
+struct taskq   *nettqmp[NET_TASKQ];
 
 struct task if_input_task_locked = TASK_INITIALIZER(if_netisr, NULL);
 
@@ -254,10 +254,10 @@ ifinit(void)
 
        timeout_set(&net_tick_to, net_tick, &net_tick_to);
 
-       for (i = 0; i < SOFTNET_TASKS; i++) {
-               softnettq[i] = taskq_create("softnet", 1, IPL_NET, 
TASKQ_MPSAFE);
-               if (softnettq[i] == NULL)
-                       panic("unable to create softnet taskq");
+       for (i = 0; i < NET_TASKQ; i++) {
+               nettqmp[i] = taskq_create("softnet", 1, IPL_NET, TASKQ_MPSAFE);
+               if (nettqmp[i] == NULL)
+                       panic("unable to create network taskq %d", i);
        }
 
        net_tick(&net_tick_to);
@@ -2924,12 +2924,19 @@ unhandled_af(int af)
        panic("unhandled af %d", af);
 }
 
+/*
+ * XXXSMP This tunable is here to work around the fact that IPsec
+ * globals aren't ready to be accessed by multiple threads in
+ * parallel.
+ */
+int             nettaskqs = NET_TASKQ;
+
 struct taskq *
 net_tq(unsigned int ifindex)
 {
        struct taskq *t = NULL;
 
-       t = softnettq[ifindex % SOFTNET_TASKS];
+       t = nettqmp[ifindex % nettaskqs];
 
        return (t);
 }

Reply via email to