Blob Blame History Raw
From f88fc06fa74917680b50b3cfd609d659a188acc1 Mon Sep 17 00:00:00 2001
From: "Lendacky, Thomas" <Thomas.Lendacky@amd.com>
Date: Wed, 28 Jun 2017 13:43:00 -0500
Subject: [PATCH 21/59] amd-xgbe: Add NUMA affinity support for IRQ hints
References: git-fixes
Patch-mainline: v4.13-rc1
Git-commit: f00ba49d8ef9b7a8a9f17be4128fad397e42683b

For IRQ affinity, set the affinity hints for the IRQs to be (initially) on
the processors corresponding to the NUMA node of the device.

Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Acked-by: Denis Kirjanov <denis.kirjanov@suse.com>
---
 drivers/net/ethernet/amd/xgbe/xgbe-drv.c | 18 +++++++++++++++---
 drivers/net/ethernet/amd/xgbe/xgbe.h     |  2 ++
 2 files changed, 17 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
index d691e6ec1fdc..4cf58558ece4 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c
@@ -191,12 +191,17 @@ static int xgbe_alloc_channels(struct xgbe_prv_data *pdata)
 	struct xgbe_channel *channel;
 	struct xgbe_ring *ring;
 	unsigned int count, i;
+	unsigned int cpu;
 	int node;
 
-	node = dev_to_node(pdata->dev);
-
 	count = max_t(unsigned int, pdata->tx_ring_count, pdata->rx_ring_count);
 	for (i = 0; i < count; i++) {
+		/* Attempt to use a CPU on the node the device is on */
+		cpu = cpumask_local_spread(i, dev_to_node(pdata->dev));
+
+		/* Set the allocation node based on the returned CPU */
+		node = cpu_to_node(cpu);
+
 		channel = xgbe_alloc_node(sizeof(*channel), node);
 		if (!channel)
 			goto err_mem;
@@ -208,6 +213,7 @@ static int xgbe_alloc_channels(struct xgbe_prv_data *pdata)
 		channel->dma_regs = pdata->xgmac_regs + DMA_CH_BASE +
 				    (DMA_CH_INC * i);
 		channel->node = node;
+		cpumask_set_cpu(cpu, &channel->affinity_mask);
 
 		if (pdata->per_channel_irq)
 			channel->dma_irq = pdata->channel_irq[i];
@@ -235,7 +241,7 @@ static int xgbe_alloc_channels(struct xgbe_prv_data *pdata)
 		}
 
 		netif_dbg(pdata, drv, pdata->netdev,
-			  "%s: node=%d\n", channel->name, node);
+			  "%s: cpu=%u, node=%d\n", channel->name, cpu, node);
 
 		netif_dbg(pdata, drv, pdata->netdev,
 			  "%s: dma_regs=%p, dma_irq=%d, tx=%p, rx=%p\n",
@@ -915,6 +921,9 @@ static int xgbe_request_irqs(struct xgbe_prv_data *pdata)
 				     channel->dma_irq);
 			goto err_dma_irq;
 		}
+
+		irq_set_affinity_hint(channel->dma_irq,
+				      &channel->affinity_mask);
 	}
 
 	return 0;
@@ -924,6 +933,7 @@ static int xgbe_request_irqs(struct xgbe_prv_data *pdata)
 	for (i--; i < pdata->channel_count; i--) {
 		channel = pdata->channel[i];
 
+		irq_set_affinity_hint(channel->dma_irq, NULL);
 		devm_free_irq(pdata->dev, channel->dma_irq, channel);
 	}
 
@@ -951,6 +961,8 @@ static void xgbe_free_irqs(struct xgbe_prv_data *pdata)
 
 	for (i = 0; i < pdata->channel_count; i++) {
 		channel = pdata->channel[i];
+
+		irq_set_affinity_hint(channel->dma_irq, NULL);
 		devm_free_irq(pdata->dev, channel->dma_irq, channel);
 	}
 }
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe.h b/drivers/net/ethernet/amd/xgbe/xgbe.h
index 2f634be93f3c..d434d38b9303 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe.h
+++ b/drivers/net/ethernet/amd/xgbe/xgbe.h
@@ -128,6 +128,7 @@
 #include <linux/net_tstamp.h>
 #include <net/dcbnl.h>
 #include <linux/completion.h>
+#include <linux/cpumask.h>
 
 #define XGBE_DRV_NAME		"amd-xgbe"
 #define XGBE_DRV_VERSION	"1.0.3"
@@ -465,6 +466,7 @@ struct xgbe_channel {
 	struct xgbe_ring *rx_ring;
 
 	int node;
+	cpumask_t affinity_mask;
 } ____cacheline_aligned;
 
 enum xgbe_state {
-- 
2.16.4