Skip to content

Commit f6be053

Browse files
KAGA-KOKOksacilotto
authored andcommitted
x86/apic/vector: Fix ordering in vector assignment
BugLink: https://bugs.launchpad.net/bugs/1910816 commit 190113b upstream. Prarit reported that depending on the affinity setting the ' irq $N: Affinity broken due to vector space exhaustion.' message is showing up in dmesg, but the vector space on the CPUs in the affinity mask is definitely not exhausted. Shung-Hsi provided traces and analysis which pinpoints the problem: The ordering of trying to assign an interrupt vector in assign_irq_vector_any_locked() is simply wrong if the interrupt data has a valid node assigned. It does: 1) Try the intersection of affinity mask and node mask 2) Try the node mask 3) Try the full affinity mask 4) Try the full online mask Obviously #2 and #3 are in the wrong order as the requested affinity mask has to take precedence. In the observed cases #1 failed because the affinity mask did not contain CPUs from node 0. That made it allocate a vector from node 0, thereby breaking affinity and emitting the misleading message. Revert the order of #2 and #3 so the full affinity mask without the node intersection is tried before actually affinity is broken. If no node is assigned then only the full affinity mask and if that fails the full online mask is tried. Fixes: d6ffc6a ("x86/vector: Respect affinity mask in irq descriptor") Reported-by: Prarit Bhargava <[email protected]> Reported-by: Shung-Hsi Yu <[email protected]> Signed-off-by: Thomas Gleixner <[email protected]> Tested-by: Shung-Hsi Yu <[email protected]> Cc: [email protected] Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]> Signed-off-by: Kamal Mostafa <[email protected]> Signed-off-by: Kelsey Skunberg <[email protected]>
1 parent 24f346b commit f6be053

File tree

1 file changed

+14
-10
lines changed

1 file changed

+14
-10
lines changed

arch/x86/kernel/apic/vector.c

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -272,20 +272,24 @@ static int assign_irq_vector_any_locked(struct irq_data *irqd)
272272
const struct cpumask *affmsk = irq_data_get_affinity_mask(irqd);
273273
int node = irq_data_get_node(irqd);
274274

275-
if (node == NUMA_NO_NODE)
276-
goto all;
277-
/* Try the intersection of @affmsk and node mask */
278-
cpumask_and(vector_searchmask, cpumask_of_node(node), affmsk);
279-
if (!assign_vector_locked(irqd, vector_searchmask))
280-
return 0;
281-
/* Try the node mask */
282-
if (!assign_vector_locked(irqd, cpumask_of_node(node)))
283-
return 0;
284-
all:
275+
if (node != NUMA_NO_NODE) {
276+
/* Try the intersection of @affmsk and node mask */
277+
cpumask_and(vector_searchmask, cpumask_of_node(node), affmsk);
278+
if (!assign_vector_locked(irqd, vector_searchmask))
279+
return 0;
280+
}
281+
285282
/* Try the full affinity mask */
286283
cpumask_and(vector_searchmask, affmsk, cpu_online_mask);
287284
if (!assign_vector_locked(irqd, vector_searchmask))
288285
return 0;
286+
287+
if (node != NUMA_NO_NODE) {
288+
/* Try the node mask */
289+
if (!assign_vector_locked(irqd, cpumask_of_node(node)))
290+
return 0;
291+
}
292+
289293
/* Try the full online mask */
290294
return assign_vector_locked(irqd, cpu_online_mask);
291295
}

0 commit comments

Comments
 (0)