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;