NET_LOCK() should raise IPL before acquiring the lock, and NET_UNLOCK()
should restore the level after releasing the lock. Otherwise, lock
recursion can occur, most likely right after the splx(). An example:

nd6_slowtimo  <- NET_LOCK()
timeout_run
softclock
softintr_dispatch
dosoftint
interrupt
k_intr
if_netisr  <- NET_LOCK()
taskq_thread

OK?

Index: sys/systm.h
===================================================================
RCS file: src/sys/sys/systm.h,v
retrieving revision 1.120
diff -u -p -r1.120 systm.h
--- sys/systm.h 19 Dec 2016 08:36:50 -0000      1.120
+++ sys/systm.h 23 Dec 2016 05:59:26 -0000
@@ -297,14 +297,14 @@ extern struct rwlock netlock;
 
 #define        NET_LOCK(s)                                                     
\
 do {                                                                   \
-       rw_enter_write(&netlock);                                       \
        s = splsoftnet();                                               \
+       rw_enter_write(&netlock);                                       \
 } while (0)
 
-#define        NET_UNLOCK(s)                                           \
+#define        NET_UNLOCK(s)                                                   
\
 do {                                                                   \
-       splx(s);                                                        \
        rw_exit_write(&netlock);                                        \
+       splx(s);                                                        \
 } while (0)
 
 #define        NET_ASSERT_LOCKED()                                             
\

Reply via email to