diff options
author | Steve Hodgson <shodgson@solarflare.com> | 2008-12-13 00:33:02 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-12-13 00:56:21 -0500 |
commit | 1ab00629f06fb3c47de6373cd92d086f33775444 (patch) | |
tree | 141cd0599bc92c1911c7c487cc515ec1460908cd /drivers/net | |
parent | 65f667fb472d28c1594d862b213a564e292a466c (diff) |
sfc: Make reset_workqueue driver-global rather than per-NIC
Each reset is serialised by the rtnl_lock anyway, so there's no win
per-NIC.
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/sfc/efx.c | 45 | ||||
-rw-r--r-- | drivers/net/sfc/net_driver.h | 2 |
2 files changed, 20 insertions, 27 deletions
diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c index bbc84026dd86..127b4da0a5e7 100644 --- a/drivers/net/sfc/efx.c +++ b/drivers/net/sfc/efx.c | |||
@@ -39,6 +39,12 @@ | |||
39 | */ | 39 | */ |
40 | static struct workqueue_struct *refill_workqueue; | 40 | static struct workqueue_struct *refill_workqueue; |
41 | 41 | ||
42 | /* Reset workqueue. If any NIC has a hardware failure then a reset will be | ||
43 | * queued onto this work queue. This is not a per-nic work queue, because | ||
44 | * efx_reset_work() acquires the rtnl lock, so resets are naturally serialised. | ||
45 | */ | ||
46 | static struct workqueue_struct *reset_workqueue; | ||
47 | |||
42 | /************************************************************************** | 48 | /************************************************************************** |
43 | * | 49 | * |
44 | * Configurable values | 50 | * Configurable values |
@@ -1697,7 +1703,7 @@ void efx_schedule_reset(struct efx_nic *efx, enum reset_type type) | |||
1697 | 1703 | ||
1698 | efx->reset_pending = method; | 1704 | efx->reset_pending = method; |
1699 | 1705 | ||
1700 | queue_work(efx->reset_workqueue, &efx->reset_work); | 1706 | queue_work(reset_workqueue, &efx->reset_work); |
1701 | } | 1707 | } |
1702 | 1708 | ||
1703 | /************************************************************************** | 1709 | /************************************************************************** |
@@ -1763,7 +1769,7 @@ static int efx_init_struct(struct efx_nic *efx, struct efx_nic_type *type, | |||
1763 | struct efx_channel *channel; | 1769 | struct efx_channel *channel; |
1764 | struct efx_tx_queue *tx_queue; | 1770 | struct efx_tx_queue *tx_queue; |
1765 | struct efx_rx_queue *rx_queue; | 1771 | struct efx_rx_queue *rx_queue; |
1766 | int i, rc; | 1772 | int i; |
1767 | 1773 | ||
1768 | /* Initialise common structures */ | 1774 | /* Initialise common structures */ |
1769 | memset(efx, 0, sizeof(*efx)); | 1775 | memset(efx, 0, sizeof(*efx)); |
@@ -1832,33 +1838,14 @@ static int efx_init_struct(struct efx_nic *efx, struct efx_nic_type *type, | |||
1832 | interrupt_mode); | 1838 | interrupt_mode); |
1833 | 1839 | ||
1834 | efx->workqueue = create_singlethread_workqueue("sfc_work"); | 1840 | efx->workqueue = create_singlethread_workqueue("sfc_work"); |
1835 | if (!efx->workqueue) { | 1841 | if (!efx->workqueue) |
1836 | rc = -ENOMEM; | 1842 | return -ENOMEM; |
1837 | goto fail1; | ||
1838 | } | ||
1839 | |||
1840 | efx->reset_workqueue = create_singlethread_workqueue("sfc_reset"); | ||
1841 | if (!efx->reset_workqueue) { | ||
1842 | rc = -ENOMEM; | ||
1843 | goto fail2; | ||
1844 | } | ||
1845 | 1843 | ||
1846 | return 0; | 1844 | return 0; |
1847 | |||
1848 | fail2: | ||
1849 | destroy_workqueue(efx->workqueue); | ||
1850 | efx->workqueue = NULL; | ||
1851 | |||
1852 | fail1: | ||
1853 | return rc; | ||
1854 | } | 1845 | } |
1855 | 1846 | ||
1856 | static void efx_fini_struct(struct efx_nic *efx) | 1847 | static void efx_fini_struct(struct efx_nic *efx) |
1857 | { | 1848 | { |
1858 | if (efx->reset_workqueue) { | ||
1859 | destroy_workqueue(efx->reset_workqueue); | ||
1860 | efx->reset_workqueue = NULL; | ||
1861 | } | ||
1862 | if (efx->workqueue) { | 1849 | if (efx->workqueue) { |
1863 | destroy_workqueue(efx->workqueue); | 1850 | destroy_workqueue(efx->workqueue); |
1864 | efx->workqueue = NULL; | 1851 | efx->workqueue = NULL; |
@@ -1923,7 +1910,7 @@ static void efx_pci_remove(struct pci_dev *pci_dev) | |||
1923 | * scheduled from this point because efx_stop_all() has been | 1910 | * scheduled from this point because efx_stop_all() has been |
1924 | * called, we are no longer registered with driverlink, and | 1911 | * called, we are no longer registered with driverlink, and |
1925 | * the net_device's have been removed. */ | 1912 | * the net_device's have been removed. */ |
1926 | flush_workqueue(efx->reset_workqueue); | 1913 | cancel_work_sync(&efx->reset_work); |
1927 | 1914 | ||
1928 | efx_pci_remove_main(efx); | 1915 | efx_pci_remove_main(efx); |
1929 | 1916 | ||
@@ -2045,7 +2032,7 @@ static int __devinit efx_pci_probe(struct pci_dev *pci_dev, | |||
2045 | * scheduled since efx_stop_all() has been called, and we | 2032 | * scheduled since efx_stop_all() has been called, and we |
2046 | * have not and never have been registered with either | 2033 | * have not and never have been registered with either |
2047 | * the rtnetlink or driverlink layers. */ | 2034 | * the rtnetlink or driverlink layers. */ |
2048 | flush_workqueue(efx->reset_workqueue); | 2035 | cancel_work_sync(&efx->reset_work); |
2049 | 2036 | ||
2050 | /* Retry if a recoverably reset event has been scheduled */ | 2037 | /* Retry if a recoverably reset event has been scheduled */ |
2051 | if ((efx->reset_pending != RESET_TYPE_INVISIBLE) && | 2038 | if ((efx->reset_pending != RESET_TYPE_INVISIBLE) && |
@@ -2121,6 +2108,11 @@ static int __init efx_init_module(void) | |||
2121 | rc = -ENOMEM; | 2108 | rc = -ENOMEM; |
2122 | goto err_refill; | 2109 | goto err_refill; |
2123 | } | 2110 | } |
2111 | reset_workqueue = create_singlethread_workqueue("sfc_reset"); | ||
2112 | if (!reset_workqueue) { | ||
2113 | rc = -ENOMEM; | ||
2114 | goto err_reset; | ||
2115 | } | ||
2124 | 2116 | ||
2125 | rc = pci_register_driver(&efx_pci_driver); | 2117 | rc = pci_register_driver(&efx_pci_driver); |
2126 | if (rc < 0) | 2118 | if (rc < 0) |
@@ -2129,6 +2121,8 @@ static int __init efx_init_module(void) | |||
2129 | return 0; | 2121 | return 0; |
2130 | 2122 | ||
2131 | err_pci: | 2123 | err_pci: |
2124 | destroy_workqueue(reset_workqueue); | ||
2125 | err_reset: | ||
2132 | destroy_workqueue(refill_workqueue); | 2126 | destroy_workqueue(refill_workqueue); |
2133 | err_refill: | 2127 | err_refill: |
2134 | unregister_netdevice_notifier(&efx_netdev_notifier); | 2128 | unregister_netdevice_notifier(&efx_netdev_notifier); |
@@ -2141,6 +2135,7 @@ static void __exit efx_exit_module(void) | |||
2141 | printk(KERN_INFO "Solarflare NET driver unloading\n"); | 2135 | printk(KERN_INFO "Solarflare NET driver unloading\n"); |
2142 | 2136 | ||
2143 | pci_unregister_driver(&efx_pci_driver); | 2137 | pci_unregister_driver(&efx_pci_driver); |
2138 | destroy_workqueue(reset_workqueue); | ||
2144 | destroy_workqueue(refill_workqueue); | 2139 | destroy_workqueue(refill_workqueue); |
2145 | unregister_netdevice_notifier(&efx_netdev_notifier); | 2140 | unregister_netdevice_notifier(&efx_netdev_notifier); |
2146 | 2141 | ||
diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index e596c9a6a4c4..f91060963475 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h | |||
@@ -635,7 +635,6 @@ union efx_multicast_hash { | |||
635 | * @legacy_irq: IRQ number | 635 | * @legacy_irq: IRQ number |
636 | * @workqueue: Workqueue for port reconfigures and the HW monitor. | 636 | * @workqueue: Workqueue for port reconfigures and the HW monitor. |
637 | * Work items do not hold and must not acquire RTNL. | 637 | * Work items do not hold and must not acquire RTNL. |
638 | * @reset_workqueue: Workqueue for resets. Work item will acquire RTNL. | ||
639 | * @reset_work: Scheduled reset workitem | 638 | * @reset_work: Scheduled reset workitem |
640 | * @monitor_work: Hardware monitor workitem | 639 | * @monitor_work: Hardware monitor workitem |
641 | * @membase_phys: Memory BAR value as physical address | 640 | * @membase_phys: Memory BAR value as physical address |
@@ -711,7 +710,6 @@ struct efx_nic { | |||
711 | const struct efx_nic_type *type; | 710 | const struct efx_nic_type *type; |
712 | int legacy_irq; | 711 | int legacy_irq; |
713 | struct workqueue_struct *workqueue; | 712 | struct workqueue_struct *workqueue; |
714 | struct workqueue_struct *reset_workqueue; | ||
715 | struct work_struct reset_work; | 713 | struct work_struct reset_work; |
716 | struct delayed_work monitor_work; | 714 | struct delayed_work monitor_work; |
717 | resource_size_t membase_phys; | 715 | resource_size_t membase_phys; |