Author: davidcs
Date: Tue May  9 01:01:41 2017
New Revision: 317996
URL: https://svnweb.freebsd.org/changeset/base/317996

Log:
  Fix bug where MTX_DEF lock was held while taskqueue_drain() was invoked.
  Check IFF_DRV_RUNNING flag is set prior to calling ql_hw_set_multi()
  
  MFC after:3 days

Modified:
  head/sys/dev/qlxgbe/ql_isr.c
  head/sys/dev/qlxgbe/ql_os.c

Modified: head/sys/dev/qlxgbe/ql_isr.c
==============================================================================
--- head/sys/dev/qlxgbe/ql_isr.c        Tue May  9 00:51:10 2017        
(r317995)
+++ head/sys/dev/qlxgbe/ql_isr.c        Tue May  9 01:01:41 2017        
(r317996)
@@ -987,7 +987,8 @@ ql_isr(void *arg)
 
        fp = &ha->tx_fp[idx];
 
-       if (fp->fp_taskqueue != NULL)
+       if ((fp->fp_taskqueue != NULL) &&
+               (ifp->if_drv_flags & IFF_DRV_RUNNING))
                taskqueue_enqueue(fp->fp_taskqueue, &fp->fp_task);
 
        return;

Modified: head/sys/dev/qlxgbe/ql_os.c
==============================================================================
--- head/sys/dev/qlxgbe/ql_os.c Tue May  9 00:51:10 2017        (r317995)
+++ head/sys/dev/qlxgbe/ql_os.c Tue May  9 01:01:41 2017        (r317996)
@@ -925,7 +925,9 @@ qla_set_multi(qla_host_t *ha, uint32_t a
        if_maddr_runlock(ifp);
 
        QLA_LOCK(ha);
-       ret = ql_hw_set_multi(ha, mta, mcnt, add_multi);
+       if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
+               ret = ql_hw_set_multi(ha, mta, mcnt, add_multi);
+       }
        QLA_UNLOCK(ha);
 
        return (ret);
@@ -1031,20 +1033,16 @@ qla_ioctl(struct ifnet *ifp, u_long cmd,
                QL_DPRINT4(ha, (ha->pci_dev,
                        "%s: %s (0x%lx)\n", __func__, "SIOCADDMULTI", cmd));
 
-               if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
-                       if (qla_set_multi(ha, 1))
-                               ret = EINVAL;
-               }
+               if (qla_set_multi(ha, 1))
+                       ret = EINVAL;
                break;
 
        case SIOCDELMULTI:
                QL_DPRINT4(ha, (ha->pci_dev,
                        "%s: %s (0x%lx)\n", __func__, "SIOCDELMULTI", cmd));
 
-               if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
-                       if (qla_set_multi(ha, 0))
-                               ret = EINVAL;
-               }
+               if (qla_set_multi(ha, 0))
+                       ret = EINVAL;
                break;
 
        case SIOCSIFMEDIA:
@@ -1529,9 +1527,9 @@ qla_stop(qla_host_t *ha)
 
        ha->flags.qla_interface_up = 0;
 
+       QLA_UNLOCK(ha);
        qla_drain_fp_taskqueues(ha);
-
-       ql_hw_stop_rcv(ha);
+       QLA_LOCK(ha);
 
        ql_del_hw_if(ha);
 
@@ -1922,8 +1920,6 @@ qla_error_recovery(void *context, int pe
                ha->hw.imd_compl = 1;
                qla_mdelay(__func__, 300);
 
-               ql_hw_stop_rcv(ha);
-
                ifp->if_drv_flags &= ~(IFF_DRV_OACTIVE | IFF_DRV_RUNNING);
 
                for (i = 0; i < ha->hw.num_sds_rings; i++) {
@@ -1943,6 +1939,8 @@ qla_error_recovery(void *context, int pe
 
         QLA_UNLOCK(ha);
 
+       qla_drain_fp_taskqueues(ha);
+
        if ((ha->pci_func & 0x1) == 0) {
 
                if (!ha->msg_from_peer) {
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to