Paul and Antoine reported that, since the NET_LOCK() went in, doing a channel scan with iwm(4) and iwn(4) freezes X.
This is a deadlock due to the fact that wireless drivers sleep during a long time holding the NET_LOCK() while the X server tries to communicate with unix sockets, that still need the NET_LOCK(). The obvious solution to this problem is to not hold the NET_LOCK() for unix socket related operations. We're working on that. However since hardware ioctl(2) can sleep there's no problem to release the NET_LOCK() there. This is true for all ioctls that are not modifying any stack state (address, multicast group, etc). Hence the diff below that should fix the problem in a generic way. ok? Index: netinet/in.c =================================================================== RCS file: /cvs/src/sys/netinet/in.c,v retrieving revision 1.133 diff -u -p -r1.133 in.c --- netinet/in.c 20 Dec 2016 12:35:38 -0000 1.133 +++ netinet/in.c 6 Feb 2017 11:15:45 -0000 @@ -390,7 +390,11 @@ in_ioctl(u_long cmd, caddr_t data, struc default: if (ifp->if_ioctl == NULL) return (EOPNOTSUPP); - return ((*ifp->if_ioctl)(ifp, cmd, data)); + /* XXXSMP breaks atomicity */ + rw_exit_write(&netlock); + error = ((*ifp->if_ioctl)(ifp, cmd, data)); + rw_enter_write(&netlock); + return (error); } return (0); } Index: netinet6/in6.c =================================================================== RCS file: /cvs/src/sys/netinet6/in6.c,v retrieving revision 1.197 diff -u -p -r1.197 in6.c --- netinet6/in6.c 5 Feb 2017 16:04:14 -0000 1.197 +++ netinet6/in6.c 6 Feb 2017 11:16:09 -0000 @@ -190,6 +190,7 @@ in6_ioctl(u_long cmd, caddr_t data, stru struct in6_ifaddr *ia6 = NULL; struct in6_aliasreq *ifra = (struct in6_aliasreq *)data; struct sockaddr_in6 *sa6; + int error; if (ifp == NULL) return (EOPNOTSUPP); @@ -469,9 +470,13 @@ in6_ioctl(u_long cmd, caddr_t data, stru break; default: - if (ifp == NULL || ifp->if_ioctl == 0) + if (ifp->if_ioctl == NULL) return (EOPNOTSUPP); - return ((*ifp->if_ioctl)(ifp, cmd, data)); + /* XXXSMP breaks atomicity */ + rw_exit_write(&netlock); + error = ((*ifp->if_ioctl)(ifp, cmd, data)); + rw_enter_write(&netlock); + return (error); } return (0); Index: dev/pci/if_iwm.c =================================================================== RCS file: /cvs/src/sys/dev/pci/if_iwm.c,v retrieving revision 1.162 diff -u -p -r1.162 if_iwm.c --- dev/pci/if_iwm.c 4 Feb 2017 19:20:59 -0000 1.162 +++ dev/pci/if_iwm.c 6 Feb 2017 11:15:56 -0000 @@ -6133,18 +6133,13 @@ iwm_ioctl(struct ifnet *ifp, u_long cmd, struct ifreq *ifr; int s, err = 0; - /* XXXSMP breaks atomicity */ - rw_exit_write(&netlock); - /* * Prevent processes from entering this function while another * process is tsleep'ing in it. */ err = rw_enter(&sc->ioctl_rwl, RW_WRITE | RW_INTR); - if (err) { - rw_enter_write(&netlock); + if (err) return err; - } s = splnet(); @@ -6190,7 +6185,6 @@ iwm_ioctl(struct ifnet *ifp, u_long cmd, splx(s); rw_exit(&sc->ioctl_rwl); - rw_enter_write(&netlock); return err; }