summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Hutchings <bhutchings@solarflare.com>2008-07-18 19:03:10 +0100
committerJeff Garzik <jgarzik@redhat.com>2008-07-22 19:44:15 -0400
commitaa6ef27ea906e74bd23d14f43f095c012469d9c7 (patch)
treeb3021a33a78593153c145b1ef6b382288e96d253
parent8d9853d911b9d3fb767c3886066530c0e39b78ba (diff)
sfc: Create one RX queue and interrupt per CPU package by default
Using multiple cores in the same package to handle received traffic does not appear to provide a performance benefit. Therefore use CPU topology information to count CPU packages and use that as the default number of RX queues and interrupts. We rely on interrupt balancing to spread the interrupts across packages. Signed-off-by: Ben Hutchings <bhutchings@solarflare.com> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
-rw-r--r--drivers/net/sfc/efx.c19
1 files changed, 18 insertions, 1 deletions
diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c
index 7b2a8186623..45c72eebb3a 100644
--- a/drivers/net/sfc/efx.c
+++ b/drivers/net/sfc/efx.c
@@ -19,6 +19,7 @@
#include <linux/in.h>
#include <linux/crc32.h>
#include <linux/ethtool.h>
+#include <linux/topology.h>
#include "net_driver.h"
#include "gmii.h"
#include "ethtool.h"
@@ -832,7 +833,23 @@ static void efx_probe_interrupts(struct efx_nic *efx)
if (efx->interrupt_mode == EFX_INT_MODE_MSIX) {
BUG_ON(!pci_find_capability(efx->pci_dev, PCI_CAP_ID_MSIX));
- efx->rss_queues = rss_cpus ? rss_cpus : num_online_cpus();
+ if (rss_cpus == 0) {
+ cpumask_t core_mask;
+ int cpu;
+
+ cpus_clear(core_mask);
+ efx->rss_queues = 0;
+ for_each_online_cpu(cpu) {
+ if (!cpu_isset(cpu, core_mask)) {
+ ++efx->rss_queues;
+ cpus_or(core_mask, core_mask,
+ topology_core_siblings(cpu));
+ }
+ }
+ } else {
+ efx->rss_queues = rss_cpus;
+ }
+
efx->rss_queues = min(efx->rss_queues, max_channel + 1);
efx->rss_queues = min(efx->rss_queues, EFX_MAX_CHANNELS);