Patch "genirq/cpuhotplug: Enforce affinity setting on startup of managed irqs" has been added to the 4.13-stable tree
Subsystems (2)
This is a note to let you know that I've just added the patch titled
genirq/cpuhotplug: Enforce affinity setting on startup of managed irqs
to the 4.13-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
genirq-cpuhotplug-enforce-affinity-setting-on-startup-of-managed-irqs.patch
and it can be found in the queue-4.13 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
e43b3b58548051f8809391eb7bec7a27ed3003eaMon Sep 17 00:00:00 2001
From: Thomas Gleixner <[email protected]>
Date: Wed, 4 Oct 2017 21:07:38 +0200
Subject: genirq/cpuhotplug: Enforce affinity setting on startup of managed irqs
From: Thomas Gleixner <[email protected]>
commit e43b3b58548051f8809391eb7bec7a27ed3003ea upstream.
Managed interrupts can end up in a stale state on CPU hotplug. If the interrupt is not targeting a single CPU, i.e. the affinity mask spawns multiple CPUs then the following can happen:
After boot:
dstate: 0x01601200
IRQD_ACTIVATED
IRQD_IRQ_STARTED
IRQD_SINGLE_TARGET
IRQD_AFFINITY_SET
IRQD_AFFINITY_MANAGED
node: 0 affinity: 24-31 effectiv: 24 pending: 0
After offlining CPU 31 - 24
dstate: 0x01a31000
IRQD_IRQ_DISABLED
IRQD_IRQ_MASKED
IRQD_SINGLE_TARGET
IRQD_AFFINITY_SET
IRQD_AFFINITY_MANAGED
IRQD_MANAGED_SHUTDOWN
node: 0 affinity: 24-31 effectiv: 24 pending: 0
Now CPU 25 gets onlined again, so it should get the effective interrupt affinity for this interruopt, but due to the x86 interrupt affinity setter restrictions this ends up after restarting the interrupt with:
dstate: 0x01601300
IRQD_ACTIVATED
IRQD_IRQ_STARTED
IRQD_SINGLE_TARGET
IRQD_AFFINITY_SET
IRQD_SETAFFINITY_PENDING
IRQD_AFFINITY_MANAGED
node: 0 affinity: 24-31 effectiv: 24 pending: 24-31
So the interrupt is still affine to CPU 24, which was the last CPU to go offline of that affinity set and the move to an online CPU within 24-31, in this case 25, is pending. This mechanism is x86/ia64 specific as those architectures cannot move interrupts from thread context and do this when an interrupt is actually handled. So the move is set to pending.
Whats worse is that offlining CPU 25 again results in:
dstate: 0x01601300
IRQD_ACTIVATED
IRQD_IRQ_STARTED
IRQD_SINGLE_TARGET
IRQD_AFFINITY_SET
IRQD_SETAFFINITY_PENDING
IRQD_AFFINITY_MANAGED
node: 0 affinity: 24-31 effectiv: 24 pending: 24-31
This means the interrupt has not been shut down, because the outgoing CPU is not in the effective affinity mask, but of course nothing notices that the effective affinity mask is pointing at an offline CPU.
In the case of restarting a managed interrupt the move restriction does not apply, so the affinity setting can be made unconditional. This needs to be done _before_ the interrupt is started up as otherwise the condition for moving it from thread context would not longer be fulfilled.
With that change applied onlining CPU 25 after offlining 31-24 results in:
dstate: 0x01600200
IRQD_ACTIVATED
IRQD_IRQ_STARTED
IRQD_SINGLE_TARGET
IRQD_AFFINITY_MANAGED
node: 0 affinity: 24-31 effectiv: 25
pending:
And after offlining CPU 25:
dstate: 0x01a30000
IRQD_IRQ_DISABLED
IRQD_IRQ_MASKED
IRQD_SINGLE_TARGET
IRQD_AFFINITY_MANAGED
IRQD_MANAGED_SHUTDOWN
node: 0 affinity: 24-31 effectiv: 25
pending:
which is the correct and expected result.
--- kernel/irq/chip.c | 2 +- kernel/irq/manage.c | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-)
kernel/irq/chip.c +1 -1
@@ -265,8 +265,8 @@ int irq_startup(struct irq_desc *desc, birq_setup_affinity (desc);break ;case IRQ_STARTUP_MANAGED : +irq_do_set_affinity (d, aff, false); ret =__irq_startup (desc); -irq_set_affinity_locked (d, aff, false);break ;case IRQ_STARTUP_ABORT :return 0 ;
kernel/irq/manage.c +3 -0
@@ -175,6 +175,9 @@ int irq_do_set_affinity(struct irq_datastruct irq_chip *chip =irq_data_get_irq_chip (data);int ret; +if (!chip || !chip->irq_set_affinity) +return -EINVAL ; + ret = chip->irq_set_affinity (data, mask, force);switch (ret) {case IRQ_SET_MASK_OK :
Patches currently in stable-queue which might be from [email protected] are
queue-4.13/genirq-cpuhotplug-add-sanity-check-for-effective-affinity-mask.patch queue-4.13/genirq-cpuhotplug-enforce-affinity-setting-on-startup-of-managed-irqs.patch