aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/sfc
diff options
context:
space:
mode:
authorSteve Hodgson <shodgson@solarflare.com>2008-12-13 00:33:02 -0500
committerDavid S. Miller <davem@davemloft.net>2008-12-13 00:56:21 -0500
commit1ab00629f06fb3c47de6373cd92d086f33775444 (patch)
tree141cd0599bc92c1911c7c487cc515ec1460908cd /drivers/net/sfc
parent65f667fb472d28c1594d862b213a564e292a466c (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/sfc')
-rw-r--r--drivers/net/sfc/efx.c45
-rw-r--r--drivers/net/sfc/net_driver.h2
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 */
40static struct workqueue_struct *refill_workqueue; 40static 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 */
46static 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
1856static void efx_fini_struct(struct efx_nic *efx) 1847static 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;