Hi,
The current workaround to disable parallel IPsec does not work.
Variable nettaskqs must not change at runtime. Interface input
queues choose the thread during init with ifiq_softnet = net_tq().
So it cannot be modified after pfkeyv2_send() sets the first SA in
kernel. Also changing the calculation in net_tq() may call task_del()
with a different taskq than task_add().
Instead of restricting the index of the first softnet task, use an
exclusive lock.
For now just move the comment. We can still decide if a write net
lock or kernel lock is better.
ok?
bluhm
Index: net/if.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/net/if.c,v
retrieving revision 1.642
diff -u -p -r1.642 if.c
--- net/if.c 30 Jun 2021 13:23:33 -0000 1.642
+++ net/if.c 20 Jul 2021 13:38:51 -0000
@@ -834,6 +834,12 @@ if_input_process(struct ifnet *ifp, stru
* to PF globals, pipex globals, unicast and multicast addresses
* lists and the socket layer.
*/
+
+ /*
+ * XXXSMP IPsec data structures are not ready to be accessed
+ * by multiple network threads in parallel. In this case
+ * use an exclusive lock.
+ */
NET_LOCK();
while ((m = ml_dequeue(ml)) != NULL)
(*ifp->if_input)(ifp, m);
@@ -3311,17 +3317,14 @@ 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;
+ static int nettaskqs;
+
+ if (nettaskqs == 0)
+ nettaskqs = min(NET_TASKQ, ncpus);
t = nettqmp[ifindex % nettaskqs];
Index: net/pfkeyv2.c
===================================================================
RCS file: /data/mirror/openbsd/cvs/src/sys/net/pfkeyv2.c,v
retrieving revision 1.218
diff -u -p -r1.218 pfkeyv2.c
--- net/pfkeyv2.c 14 Jul 2021 22:39:26 -0000 1.218
+++ net/pfkeyv2.c 20 Jul 2021 12:48:30 -0000
@@ -2019,14 +2019,6 @@ 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;
}