diff options
Diffstat (limited to 'drivers/net/sfc')
-rw-r--r-- | drivers/net/sfc/efx.c | 60 |
1 files changed, 35 insertions, 25 deletions
diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c index 9f1ac3a25911..487df9499c35 100644 --- a/drivers/net/sfc/efx.c +++ b/drivers/net/sfc/efx.c | |||
@@ -819,38 +819,48 @@ static void efx_fini_io(struct efx_nic *efx) | |||
819 | pci_disable_device(efx->pci_dev); | 819 | pci_disable_device(efx->pci_dev); |
820 | } | 820 | } |
821 | 821 | ||
822 | /* Probe the number and type of interrupts we are able to obtain. */ | 822 | /* Get number of RX queues wanted. Return number of online CPU |
823 | * packages in the expectation that an IRQ balancer will spread | ||
824 | * interrupts across them. */ | ||
825 | static int efx_wanted_rx_queues(void) | ||
826 | { | ||
827 | cpumask_t core_mask; | ||
828 | int count; | ||
829 | int cpu; | ||
830 | |||
831 | cpus_clear(core_mask); | ||
832 | count = 0; | ||
833 | for_each_online_cpu(cpu) { | ||
834 | if (!cpu_isset(cpu, core_mask)) { | ||
835 | ++count; | ||
836 | cpus_or(core_mask, core_mask, | ||
837 | topology_core_siblings(cpu)); | ||
838 | } | ||
839 | } | ||
840 | |||
841 | return count; | ||
842 | } | ||
843 | |||
844 | /* Probe the number and type of interrupts we are able to obtain, and | ||
845 | * the resulting numbers of channels and RX queues. | ||
846 | */ | ||
823 | static void efx_probe_interrupts(struct efx_nic *efx) | 847 | static void efx_probe_interrupts(struct efx_nic *efx) |
824 | { | 848 | { |
825 | int max_channel = efx->type->phys_addr_channels - 1; | 849 | int max_channels = |
826 | struct msix_entry xentries[EFX_MAX_CHANNELS]; | 850 | min_t(int, efx->type->phys_addr_channels, EFX_MAX_CHANNELS); |
827 | int rc, i; | 851 | int rc, i; |
828 | 852 | ||
829 | if (efx->interrupt_mode == EFX_INT_MODE_MSIX) { | 853 | if (efx->interrupt_mode == EFX_INT_MODE_MSIX) { |
830 | BUG_ON(!pci_find_capability(efx->pci_dev, PCI_CAP_ID_MSIX)); | 854 | struct msix_entry xentries[EFX_MAX_CHANNELS]; |
831 | 855 | int wanted_ints; | |
832 | if (rss_cpus == 0) { | ||
833 | cpumask_t core_mask; | ||
834 | int cpu; | ||
835 | |||
836 | cpus_clear(core_mask); | ||
837 | efx->rss_queues = 0; | ||
838 | for_each_online_cpu(cpu) { | ||
839 | if (!cpu_isset(cpu, core_mask)) { | ||
840 | ++efx->rss_queues; | ||
841 | cpus_or(core_mask, core_mask, | ||
842 | topology_core_siblings(cpu)); | ||
843 | } | ||
844 | } | ||
845 | } else { | ||
846 | efx->rss_queues = rss_cpus; | ||
847 | } | ||
848 | 856 | ||
849 | efx->rss_queues = min(efx->rss_queues, max_channel + 1); | 857 | /* We want one RX queue and interrupt per CPU package |
850 | efx->rss_queues = min(efx->rss_queues, EFX_MAX_CHANNELS); | 858 | * (or as specified by the rss_cpus module parameter). |
859 | * We will need one channel per interrupt. | ||
860 | */ | ||
861 | wanted_ints = rss_cpus ? rss_cpus : efx_wanted_rx_queues(); | ||
862 | efx->rss_queues = min(wanted_ints, max_channels); | ||
851 | 863 | ||
852 | /* Request maximum number of MSI interrupts, and fill out | ||
853 | * the channel interrupt information the allowed allocation */ | ||
854 | for (i = 0; i < efx->rss_queues; i++) | 864 | for (i = 0; i < efx->rss_queues; i++) |
855 | xentries[i].entry = i; | 865 | xentries[i].entry = i; |
856 | rc = pci_enable_msix(efx->pci_dev, xentries, efx->rss_queues); | 866 | rc = pci_enable_msix(efx->pci_dev, xentries, efx->rss_queues); |