[PATCH RFC 3/3] net: stmmac: Migrate IRQ balancing to cpumask_local_spread()

Florian Bezdeka florian.bezdeka at siemens.com
Wed Aug 19 07:30:32 PDT 2026


The previous balancing mechanism was based on num_online_cpus(), which
is a problem for systems cpu-isolating workloads. IRQs were targeting
CPUs that were isolated for those sensitive workloads.

With a migration to cpumask_local_spread() we
    - get NUMA locality
    - honor the default SMP affinity mask, which avoids targeting
      isolated CPUs.

This also aligns with the pattern used by most network drivers dealing
with IRQ affinities / affinity hints.

Signed-off-by: Florian Bezdeka <florian.bezdeka at siemens.com>
---
 drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 21 +++++++++++++++++----
 1 file changed, 17 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index a71f0df263785dd8badc45292ca3067ab33bda05..949ced7e46d2814b57c6bd86b4886ac3bf33996c 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -3826,11 +3826,16 @@ static int stmmac_request_irq_multi_msi(struct net_device *dev)
 	struct stmmac_priv *priv = netdev_priv(dev);
 	struct stmmac_msi *msi = priv->msi;
 	enum request_irq_err irq_err;
+	cpumask_var_t affinity;
 	int irq_idx = 0;
 	char *int_name;
+	int node;
 	int ret;
 	int i;
 
+	if (!zalloc_cpumask_var(&affinity, GFP_KERNEL))
+		return -ENOMEM;
+
 	/* For common interrupt */
 	int_name = msi->int_name_mac;
 	sprintf(int_name, "%s:%s", dev->name, "mac");
@@ -3916,6 +3921,7 @@ static int stmmac_request_irq_multi_msi(struct net_device *dev)
 	}
 
 	/* Request Rx MSI irq */
+	node = dev_to_node(&priv->dev->dev);
 	for (i = 0; i < priv->plat->rx_queues_to_use; i++) {
 		if (i >= MTL_MAX_RX_QUEUES)
 			break;
@@ -3935,8 +3941,10 @@ static int stmmac_request_irq_multi_msi(struct net_device *dev)
 			irq_idx = i;
 			goto irq_error;
 		}
-		irq_set_affinity_hint(msi->rx_irq[i],
-				      cpumask_of(i % num_online_cpus()));
+
+		cpumask_clear(affinity);
+		cpumask_set_cpu(cpumask_local_spread(i, node), affinity);
+		irq_set_affinity_and_hint(msi->rx_irq[i], affinity);
 	}
 
 	/* Request Tx MSI irq */
@@ -3959,13 +3967,18 @@ static int stmmac_request_irq_multi_msi(struct net_device *dev)
 			irq_idx = i;
 			goto irq_error;
 		}
-		irq_set_affinity_hint(msi->tx_irq[i],
-				      cpumask_of(i % num_online_cpus()));
+
+		cpumask_clear(affinity);
+		cpumask_set_cpu(cpumask_local_spread(i, node), affinity);
+		irq_set_affinity_and_hint(msi->tx_irq[i], affinity);
 	}
 
+	free_cpumask_var(affinity);
+
 	return 0;
 
 irq_error:
+	free_cpumask_var(affinity);
 	stmmac_free_irq(dev, irq_err, irq_idx);
 	return ret;
 }

-- 
2.55.0




More information about the linux-arm-kernel mailing list