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

From: Florian Bezdeka

Date: Wed Aug 19 2026 - 10:36:02 EST


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@xxxxxxxxxxx>
---
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