diff options
Diffstat (limited to 'drivers/net/sfc/efx.c')
-rw-r--r-- | drivers/net/sfc/efx.c | 39 |
1 files changed, 35 insertions, 4 deletions
diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c index 7b2015f9e469..45c72eebb3a7 100644 --- a/drivers/net/sfc/efx.c +++ b/drivers/net/sfc/efx.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/in.h> | 19 | #include <linux/in.h> |
20 | #include <linux/crc32.h> | 20 | #include <linux/crc32.h> |
21 | #include <linux/ethtool.h> | 21 | #include <linux/ethtool.h> |
22 | #include <linux/topology.h> | ||
22 | #include "net_driver.h" | 23 | #include "net_driver.h" |
23 | #include "gmii.h" | 24 | #include "gmii.h" |
24 | #include "ethtool.h" | 25 | #include "ethtool.h" |
@@ -832,7 +833,23 @@ static void efx_probe_interrupts(struct efx_nic *efx) | |||
832 | if (efx->interrupt_mode == EFX_INT_MODE_MSIX) { | 833 | if (efx->interrupt_mode == EFX_INT_MODE_MSIX) { |
833 | BUG_ON(!pci_find_capability(efx->pci_dev, PCI_CAP_ID_MSIX)); | 834 | BUG_ON(!pci_find_capability(efx->pci_dev, PCI_CAP_ID_MSIX)); |
834 | 835 | ||
835 | efx->rss_queues = rss_cpus ? rss_cpus : num_online_cpus(); | 836 | if (rss_cpus == 0) { |
837 | cpumask_t core_mask; | ||
838 | int cpu; | ||
839 | |||
840 | cpus_clear(core_mask); | ||
841 | efx->rss_queues = 0; | ||
842 | for_each_online_cpu(cpu) { | ||
843 | if (!cpu_isset(cpu, core_mask)) { | ||
844 | ++efx->rss_queues; | ||
845 | cpus_or(core_mask, core_mask, | ||
846 | topology_core_siblings(cpu)); | ||
847 | } | ||
848 | } | ||
849 | } else { | ||
850 | efx->rss_queues = rss_cpus; | ||
851 | } | ||
852 | |||
836 | efx->rss_queues = min(efx->rss_queues, max_channel + 1); | 853 | efx->rss_queues = min(efx->rss_queues, max_channel + 1); |
837 | efx->rss_queues = min(efx->rss_queues, EFX_MAX_CHANNELS); | 854 | efx->rss_queues = min(efx->rss_queues, EFX_MAX_CHANNELS); |
838 | 855 | ||
@@ -1762,7 +1779,7 @@ void efx_schedule_reset(struct efx_nic *efx, enum reset_type type) | |||
1762 | 1779 | ||
1763 | efx->reset_pending = method; | 1780 | efx->reset_pending = method; |
1764 | 1781 | ||
1765 | queue_work(efx->workqueue, &efx->reset_work); | 1782 | queue_work(efx->reset_workqueue, &efx->reset_work); |
1766 | } | 1783 | } |
1767 | 1784 | ||
1768 | /************************************************************************** | 1785 | /************************************************************************** |
@@ -1907,14 +1924,28 @@ static int efx_init_struct(struct efx_nic *efx, struct efx_nic_type *type, | |||
1907 | goto fail1; | 1924 | goto fail1; |
1908 | } | 1925 | } |
1909 | 1926 | ||
1927 | efx->reset_workqueue = create_singlethread_workqueue("sfc_reset"); | ||
1928 | if (!efx->reset_workqueue) { | ||
1929 | rc = -ENOMEM; | ||
1930 | goto fail2; | ||
1931 | } | ||
1932 | |||
1910 | return 0; | 1933 | return 0; |
1911 | 1934 | ||
1935 | fail2: | ||
1936 | destroy_workqueue(efx->workqueue); | ||
1937 | efx->workqueue = NULL; | ||
1938 | |||
1912 | fail1: | 1939 | fail1: |
1913 | return rc; | 1940 | return rc; |
1914 | } | 1941 | } |
1915 | 1942 | ||
1916 | static void efx_fini_struct(struct efx_nic *efx) | 1943 | static void efx_fini_struct(struct efx_nic *efx) |
1917 | { | 1944 | { |
1945 | if (efx->reset_workqueue) { | ||
1946 | destroy_workqueue(efx->reset_workqueue); | ||
1947 | efx->reset_workqueue = NULL; | ||
1948 | } | ||
1918 | if (efx->workqueue) { | 1949 | if (efx->workqueue) { |
1919 | destroy_workqueue(efx->workqueue); | 1950 | destroy_workqueue(efx->workqueue); |
1920 | efx->workqueue = NULL; | 1951 | efx->workqueue = NULL; |
@@ -1977,7 +2008,7 @@ static void efx_pci_remove(struct pci_dev *pci_dev) | |||
1977 | * scheduled from this point because efx_stop_all() has been | 2008 | * scheduled from this point because efx_stop_all() has been |
1978 | * called, we are no longer registered with driverlink, and | 2009 | * called, we are no longer registered with driverlink, and |
1979 | * the net_device's have been removed. */ | 2010 | * the net_device's have been removed. */ |
1980 | flush_workqueue(efx->workqueue); | 2011 | flush_workqueue(efx->reset_workqueue); |
1981 | 2012 | ||
1982 | efx_pci_remove_main(efx); | 2013 | efx_pci_remove_main(efx); |
1983 | 2014 | ||
@@ -2098,7 +2129,7 @@ static int __devinit efx_pci_probe(struct pci_dev *pci_dev, | |||
2098 | * scheduled since efx_stop_all() has been called, and we | 2129 | * scheduled since efx_stop_all() has been called, and we |
2099 | * have not and never have been registered with either | 2130 | * have not and never have been registered with either |
2100 | * the rtnetlink or driverlink layers. */ | 2131 | * the rtnetlink or driverlink layers. */ |
2101 | cancel_work_sync(&efx->reset_work); | 2132 | flush_workqueue(efx->reset_workqueue); |
2102 | 2133 | ||
2103 | /* Retry if a recoverably reset event has been scheduled */ | 2134 | /* Retry if a recoverably reset event has been scheduled */ |
2104 | if ((efx->reset_pending != RESET_TYPE_INVISIBLE) && | 2135 | if ((efx->reset_pending != RESET_TYPE_INVISIBLE) && |