From owner-svn-src-stable-11@freebsd.org Wed Feb 1 20:27:39 2017 Return-Path: Delivered-To: svn-src-stable-11@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id AFC6CCCCA85; Wed, 1 Feb 2017 20:27:39 +0000 (UTC) (envelope-from kp@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 653E21925; Wed, 1 Feb 2017 20:27:39 +0000 (UTC) (envelope-from kp@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id v11KRcXl070069; Wed, 1 Feb 2017 20:27:38 GMT (envelope-from kp@FreeBSD.org) Received: (from kp@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id v11KRciL070067; Wed, 1 Feb 2017 20:27:38 GMT (envelope-from kp@FreeBSD.org) Message-Id: <201702012027.v11KRciL070067@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: kp set sender to kp@FreeBSD.org using -f From: Kristof Provost Date: Wed, 1 Feb 2017 20:27:38 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org Subject: svn commit: r313050 - stable/11/sys/net X-SVN-Group: stable-11 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-11@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for only the 11-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 01 Feb 2017 20:27:39 -0000 Author: kp Date: Wed Feb 1 20:27:38 2017 New Revision: 313050 URL: https://svnweb.freebsd.org/changeset/base/313050 Log: MFC 312782 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 Sponsored by: RootBSD Differential Revision: https://reviews.freebsd.org/D9290 Modified: stable/11/sys/net/if_bridge.c stable/11/sys/net/if_bridgevar.h Directory Properties: stable/11/ (props changed) Modified: stable/11/sys/net/if_bridge.c ============================================================================== --- stable/11/sys/net/if_bridge.c Wed Feb 1 20:27:07 2017 (r313049) +++ stable/11/sys/net/if_bridge.c Wed Feb 1 20:27:38 2017 (r313050) @@ -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: stable/11/sys/net/if_bridgevar.h ============================================================================== --- stable/11/sys/net/if_bridgevar.h Wed Feb 1 20:27:07 2017 (r313049) +++ stable/11/sys/net/if_bridgevar.h Wed Feb 1 20:27:38 2017 (r313050) @@ -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) \