RE: [PATCH v2 8/8] irqchip/al-fic: add irq_set_affinity callback
From: Farber, Eliav
Date: Mon Oct 05 2026 - 07:23:22 EST
On Sun, 2026-10-05 at 01:25 +0000, Radu Rendec wrote:
> This is a common problem to all multiplexing irq drivers; not because
> the parent interrupt is shared but because changing the affinity of one
> child interrupt (by changing the parent interrupt's affinity under the
> hood) would have the side effect of changing the affinity of all its
> siblings.
>
> I think the correct behavior is to fail with -EINVAL in this case.
-EINVAL is not usable here because it restores the failure this patch
fixes. The consumer is arm-cmn. We have a SoC where its interrupt is
routed through a FIC group instead of a direct GIC SPI, and
drivers/perf/arm-cmn.c does
err = irq_set_affinity(irq, cpumask_of(cmn->cpu));
if (err)
return err;
at probe, so with no .irq_set_affinity callback the PMU does not probe at
all.
> If you insist on having the ability to change the child interrupts'
> affinity, you may want to look at this patch and do something similar:
> https://lore.kernel.org/all/20251128212055.1409093-4-rrendec@xxxxxxxxxx/
I implemented that for al-fic and tested it on hardware. It seems to
work: with the parent SPI pinned to one CPU and the child's affinity set
to another, the child dispatch is accounted on the target CPU, one
dispatch per parent interrupt, no re-fire storm.
What stops me from just sending it is that it changes the interrupt path
for every child of every FIC instance, not only for a child that asks for
affinity. .irq_pre_redirect is called before the affinity check, so it
runs on every dispatch. The ack therefore has to leave the flow handler
and be done in the parent context always, and .irq_ack has to become a
noop so it is not done twice. A level configured group has to be masked
in .irq_pre_redirect as well, because the FIC re-asserts the cause bit
while the source is still asserted, so for those groups the mask moves
into the parent context too. Today all of this happens inside
handle_level_irq() and handle_edge_irq(), under desc->lock.
Do you still consider that justified for this driver, given that the only
caller needing anything here is one that just needs the call not to fail?
Thanks,
Eliav