svn commit: r269537 - head/sys/dev/cxgbe
Navdeep Parhar
np at FreeBSD.org
Mon Aug 4 22:32:17 UTC 2014
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:
More information about the svn-src-all
mailing list