Date: Tue, 22 Apr 2014 20:19:10 +0000 (UTC) From: "George V. Neville-Neil" <gnn@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r264772 - head/sys/dev/sfxge Message-ID: <201404222019.s3MKJA4l012224@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: gnn Date: Tue Apr 22 20:19:09 2014 New Revision: 264772 URL: http://svnweb.freebsd.org/changeset/base/264772 Log: Check that port is started when MAC filter is set The MAC filter set may be called without softc_lock held in the case of SIOCADDMULTI and SIOCDELMULTI ioctls. The ioctl handler checks IFF_DRV_RUNNING flag which implies port started, but it is not guaranteed to remain. softc_lock shared lock can't be held in the case of these ioctls processing, since it results in failure where kernel complains that non-sleepable lock is held in sleeping thread. Both problems are repeatable on LAG with LACP proto bring up. Submitted by: Andrew Rybchenko <Andrew.Rybchenko at oktetlabs.ru> Sponsored by: Solarflare Communications, Inc. MFC after: 2 weeks Modified: head/sys/dev/sfxge/sfxge_port.c Modified: head/sys/dev/sfxge/sfxge_port.c ============================================================================== --- head/sys/dev/sfxge/sfxge_port.c Tue Apr 22 20:17:05 2014 (r264771) +++ head/sys/dev/sfxge/sfxge_port.c Tue Apr 22 20:19:09 2014 (r264772) @@ -320,10 +320,21 @@ sfxge_mac_filter_set(struct sfxge_softc struct sfxge_port *port = &sc->port; int rc; - KASSERT(port->init_state == SFXGE_PORT_STARTED, ("port not started")); - mtx_lock(&port->lock); - rc = sfxge_mac_filter_set_locked(sc); + /* + * The function may be called without softc_lock held in the + * case of SIOCADDMULTI and SIOCDELMULTI ioctls. ioctl handler + * checks IFF_DRV_RUNNING flag which implies port started, but + * it is not guaranteed to remain. softc_lock shared lock can't + * be held in the case of these ioctls processing, since it + * results in failure where kernel complains that non-sleepable + * lock is held in sleeping thread. Both problems are repeatable + * on LAG with LACP proto bring up. + */ + if (port->init_state == SFXGE_PORT_STARTED) + rc = sfxge_mac_filter_set_locked(sc); + else + rc = 0; mtx_unlock(&port->lock); return rc; }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201404222019.s3MKJA4l012224>