Trying to grab the NET_LOCK() while holding an ifp reference is wrong. This creates deadlock as found by Hrvoje Popovski. The reason is that if_detach() sleeps holding the NET_LOCK() while waiting for others threads to release their reference.
Diff below fixes the linkstate vs if_detach() deadlock. ok? Index: net/if.c =================================================================== RCS file: /cvs/src/sys/net/if.c,v retrieving revision 1.499 diff -u -p -r1.499 if.c --- net/if.c 28 May 2017 12:51:33 -0000 1.499 +++ net/if.c 28 May 2017 16:23:16 -0000 @@ -1559,15 +1559,14 @@ if_linkstate_task(void *xifidx) struct ifnet *ifp; int s; - ifp = if_get(ifidx); - if (ifp == NULL) - return; - NET_LOCK(s); - if_linkstate(ifp); - NET_UNLOCK(s); + ifp = if_get(ifidx); + if (ifp != NULL) + if_linkstate(ifp); if_put(ifp); + + NET_UNLOCK(s); } void