diff options
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/ethernet/amd/xgbe/xgbe-drv.c | 18 | ||||
-rw-r--r-- | 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 43b84ff0b621..ecef3ee87b17 100644 --- a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c +++ b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c @@ -192,12 +192,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; @@ -209,6 +214,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]; @@ -236,7 +242,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", @@ -916,6 +922,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; @@ -925,6 +934,7 @@ err_dma_irq: 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); } @@ -952,6 +962,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 ac3b5588b845..7b50469c77a0 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 { |