[PATCH v6 05/29] x86/apic/vector: Do not allocate vectors for NMIs
Ricardo Neri
ricardo.neri-calderon at linux.intel.com
Fri May 6 09:59:44 AEST 2022
Vectors are meaningless when allocating IRQs with NMI as the delivery mode.
In such case, skip the reservation of IRQ vectors. Do it in the lowest-
level functions where the actual IRQ reservation takes place.
Since NMIs target specific CPUs, keep the functionality to find the best
CPU.
Cc: Andi Kleen <ak at linux.intel.com>
Cc: "Ravi V. Shankar" <ravi.v.shankar at intel.com>
Cc: Stephane Eranian <eranian at google.com>
Cc: iommu at lists.linux-foundation.org
Cc: linuxppc-dev at lists.ozlabs.org
Cc: x86 at kernel.org
Reviewed-by: Tony Luck <tony.luck at intel.com>
Signed-off-by: Ricardo Neri <ricardo.neri-calderon at linux.intel.com>
---
Changes since v5:
* Introduced this patch.
Changes since v4:
* N/A
Changes since v3:
* N/A
Changes since v2:
* N/A
Changes since v1:
* N/A
---
arch/x86/kernel/apic/vector.c | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)
diff --git a/arch/x86/kernel/apic/vector.c b/arch/x86/kernel/apic/vector.c
index 838e220e8860..11f881f45cec 100644
--- a/arch/x86/kernel/apic/vector.c
+++ b/arch/x86/kernel/apic/vector.c
@@ -245,11 +245,20 @@ assign_vector_locked(struct irq_data *irqd, const struct cpumask *dest)
if (apicd->move_in_progress || !hlist_unhashed(&apicd->clist))
return -EBUSY;
+ if (apicd->hw_irq_cfg.delivery_mode == APIC_DELIVERY_MODE_NMI) {
+ cpu = irq_matrix_find_best_cpu(vector_matrix, dest);
+ apicd->cpu = cpu;
+ vector = 0;
+ goto no_vector;
+ }
+
vector = irq_matrix_alloc(vector_matrix, dest, resvd, &cpu);
trace_vector_alloc(irqd->irq, vector, resvd, vector);
if (vector < 0)
return vector;
apic_update_vector(irqd, vector, cpu);
+
+no_vector:
apic_update_irq_cfg(irqd, vector, cpu);
return 0;
@@ -321,12 +330,22 @@ assign_managed_vector(struct irq_data *irqd, const struct cpumask *dest)
/* set_affinity might call here for nothing */
if (apicd->vector && cpumask_test_cpu(apicd->cpu, vector_searchmask))
return 0;
+
+ if (apicd->hw_irq_cfg.delivery_mode == APIC_DELIVERY_MODE_NMI) {
+ cpu = irq_matrix_find_best_cpu_managed(vector_matrix, dest);
+ apicd->cpu = cpu;
+ vector = 0;
+ goto no_vector;
+ }
+
vector = irq_matrix_alloc_managed(vector_matrix, vector_searchmask,
&cpu);
trace_vector_alloc_managed(irqd->irq, vector, vector);
if (vector < 0)
return vector;
apic_update_vector(irqd, vector, cpu);
+
+no_vector:
apic_update_irq_cfg(irqd, vector, cpu);
return 0;
}
@@ -376,6 +395,10 @@ static void x86_vector_deactivate(struct irq_domain *dom, struct irq_data *irqd)
if (apicd->has_reserved)
return;
+ /* NMI IRQs do not have associated vectors; nothing to do. */
+ if (apicd->hw_irq_cfg.delivery_mode == APIC_DELIVERY_MODE_NMI)
+ return;
+
raw_spin_lock_irqsave(&vector_lock, flags);
clear_irq_vector(irqd);
if (apicd->can_reserve)
@@ -472,6 +495,10 @@ static void vector_free_reserved_and_managed(struct irq_data *irqd)
trace_vector_teardown(irqd->irq, apicd->is_managed,
apicd->has_reserved);
+ /* NMI IRQs do not have associated vectors; nothing to do. */
+ if (apicd->hw_irq_cfg.delivery_mode == APIC_DELIVERY_MODE_NMI)
+ return;
+
if (apicd->has_reserved)
irq_matrix_remove_reserved(vector_matrix);
if (apicd->is_managed)
--
2.17.1
More information about the Linuxppc-dev
mailing list