Re: [PATCH RFC 3/3] net: stmmac: Migrate IRQ balancing to cpumask_local_spread()
From: Florian Bezdeka <hidden>
Date: 2026-08-21 16:40:25
Also in:
linux-arm-kernel, linux-rt-devel, lkml
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.