svn commit: r264772 - head/sys/dev/sfxge

George V. Neville-Neil gnn at FreeBSD.org
Tue Apr 22 20:19:10 UTC 2014


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;
 }


More information about the svn-src-head mailing list