Index: sys/net/pfvar.h =================================================================== --- sys/net/pfvar.h +++ sys/net/pfvar.h @@ -154,6 +154,8 @@ #define PF_RULES_RASSERT() rw_assert(&pf_rules_lock, RA_RLOCKED) #define PF_RULES_WASSERT() rw_assert(&pf_rules_lock, RA_WLOCKED) +extern struct sx pf_end_lock; + #define PF_MODVER 1 #define PFLOG_MODVER 1 #define PFSYNC_MODVER 1 Index: sys/netpfil/pf/pf.c =================================================================== --- sys/netpfil/pf/pf.c +++ sys/netpfil/pf/pf.c @@ -1428,8 +1428,9 @@ VNET_ITERATOR_DECL(vnet_iter); u_int idx = 0; + sx_xlock(&pf_end_lock); for (;;) { - tsleep(pf_purge_thread, 0, "pftm", hz / 10); + sx_sleep(pf_purge_thread, &pf_end_lock, 0, "pftm", hz / 10); VNET_LIST_RLOCK(); VNET_FOREACH(vnet_iter) { @@ -1438,6 +1439,7 @@ if (pf_end_threads) { pf_end_threads++; wakeup(pf_purge_thread); + sx_xunlock(&pf_end_lock); VNET_LIST_RUNLOCK(); kproc_exit(0); } Index: sys/netpfil/pf/pf_ioctl.c =================================================================== --- sys/netpfil/pf/pf_ioctl.c +++ sys/netpfil/pf/pf_ioctl.c @@ -201,6 +201,7 @@ struct rwlock pf_rules_lock; struct sx pf_ioctl_lock; +struct sx pf_end_lock; /* pfsync */ pfsync_state_import_t *pfsync_state_import_ptr = NULL; @@ -3730,6 +3731,7 @@ rw_init(&pf_rules_lock, "pf rulesets"); sx_init(&pf_ioctl_lock, "pf ioctl"); + sx_init(&pf_end_lock, "pf end thread"); pf_mtag_initialize(); @@ -3791,11 +3793,13 @@ /* Unload the root VNET */ pf_unload_vnet(); + sx_xlock(&pf_end_lock); pf_end_threads = 1; while (pf_end_threads < 2) { wakeup_one(pf_purge_thread); - tsleep(pf_purge_thread, 0, "pftmo", 0); + sx_sleep(pf_purge_thread, &pf_end_lock, 0, "pftmo", 0); } + sx_xunlock(&pf_end_lock); if (pf_dev != NULL) destroy_dev(pf_dev); @@ -3804,6 +3808,7 @@ rw_destroy(&pf_rules_lock); sx_destroy(&pf_ioctl_lock); + sx_destroy(&pf_end_lock); return (error); }