On 04/07/17(Tue) 01:49, Hrvoje Popovski wrote:
> Hi all,
>
> with cvs tree (with or without bluhm@ uipc_syscalls patch) fetched few
> minutes ago i'm getting panic below. would show witness be of any good?
>
>
> Setup is quite standard, carp, pf, pfsync, isakmpd ....
Thanks for the report. IPsec is here again, this time with pfsync.
> # panic: kernel diagnostic assertion "_kernel_lock_held()" failed: file
> "/usr/src/sys/netinet/ip_output.c", line 234
Diff below should prevent and document the problem.
Index: net/pf.c
===================================================================
RCS file: /cvs/src/sys/net/pf.c,v
retrieving revision 1.1036
diff -u -p -r1.1036 pf.c
--- net/pf.c 3 Jul 2017 08:11:21 -0000 1.1036
+++ net/pf.c 4 Jul 2017 10:31:06 -0000
@@ -1203,14 +1203,31 @@ void
pf_purge_thread(void *v)
{
int nloops = 0, s;
+#ifdef IPSEC
+ int locked = 0;
+#endif /* IPSEC */
KERNEL_UNLOCK();
- NET_LOCK(s);
for (;;) {
- rwsleep(pf_purge_thread, &netlock, PWAIT, "pftm", 1 * hz);
+ tsleep(pf_purge_thread, PWAIT, "pftm", 1 * hz);
+#ifdef IPSEC
+ /*
+ * At least pfsync can send traffic.
+ *
+ * IPsec is not ready to run without KERNEL_LOCK(). So all
+ * the traffic on your machine is punished if you have IPsec
+ * enabled.
+ */
+ extern int ipsec_in_use;
+ if (ipsec_in_use) {
+ KERNEL_LOCK();
+ locked = 1;
+ }
+#endif /* IPSEC */
+ NET_LOCK(s);
PF_LOCK();
/* process a fraction of the state table every second */
pf_purge_expired_states(1 + (pf_status.states
@@ -1229,8 +1246,13 @@ pf_purge_thread(void *v)
pf_purge_expired_fragments();
nloops = 0;
}
+ NET_UNLOCK(s);
+
+#ifdef IPSEC
+ if (locked)
+ KERNEL_UNLOCK();
+#endif /* IPSEC */
}
- NET_UNLOCK(s);
}
int32_t