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

Reply via email to