diff options
| -rw-r--r-- | drivers/net/sfc/efx.c | 20 | ||||
| -rw-r--r-- | drivers/net/sfc/net_driver.h | 5 |
2 files changed, 21 insertions, 4 deletions
diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c index 7b2015f9e469..7b2a81866232 100644 --- a/drivers/net/sfc/efx.c +++ b/drivers/net/sfc/efx.c | |||
| @@ -1762,7 +1762,7 @@ void efx_schedule_reset(struct efx_nic *efx, enum reset_type type) | |||
| 1762 | 1762 | ||
| 1763 | efx->reset_pending = method; | 1763 | efx->reset_pending = method; |
| 1764 | 1764 | ||
| 1765 | queue_work(efx->workqueue, &efx->reset_work); | 1765 | queue_work(efx->reset_workqueue, &efx->reset_work); |
| 1766 | } | 1766 | } |
| 1767 | 1767 | ||
| 1768 | /************************************************************************** | 1768 | /************************************************************************** |
| @@ -1907,14 +1907,28 @@ static int efx_init_struct(struct efx_nic *efx, struct efx_nic_type *type, | |||
| 1907 | goto fail1; | 1907 | goto fail1; |
| 1908 | } | 1908 | } |
| 1909 | 1909 | ||
| 1910 | efx->reset_workqueue = create_singlethread_workqueue("sfc_reset"); | ||
| 1911 | if (!efx->reset_workqueue) { | ||
| 1912 | rc = -ENOMEM; | ||
| 1913 | goto fail2; | ||
| 1914 | } | ||
| 1915 | |||
| 1910 | return 0; | 1916 | return 0; |
| 1911 | 1917 | ||
| 1918 | fail2: | ||
| 1919 | destroy_workqueue(efx->workqueue); | ||
| 1920 | efx->workqueue = NULL; | ||
| 1921 | |||
| 1912 | fail1: | 1922 | fail1: |
| 1913 | return rc; | 1923 | return rc; |
| 1914 | } | 1924 | } |
| 1915 | 1925 | ||
| 1916 | static void efx_fini_struct(struct efx_nic *efx) | 1926 | static void efx_fini_struct(struct efx_nic *efx) |
| 1917 | { | 1927 | { |
| 1928 | if (efx->reset_workqueue) { | ||
| 1929 | destroy_workqueue(efx->reset_workqueue); | ||
| 1930 | efx->reset_workqueue = NULL; | ||
| 1931 | } | ||
| 1918 | if (efx->workqueue) { | 1932 | if (efx->workqueue) { |
| 1919 | destroy_workqueue(efx->workqueue); | 1933 | destroy_workqueue(efx->workqueue); |
| 1920 | efx->workqueue = NULL; | 1934 | efx->workqueue = NULL; |
| @@ -1977,7 +1991,7 @@ static void efx_pci_remove(struct pci_dev *pci_dev) | |||
| 1977 | * scheduled from this point because efx_stop_all() has been | 1991 | * scheduled from this point because efx_stop_all() has been |
| 1978 | * called, we are no longer registered with driverlink, and | 1992 | * called, we are no longer registered with driverlink, and |
| 1979 | * the net_device's have been removed. */ | 1993 | * the net_device's have been removed. */ |
| 1980 | flush_workqueue(efx->workqueue); | 1994 | flush_workqueue(efx->reset_workqueue); |
| 1981 | 1995 | ||
| 1982 | efx_pci_remove_main(efx); | 1996 | efx_pci_remove_main(efx); |
| 1983 | 1997 | ||
| @@ -2098,7 +2112,7 @@ static int __devinit efx_pci_probe(struct pci_dev *pci_dev, | |||
| 2098 | * scheduled since efx_stop_all() has been called, and we | 2112 | * scheduled since efx_stop_all() has been called, and we |
| 2099 | * have not and never have been registered with either | 2113 | * have not and never have been registered with either |
| 2100 | * the rtnetlink or driverlink layers. */ | 2114 | * the rtnetlink or driverlink layers. */ |
| 2101 | cancel_work_sync(&efx->reset_work); | 2115 | flush_workqueue(efx->reset_workqueue); |
| 2102 | 2116 | ||
| 2103 | /* Retry if a recoverably reset event has been scheduled */ | 2117 | /* Retry if a recoverably reset event has been scheduled */ |
| 2104 | if ((efx->reset_pending != RESET_TYPE_INVISIBLE) && | 2118 | if ((efx->reset_pending != RESET_TYPE_INVISIBLE) && |
diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index d803b86c647c..219c74a772c3 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h | |||
| @@ -616,7 +616,9 @@ union efx_multicast_hash { | |||
| 616 | * @pci_dev: The PCI device | 616 | * @pci_dev: The PCI device |
| 617 | * @type: Controller type attributes | 617 | * @type: Controller type attributes |
| 618 | * @legacy_irq: IRQ number | 618 | * @legacy_irq: IRQ number |
| 619 | * @workqueue: Workqueue for resets, port reconfigures and the HW monitor | 619 | * @workqueue: Workqueue for port reconfigures and the HW monitor. |
| 620 | * Work items do not hold and must not acquire RTNL. | ||
| 621 | * @reset_workqueue: Workqueue for resets. Work item will acquire RTNL. | ||
| 620 | * @reset_work: Scheduled reset workitem | 622 | * @reset_work: Scheduled reset workitem |
| 621 | * @monitor_work: Hardware monitor workitem | 623 | * @monitor_work: Hardware monitor workitem |
| 622 | * @membase_phys: Memory BAR value as physical address | 624 | * @membase_phys: Memory BAR value as physical address |
| @@ -684,6 +686,7 @@ struct efx_nic { | |||
| 684 | const struct efx_nic_type *type; | 686 | const struct efx_nic_type *type; |
| 685 | int legacy_irq; | 687 | int legacy_irq; |
| 686 | struct workqueue_struct *workqueue; | 688 | struct workqueue_struct *workqueue; |
| 689 | struct workqueue_struct *reset_workqueue; | ||
| 687 | struct work_struct reset_work; | 690 | struct work_struct reset_work; |
| 688 | struct delayed_work monitor_work; | 691 | struct delayed_work monitor_work; |
| 689 | resource_size_t membase_phys; | 692 | resource_size_t membase_phys; |
