[PATCH net-next 11/11] bnge: add cpu_rmap support for IRQ affinity
Vikas Gupta <[email protected]>
| Newsgroups | gmane.linux.network,gmane.linux.kernel |
|---|---|
| Message-ID | <[email protected]> |
When CONFIG_RFS_ACCEL is enabled, allocate and populate a cpu_rmap for the RX IRQ vectors so that the kernel's aRFS infrastructure can correctly map flows to the RX queues serviced by the nearest CPU. This ensures that NTUPLE rules created by the kernel steer packets to the optimal queue based on CPU/IRQ affinity. Signed-off-by: Vikas Gupta <[email protected]> Reviewed-by: Bhargava Chenna Marreddy <[email protected]> Reviewed-by: Dharmender Garg <[email protected]> --- .../net/ethernet/broadcom/bnge/bnge_netdev.c | 35 ++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/broadcom/bnge/bnge_netdev.c b/drivers/net/ethernet/broadcom/bnge/bnge_netdev.c index fc752fe879b6..48de88924a7f 100644 --- a/drivers/net/ethernet/broadcom/bnge/bnge_netdev.c +++ b/drivers/net/ethernet/broadcom/bnge/bnge_netdev.c @@ -18,6 +18,7 @@ #include <net/ip.h> #include <linux/skbuff.h> #include <net/page_pool/helpers.h> +#include <linux/cpu_rmap.h> #include "bnge.h" #include "bnge_hwrm.h" @@ -2432,10 +2433,23 @@ static int bnge_setup_interrupts(struct bnge_net *bn) { struct net_device *dev = bn->netdev; struct bnge_dev *bd = bn->bd; + int rc; bnge_setup_msix(bn); - return netif_set_real_num_queues(dev, bd->tx_nr_rings, bd->rx_nr_rings); + rc = netif_set_real_num_queues(dev, bd->tx_nr_rings, bd->rx_nr_rings); + if (rc) + return rc; + +#ifdef CONFIG_RFS_ACCEL + if (bn->priv_flags & BNGE_NET_EN_NTUPLE) { + dev->rx_cpu_rmap = alloc_irq_cpu_rmap(bd->rx_nr_rings); + if (!dev->rx_cpu_rmap) + return -ENOMEM; + } +#endif + + return rc; } static void bnge_hwrm_resource_free(struct bnge_net *bn, bool close_path) @@ -2451,6 +2465,11 @@ static void bnge_free_irq(struct bnge_net *bn) struct bnge_irq *irq; int i; +#ifdef CONFIG_RFS_ACCEL + free_irq_cpu_rmap(bn->netdev->rx_cpu_rmap); + bn->netdev->rx_cpu_rmap = NULL; +#endif + for (i = 0; i < bd->nq_nr_rings; i++) { int map_idx = bnge_cp_num_to_irq_num(bn, i); @@ -2470,6 +2489,7 @@ static void bnge_free_irq(struct bnge_net *bn) static int bnge_request_irq(struct bnge_net *bn) { + struct cpu_rmap *rmap = NULL; struct bnge_dev *bd = bn->bd; int i, rc; @@ -2478,10 +2498,23 @@ static int bnge_request_irq(struct bnge_net *bn) netdev_err(bn->netdev, "bnge_setup_interrupts err: %d\n", rc); return rc; } + +#ifdef CONFIG_RFS_ACCEL + rmap = bn->netdev->rx_cpu_rmap; +#endif + for (i = 0; i < bd->nq_nr_rings; i++) { int map_idx = bnge_cp_num_to_irq_num(bn, i); struct bnge_irq *irq = &bd->irq_tbl[map_idx]; + if (IS_ENABLED(CONFIG_RFS_ACCEL) && + rmap && bn->bnapi[i]->rx_ring) { + rc = irq_cpu_rmap_add(rmap, irq->vector); + if (rc) + netdev_warn(bn->netdev, + "failed adding irq rmap for ring %d\n", i); + } + rc = request_irq(irq->vector, irq->handler, 0, irq->name, bn->bnapi[i]); if (rc) -- 2.47.1