]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/net/sfc/efx.c
sfc: Use a separate workqueue for resets
[linux-2.6-omap-h63xx.git] / drivers / net / sfc / efx.c
index 7b2015f9e46994407c0fef9c0bcee02b3918ce49..7b2a8186623244da041ec8baa683d075f021c232 100644 (file)
@@ -1762,7 +1762,7 @@ void efx_schedule_reset(struct efx_nic *efx, enum reset_type type)
 
        efx->reset_pending = method;
 
-       queue_work(efx->workqueue, &efx->reset_work);
+       queue_work(efx->reset_workqueue, &efx->reset_work);
 }
 
 /**************************************************************************
@@ -1907,14 +1907,28 @@ static int efx_init_struct(struct efx_nic *efx, struct efx_nic_type *type,
                goto fail1;
        }
 
+       efx->reset_workqueue = create_singlethread_workqueue("sfc_reset");
+       if (!efx->reset_workqueue) {
+               rc = -ENOMEM;
+               goto fail2;
+       }
+
        return 0;
 
+ fail2:
+       destroy_workqueue(efx->workqueue);
+       efx->workqueue = NULL;
+
  fail1:
        return rc;
 }
 
 static void efx_fini_struct(struct efx_nic *efx)
 {
+       if (efx->reset_workqueue) {
+               destroy_workqueue(efx->reset_workqueue);
+               efx->reset_workqueue = NULL;
+       }
        if (efx->workqueue) {
                destroy_workqueue(efx->workqueue);
                efx->workqueue = NULL;
@@ -1977,7 +1991,7 @@ static void efx_pci_remove(struct pci_dev *pci_dev)
         * scheduled from this point because efx_stop_all() has been
         * called, we are no longer registered with driverlink, and
         * the net_device's have been removed. */
-       flush_workqueue(efx->workqueue);
+       flush_workqueue(efx->reset_workqueue);
 
        efx_pci_remove_main(efx);
 
@@ -2098,7 +2112,7 @@ static int __devinit efx_pci_probe(struct pci_dev *pci_dev,
                 * scheduled since efx_stop_all() has been called, and we
                 * have not and never have been registered with either
                 * the rtnetlink or driverlink layers. */
-               cancel_work_sync(&efx->reset_work);
+               flush_workqueue(efx->reset_workqueue);
 
                /* Retry if a recoverably reset event has been scheduled */
                if ((efx->reset_pending != RESET_TYPE_INVISIBLE) &&