Date: Mon, 4 Aug 2014 22:32:17 +0000 (UTC) From: Navdeep Parhar <np@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r269537 - head/sys/dev/cxgbe Message-ID: <53e009f1.5fa7.3ca65627@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: np Date: Mon Aug 4 22:32:16 2014 New Revision: 269537 URL: http://svnweb.freebsd.org/changeset/base/269537 Log: cxgbe(4): Do not run any sleepable code in the SIOCSIFFLAGS handler when IFF_PROMISC or IFF_ALLMULTI is being flipped. bpf(4) holds its global mutex around ifpromisc in at least the bpf_dtor path. MFC after: 3 days Modified: head/sys/dev/cxgbe/t4_main.c Modified: head/sys/dev/cxgbe/t4_main.c ============================================================================== --- head/sys/dev/cxgbe/t4_main.c Mon Aug 4 22:31:09 2014 (r269536) +++ head/sys/dev/cxgbe/t4_main.c Mon Aug 4 22:32:16 2014 (r269537) @@ -1178,7 +1178,7 @@ cxgbe_init(void *arg) static int cxgbe_ioctl(struct ifnet *ifp, unsigned long cmd, caddr_t data) { - int rc = 0, mtu, flags; + int rc = 0, mtu, flags, can_sleep; struct port_info *pi = ifp->if_softc; struct adapter *sc = pi->adapter; struct ifreq *ifr = (struct ifreq *)data; @@ -1203,7 +1203,10 @@ cxgbe_ioctl(struct ifnet *ifp, unsigned break; case SIOCSIFFLAGS: - rc = begin_synchronized_op(sc, pi, SLEEP_OK | INTR_OK, "t4flg"); + can_sleep = 0; +redo_sifflags: + rc = begin_synchronized_op(sc, pi, + can_sleep ? (SLEEP_OK | INTR_OK) : HOLD_LOCK, "t4flg"); if (rc) return (rc); @@ -1212,15 +1215,32 @@ cxgbe_ioctl(struct ifnet *ifp, unsigned flags = pi->if_flags; if ((ifp->if_flags ^ flags) & (IFF_PROMISC | IFF_ALLMULTI)) { + if (can_sleep == 1) { + end_synchronized_op(sc, 0); + can_sleep = 0; + goto redo_sifflags; + } rc = update_mac_settings(ifp, XGMAC_PROMISC | XGMAC_ALLMULTI); } - } else + } else { + if (can_sleep == 0) { + end_synchronized_op(sc, LOCK_HELD); + can_sleep = 1; + goto redo_sifflags; + } rc = cxgbe_init_synchronized(pi); + } pi->if_flags = ifp->if_flags; - } else if (ifp->if_drv_flags & IFF_DRV_RUNNING) + } else if (ifp->if_drv_flags & IFF_DRV_RUNNING) { + if (can_sleep == 0) { + end_synchronized_op(sc, LOCK_HELD); + can_sleep = 1; + goto redo_sifflags; + } rc = cxgbe_uninit_synchronized(pi); - end_synchronized_op(sc, 0); + } + end_synchronized_op(sc, can_sleep ? 0 : LOCK_HELD); break; case SIOCADDMULTI:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?53e009f1.5fa7.3ca65627>