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