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;
 }
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to