|
@@ -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) &&
|