Attach: splassert: sowakeup: want 1 have 0 Starting stack trace... sowakeup() at sowakeup+0x41 sorwakeup() at sorwakeup+0xb4 route_input() at route_input+0x2d7 if_attach() at if_attach+0x58 xnf_attach() at xnf_attach+0x45f config_attach() at config_attach+0x1bc xen_attach_device() at xen_attach_device+0x146 xen_hotplug() at xen_hotplug+0x23f taskq_thread() at taskq_thread+0x6c end trace frame: 0x0, count: 248 End of stack trace.
Detach: splassert: sowakeup: want 1 have 0 Starting stack trace... sowakeup() at sowakeup+0x41 sorwakeup() at sorwakeup+0xb4 route_input() at route_input+0x2d7 if_detach() at if_detach+0x27e xnf_detach() at xnf_detach+0x4d config_detach() at config_detach+0x13c xen_hotplug() at xen_hotplug+0x2e5 taskq_thread() at taskq_thread+0x6c end trace frame: 0x0, count: 249 End of stack trace. xnf2 detached The taskq running xen_hotplug is KERNEL_LOCK'ed. The diff below solves the issue, but is it any good? diff --git sys/net/if.c sys/net/if.c index 1e103564710..a5c25b89560 100644 --- sys/net/if.c +++ sys/net/if.c @@ -525,11 +525,11 @@ if_attach(struct ifnet *ifp) { int s; - s = splsoftnet(); + NET_LOCK(s); if_attach_common(ifp); TAILQ_INSERT_TAIL(&ifnet, ifp, if_list); if_attachsetup(ifp); - splx(s); + NET_UNLOCK(s); } void @@ -941,6 +941,7 @@ if_detach(struct ifnet *ifp) ifq_clr_oactive(&ifp->if_snd); + rw_enter_write(&netlock); s = splnet(); /* Other CPUs must not have a reference before we start destroying. */ if_idxmap_remove(ifp); @@ -1017,6 +1018,7 @@ if_detach(struct ifnet *ifp) /* Announce that the interface is gone. */ rt_ifannouncemsg(ifp, IFAN_DEPARTURE); splx(s); + rw_exit_write(&netlock); ifq_destroy(&ifp->if_snd); }