|
Thomas Bogendoerfer |
c02579 |
From: Saurabh Sengar <ssengar@linux.microsoft.com>
|
|
Thomas Bogendoerfer |
c02579 |
Date: Mon, 31 Oct 2022 23:06:01 -0700
|
|
Thomas Bogendoerfer |
c02579 |
Subject: net: mana: Assign interrupts to CPUs based on NUMA nodes
|
|
Thomas Bogendoerfer |
c02579 |
Patch-mainline: v6.2-rc1
|
|
Thomas Bogendoerfer |
c02579 |
Git-commit: 71fa6887eeca7b631528f9c7a39815498de8028c
|
|
Thomas Bogendoerfer |
c02579 |
References: bsc#1208153
|
|
Thomas Bogendoerfer |
c02579 |
|
|
Thomas Bogendoerfer |
c02579 |
In large VMs with multiple NUMA nodes, network performance is usually
|
|
Thomas Bogendoerfer |
c02579 |
best if network interrupts are all assigned to the same virtual NUMA
|
|
Thomas Bogendoerfer |
c02579 |
node. This patch assigns online CPU according to a numa aware policy,
|
|
Thomas Bogendoerfer |
c02579 |
local cpus are returned first, followed by non-local ones, then it wraps
|
|
Thomas Bogendoerfer |
c02579 |
around.
|
|
Thomas Bogendoerfer |
c02579 |
|
|
Thomas Bogendoerfer |
c02579 |
Signed-off-by: Saurabh Sengar <ssengar@linux.microsoft.com>
|
|
Thomas Bogendoerfer |
c02579 |
Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>
|
|
Thomas Bogendoerfer |
c02579 |
Link: https://lore.kernel.org/r/1667282761-11547-1-git-send-email-ssengar@linux.microsoft.com
|
|
Thomas Bogendoerfer |
c02579 |
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
|
Thomas Bogendoerfer |
c02579 |
Acked-by: Thomas Bogendoerfer <tbogendoerfer@suse.de>
|
|
Thomas Bogendoerfer |
c02579 |
---
|
|
Thomas Bogendoerfer |
c02579 |
drivers/net/ethernet/microsoft/mana/gdma.h | 1
|
|
Thomas Bogendoerfer |
c02579 |
drivers/net/ethernet/microsoft/mana/gdma_main.c | 30 +++++++++++++++++++++---
|
|
Thomas Bogendoerfer |
c02579 |
2 files changed, 28 insertions(+), 3 deletions(-)
|
|
Thomas Bogendoerfer |
c02579 |
|
|
Thomas Bogendoerfer |
c02579 |
--- a/drivers/net/ethernet/microsoft/mana/gdma.h
|
|
Thomas Bogendoerfer |
c02579 |
+++ b/drivers/net/ethernet/microsoft/mana/gdma.h
|
|
Thomas Bogendoerfer |
c02579 |
@@ -353,6 +353,7 @@ struct gdma_context {
|
|
Thomas Bogendoerfer |
c02579 |
void __iomem *shm_base;
|
|
Thomas Bogendoerfer |
c02579 |
void __iomem *db_page_base;
|
|
Thomas Bogendoerfer |
c02579 |
u32 db_page_size;
|
|
Thomas Bogendoerfer |
c02579 |
+ int numa_node;
|
|
Thomas Bogendoerfer |
c02579 |
|
|
Thomas Bogendoerfer |
c02579 |
/* Shared memory chanenl (used to bootstrap HWC) */
|
|
Thomas Bogendoerfer |
c02579 |
struct shm_channel shm_channel;
|
|
Thomas Bogendoerfer |
c02579 |
--- a/drivers/net/ethernet/microsoft/mana/gdma_main.c
|
|
Thomas Bogendoerfer |
c02579 |
+++ b/drivers/net/ethernet/microsoft/mana/gdma_main.c
|
|
Thomas Bogendoerfer |
c02579 |
@@ -1197,8 +1197,10 @@ static int mana_gd_setup_irqs(struct pci
|
|
Thomas Bogendoerfer |
c02579 |
struct gdma_context *gc = pci_get_drvdata(pdev);
|
|
Thomas Bogendoerfer |
c02579 |
struct gdma_irq_context *gic;
|
|
Thomas Bogendoerfer |
c02579 |
unsigned int max_irqs;
|
|
Thomas Bogendoerfer |
c02579 |
+ u16 *cpus;
|
|
Thomas Bogendoerfer |
c02579 |
+ cpumask_var_t req_mask;
|
|
Thomas Bogendoerfer |
c02579 |
int nvec, irq;
|
|
Thomas Bogendoerfer |
c02579 |
- int err, i, j;
|
|
Thomas Bogendoerfer |
c02579 |
+ int err, i = 0, j;
|
|
Thomas Bogendoerfer |
c02579 |
|
|
Thomas Bogendoerfer |
c02579 |
if (max_queues_per_port > MANA_MAX_NUM_QUEUES)
|
|
Thomas Bogendoerfer |
c02579 |
max_queues_per_port = MANA_MAX_NUM_QUEUES;
|
|
Thomas Bogendoerfer |
c02579 |
@@ -1217,7 +1219,21 @@ static int mana_gd_setup_irqs(struct pci
|
|
Thomas Bogendoerfer |
c02579 |
goto free_irq_vector;
|
|
Thomas Bogendoerfer |
c02579 |
}
|
|
Thomas Bogendoerfer |
c02579 |
|
|
Thomas Bogendoerfer |
c02579 |
+ if (!zalloc_cpumask_var(&req_mask, GFP_KERNEL)) {
|
|
Thomas Bogendoerfer |
c02579 |
+ err = -ENOMEM;
|
|
Thomas Bogendoerfer |
c02579 |
+ goto free_irq;
|
|
Thomas Bogendoerfer |
c02579 |
+ }
|
|
Thomas Bogendoerfer |
c02579 |
+
|
|
Thomas Bogendoerfer |
c02579 |
+ cpus = kcalloc(nvec, sizeof(*cpus), GFP_KERNEL);
|
|
Thomas Bogendoerfer |
c02579 |
+ if (!cpus) {
|
|
Thomas Bogendoerfer |
c02579 |
+ err = -ENOMEM;
|
|
Thomas Bogendoerfer |
c02579 |
+ goto free_mask;
|
|
Thomas Bogendoerfer |
c02579 |
+ }
|
|
Thomas Bogendoerfer |
c02579 |
+ for (i = 0; i < nvec; i++)
|
|
Thomas Bogendoerfer |
c02579 |
+ cpus[i] = cpumask_local_spread(i, gc->numa_node);
|
|
Thomas Bogendoerfer |
c02579 |
+
|
|
Thomas Bogendoerfer |
c02579 |
for (i = 0; i < nvec; i++) {
|
|
Thomas Bogendoerfer |
c02579 |
+ cpumask_set_cpu(cpus[i], req_mask);
|
|
Thomas Bogendoerfer |
c02579 |
gic = &gc->irq_contexts[i];
|
|
Thomas Bogendoerfer |
c02579 |
gic->handler = NULL;
|
|
Thomas Bogendoerfer |
c02579 |
gic->arg = NULL;
|
|
Thomas Bogendoerfer |
c02579 |
@@ -1225,13 +1241,17 @@ static int mana_gd_setup_irqs(struct pci
|
|
Thomas Bogendoerfer |
c02579 |
irq = pci_irq_vector(pdev, i);
|
|
Thomas Bogendoerfer |
c02579 |
if (irq < 0) {
|
|
Thomas Bogendoerfer |
c02579 |
err = irq;
|
|
Thomas Bogendoerfer |
c02579 |
- goto free_irq;
|
|
Thomas Bogendoerfer |
c02579 |
+ goto free_mask;
|
|
Thomas Bogendoerfer |
c02579 |
}
|
|
Thomas Bogendoerfer |
c02579 |
|
|
Thomas Bogendoerfer |
c02579 |
err = request_irq(irq, mana_gd_intr, 0, "mana_intr", gic);
|
|
Thomas Bogendoerfer |
c02579 |
if (err)
|
|
Thomas Bogendoerfer |
c02579 |
- goto free_irq;
|
|
Thomas Bogendoerfer |
c02579 |
+ goto free_mask;
|
|
Thomas Bogendoerfer |
c02579 |
+ irq_set_affinity_and_hint(irq, req_mask);
|
|
Thomas Bogendoerfer |
c02579 |
+ cpumask_clear(req_mask);
|
|
Thomas Bogendoerfer |
c02579 |
}
|
|
Thomas Bogendoerfer |
c02579 |
+ free_cpumask_var(req_mask);
|
|
Thomas Bogendoerfer |
c02579 |
+ kfree(cpus);
|
|
Thomas Bogendoerfer |
c02579 |
|
|
Thomas Bogendoerfer |
c02579 |
err = mana_gd_alloc_res_map(nvec, &gc->msix_resource);
|
|
Thomas Bogendoerfer |
c02579 |
if (err)
|
|
Thomas Bogendoerfer |
c02579 |
@@ -1242,6 +1262,9 @@ static int mana_gd_setup_irqs(struct pci
|
|
Thomas Bogendoerfer |
c02579 |
|
|
Thomas Bogendoerfer |
c02579 |
return 0;
|
|
Thomas Bogendoerfer |
c02579 |
|
|
Thomas Bogendoerfer |
c02579 |
+free_mask:
|
|
Thomas Bogendoerfer |
c02579 |
+ free_cpumask_var(req_mask);
|
|
Thomas Bogendoerfer |
c02579 |
+ kfree(cpus);
|
|
Thomas Bogendoerfer |
c02579 |
free_irq:
|
|
Thomas Bogendoerfer |
c02579 |
for (j = i - 1; j >= 0; j--) {
|
|
Thomas Bogendoerfer |
c02579 |
irq = pci_irq_vector(pdev, j);
|
|
Thomas Bogendoerfer |
c02579 |
@@ -1371,6 +1394,7 @@ static int mana_gd_probe(struct pci_dev
|
|
Thomas Bogendoerfer |
c02579 |
if (!bar0_va)
|
|
Thomas Bogendoerfer |
c02579 |
goto free_gc;
|
|
Thomas Bogendoerfer |
c02579 |
|
|
Thomas Bogendoerfer |
c02579 |
+ gc->numa_node = dev_to_node(&pdev->dev);
|
|
Thomas Bogendoerfer |
c02579 |
gc->is_pf = mana_is_pf(pdev->device);
|
|
Thomas Bogendoerfer |
c02579 |
gc->bar0_va = bar0_va;
|
|
Thomas Bogendoerfer |
c02579 |
gc->dev = &pdev->dev;
|