svn commit: r312782 - head/sys/net
Kristof Provost
kp at FreeBSD.org
Wed Jan 25 21:25:27 UTC 2017
Author: kp
Date: Wed Jan 25 21:25:26 2017
New Revision: 312782
URL: https://svnweb.freebsd.org/changeset/base/312782
Log:
bridge: Release the bridge lock when calling bridge_set_ifcap()
This calls ioctl() handlers for the different interfaces in the bridge.
These handlers expect to get called in an ioctl context where it's safe
for them to sleep. We may not sleep with the bridge lock held.
However, we still need to protect the interface list, to ensure it
doesn't get changed while we iterate over it.
Use BRIDGE_XLOCK(), which prevents bridge members from being removed.
Adding bridge members is safe, because it uses LIST_INSERT_HEAD().
This caused panics when adding xen interfaces to a bridge.
PR: 216304
Reviewed by: ae
MFC after: 1 week
Sponsored by: RootBSD
Differential Revision: https://reviews.freebsd.org/D9290
Modified:
head/sys/net/if_bridge.c
head/sys/net/if_bridgevar.h
Modified: head/sys/net/if_bridge.c
==============================================================================
--- head/sys/net/if_bridge.c Wed Jan 25 21:05:48 2017 (r312781)
+++ head/sys/net/if_bridge.c Wed Jan 25 21:25:26 2017 (r312782)
@@ -909,14 +909,18 @@ bridge_mutecaps(struct bridge_softc *sc)
mask &= bif->bif_savedcaps;
}
+ BRIDGE_XLOCK(sc);
LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
enabled = bif->bif_ifp->if_capenable;
enabled &= ~BRIDGE_IFCAPS_STRIP;
/* strip off mask bits and enable them again if allowed */
enabled &= ~BRIDGE_IFCAPS_MASK;
enabled |= mask;
+ BRIDGE_UNLOCK(sc);
bridge_set_ifcap(sc, bif, enabled);
+ BRIDGE_LOCK(sc);
}
+ BRIDGE_XDROP(sc);
}
@@ -927,6 +931,8 @@ bridge_set_ifcap(struct bridge_softc *sc
struct ifreq ifr;
int error;
+ BRIDGE_UNLOCK_ASSERT(sc);
+
bzero(&ifr, sizeof(ifr));
ifr.ifr_reqcap = set;
Modified: head/sys/net/if_bridgevar.h
==============================================================================
--- head/sys/net/if_bridgevar.h Wed Jan 25 21:05:48 2017 (r312781)
+++ head/sys/net/if_bridgevar.h Wed Jan 25 21:25:26 2017 (r312782)
@@ -280,6 +280,7 @@ struct ifbpstpconf {
#define BRIDGE_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx)
#define BRIDGE_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx)
#define BRIDGE_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->sc_mtx, MA_OWNED)
+#define BRIDGE_UNLOCK_ASSERT(_sc) mtx_assert(&(_sc)->sc_mtx, MA_NOTOWNED)
#define BRIDGE_LOCK2REF(_sc, _err) do { \
mtx_assert(&(_sc)->sc_mtx, MA_OWNED); \
if ((_sc)->sc_iflist_xcnt > 0) \
More information about the svn-src-all
mailing list