x86/IRQ: re-use legacy vector ranges on APs

The legacy vectors have been actively used on CPU 0 only. CPUs not
sharing vector space with CPU 0 can easily re-use them, slightly
increasing the relatively scarce resource of total vectors available in
the system. As a result the legacy vector range simply becomes a
sub-range of the dynamic one, with an extra check performed in
_assign_irq_vector() (we can't rely on the
"per_cpu(vector_irq, new_cpu)[vector] >= 0" check in the subsequent
loop, as we need to also exclude vectors of disabled legacy IRQs).

Suggested-by: Andrew Cooper <andrew.cooper3@citrix.com>
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Andrew Cooper <andrew.cooper3@citrix.com>
This commit is contained in:
Jan Beulich committed 2019-12-27 09:54:59 +01:00
1 parent 8fb4e83dc3
commit 3fba06ba9f
4 files changed
+39 -14

No files matched your search

+2 -3
View File
@@ -2389,8 +2389,7 @@ int ioapic_guest_write(unsigned long physbase, unsigned int reg, u32 val)
}
if ( desc->arch.vector <= 0 || desc->arch.vector > LAST_DYNAMIC_VECTOR ||
(desc->arch.vector >= FIRST_LEGACY_VECTOR &&
desc->arch.vector <= LAST_LEGACY_VECTOR) )
desc->handler->enable == enable_8259A_irq )
{
int vector = desc->arch.vector;
@@ -2617,7 +2616,7 @@ void __init init_ioapic_mappings(void)
if ( nr_irqs == 0 )
nr_irqs = cpu_has_apic ?
max(16U + num_present_cpus() * NR_DYNAMIC_VECTORS,
max(0U + num_present_cpus() * NR_DYNAMIC_VECTORS,
8 * nr_irqs_gsi) :
nr_irqs_gsi;
else if ( nr_irqs < 16 )
+24 -6
View File
@@ -361,17 +361,25 @@ void destroy_irq(unsigned int irq)
int irq_to_vector(int irq)
{
int vector = IRQ_VECTOR_UNASSIGNED;
const struct irq_desc *desc;
BUG_ON(irq >= nr_irqs || irq < 0);
desc = irq_to_desc(irq);
if (IO_APIC_IRQ(irq))
{
vector = irq_to_desc(irq)->arch.vector;
if (vector >= FIRST_LEGACY_VECTOR && vector <= LAST_LEGACY_VECTOR)
vector = desc->arch.vector;
/*
* Both parts of the condition are needed here during early boot, as
* at that time IRQ0 in particular may still have the 8259A chip set,
* but has already got its special IRQ0_VECTOR.
*/
if ( desc->handler->enable == enable_8259A_irq &&
vector >= FIRST_LEGACY_VECTOR && vector <= LAST_LEGACY_VECTOR )
vector = 0;
}
else if (MSI_IRQ(irq))
vector = irq_to_desc(irq)->arch.vector;
vector = desc->arch.vector;
else
vector = LEGACY_VECTOR(irq);
@@ -568,6 +576,10 @@ next:
&& test_bit(vector, irq_used_vectors) )
goto next;
if ( cpumask_test_cpu(0, vec_mask) &&
vector >= FIRST_LEGACY_VECTOR && vector <= LAST_LEGACY_VECTOR )
goto next;
for_each_cpu(new_cpu, vec_mask)
if (per_cpu(vector_irq, new_cpu)[vector] >= 0)
goto next;
@@ -713,6 +725,10 @@ void irq_move_cleanup_interrupt(struct cpu_user_regs *regs)
{
unsigned vector, me;
/* This interrupt should not nest inside others. */
BUILD_BUG_ON(APIC_PRIO_CLASS(IRQ_MOVE_CLEANUP_VECTOR) !=
APIC_PRIO_CLASS(FIRST_DYNAMIC_VECTOR));
ack_APIC_irq();
me = smp_processor_id();
@@ -730,14 +746,15 @@ void irq_move_cleanup_interrupt(struct cpu_user_regs *regs)
if ((int)irq < 0)
continue;
if ( vector >= FIRST_LEGACY_VECTOR && vector <= LAST_LEGACY_VECTOR )
continue;
desc = irq_to_desc(irq);
if (!desc)
continue;
spin_lock(&desc->lock);
if (desc->handler->enable == enable_8259A_irq)
goto unlock;
if (!desc->arch.move_cleanup_count)
goto unlock;
@@ -1894,6 +1911,7 @@ void do_IRQ(struct cpu_user_regs *regs)
kind = "";
if ( !(vector >= FIRST_LEGACY_VECTOR &&
vector <= LAST_LEGACY_VECTOR &&
!smp_processor_id() &&
bogus_8259A_irq(vector - FIRST_LEGACY_VECTOR)) )
{
printk("CPU%u: No irq handler for vector %02x (IRQ %d%s)\n",
+3
View File
@@ -119,6 +119,9 @@
/* Only available in x2APIC mode */
#define APIC_SELF_IPI 0x3F0
/* Applicable to vectors, TPR, and PPR. */
#define APIC_PRIO_CLASS(v) ((v) & 0xF0)
#define APIC_BASE __fix_to_virt(FIX_APIC_BASE)
/* It's only used in x2APIC mode of an x2APIC unit. */
+10 -5
View File
@@ -19,22 +19,27 @@
#define IRQ0_VECTOR 0xf0
/* Legacy PIC uses vectors 0x20-0x2f. */
#define FIRST_LEGACY_VECTOR 0x20
#define FIRST_LEGACY_VECTOR FIRST_DYNAMIC_VECTOR
#define LAST_LEGACY_VECTOR (FIRST_LEGACY_VECTOR + 0xf)
#define HYPERCALL_VECTOR 0x82
#define LEGACY_SYSCALL_VECTOR 0x80
/* Dynamically-allocated vectors available to any driver. */
#define FIRST_DYNAMIC_VECTOR (LAST_LEGACY_VECTOR + 1)
/*
* Dynamically-allocated vectors available to any driver. Note that the
* legacy vector range is a sub-range of this one, re-used on CPUs not
* sharing vectors with CPU 0.
*/
#define FIRST_DYNAMIC_VECTOR 0x20
#define LAST_DYNAMIC_VECTOR 0xef
#define NR_DYNAMIC_VECTORS (LAST_DYNAMIC_VECTOR - FIRST_DYNAMIC_VECTOR + 1)
#define IRQ_MOVE_CLEANUP_VECTOR FIRST_DYNAMIC_VECTOR
/* There's no IRQ2 at the PIC. */
#define IRQ_MOVE_CLEANUP_VECTOR (FIRST_LEGACY_VECTOR + 2)
#define NR_VECTORS 256
#define FIRST_IRQ_VECTOR FIRST_LEGACY_VECTOR
#define FIRST_IRQ_VECTOR FIRST_DYNAMIC_VECTOR
#define LAST_IRQ_VECTOR LAST_HIPRIORITY_VECTOR
#endif /* _ASM_IRQ_VECTORS_H */
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.