Hi Yury,
On Wed, 2026-08-19 at 14:45 -0400, Yury Norov wrote:
On Wed, Aug 19, 2026 at 04:30:32PM +0200, Florian Bezdeka wrote:
quoted
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 <redacted>
---
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);
If you want to spread more than one IRQ, you'd better convert your
loop into for_each_numa_hop_mask(). That way you don't need to
introduce new function. See the comment on top of
cpumask_local_spread():
I was knowingly ignoring this "optimization". As already noted the patch
1 thread: I'm currently trying to demonstrate the shortcomings,
optimizations will follow once we agree on a plan / vision.