ipipe: x86: Rework and fix vector to IRQ translation
Subsystems (2)
PATCH 1/1 ipipe: x86: Rework and fix vector to IRQ translation
Depending on the configuration and hardware, the kernel may allocate device IRQs in the range above our static FIRST_SYSTEM_VECTOR. This happens quickly with a non-trivial number of MSI-X capable devices.
Fix this and also optimize the critical vector->IRQ translation by filling the kernel's per-CPU vector_irq table also with I-pipe translations.
Signed-off-by Jan Kiszka <[email protected]>
--- arch/x86/include/asm/ipipe_base.h | 6 ++++++ arch/x86/kernel/apic/io_apic.c | 1 + arch/x86/kernel/ipipe.c | 30 +++++++++++++++++------------- arch/x86/kernel/irqinit.c | 1 + arch/x86/platform/uv/tlb_uv.c | 5 +++++ 5 files changed, 30 insertions(+), 13 deletions(-)
arch/x86/include/asm/ipipe_base.h +6 -0
@@ -211,6 +211,12 @@ void __ipipe_halt_root(void);void __ipipe_serial_debug (const char *fmt, ...); +#ifdef CONFIG_IPIPE +void ipipe_init_vector_irq (int cpu); +#else +static inline void ipipe_init_vector_irq (int cpu) { } +#endif +#endif /* !__ASSEMBLY__ */ #endif /* !__X86_IPIPE_BASE_H */
arch/x86/kernel/apic/io_apic.c +1 -0
@@ -1205,6 +1205,7 @@ void __setup_vector_irq(int cpu)if (!cpumask_test_cpu (cpu, cfg->domain))per_cpu (vector_irq, cpu)[vector] =-1 ; } +ipipe_init_vector_irq (cpu);raw_spin_unlock (&vector_lock); }
arch/x86/kernel/ipipe.c +17 -13
@@ -141,6 +141,19 @@ static void __ipipe_null_handler(unsigned irq, void *cookie)/* __ipipe_enable_pipeline() -- We are running on the boot CPU, hw interrupts are off, and secondary CPUs are still lost in space. */ +void ipipe_init_vector_irq (int cpu) +{ +unsigned int vector; + +per_cpu (vector_irq, cpu)[IRQ_MOVE_CLEANUP_VECTOR ] = +IRQ_MOVE_CLEANUP_VECTOR ; + +for (vector = first_system_vector; vector <NR_VECTORS ; vector++) +if (per_cpu (vector_irq, cpu)[vector] ==-1 ) +per_cpu (vector_irq, cpu)[vector] = +ipipe_apic_vector_irq (vector); +} +void __init __ipipe_enable_pipeline (void ) {unsigned int vector, irq;
@@ -685,23 +698,14 @@ int __ipipe_syscall_root(struct pt_regs *regs)int __ipipe_handle_irq (struct pt_regs *regs) {struct ipipe_domain *this_domain, *next_domain; -unsigned int vector = regs->orig_ax, irq; +int irq, vector = regs->orig_ax;struct list_head *head, *pos;struct pt_regs *tick_regs;int m_ack; -if ((long )regs->orig_ax <0 ) { - vector = ~vector; -#ifdef CONFIG_X86_LOCAL_APIC -if (vector >=FIRST_SYSTEM_VECTOR ) - irq =ipipe_apic_vector_irq (vector); -#ifdef CONFIG_SMP - else if (vector == IRQ_MOVE_CLEANUP_VECTOR) - irq = vector; -#endif /* CONFIG_SMP */ - else -#endif /* CONFIG_X86_LOCAL_APIC */ - irq =__get_cpu_var (vector_irq)[vector]; +if (vector <0 ) { + irq =__get_cpu_var (vector_irq)[~vector]; +BUG_ON (irq <0 ); m_ack =0 ; }else {/* This is a self-triggered one. */ irq = vector;
arch/x86/kernel/irqinit.c +1 -0
@@ -232,6 +232,7 @@ static void __init apic_intr_init(void)alloc_intr_gate (IPIPE_SERVICE_VECTOR2 , ipipe_ipi2);alloc_intr_gate (IPIPE_SERVICE_VECTOR3 , ipipe_ipi3);#endif +ipipe_init_vector_irq (0 );#endif }
arch/x86/platform/uv/tlb_uv.c +5 -0
@@ -1640,6 +1640,11 @@ static int __init uv_bau_init(void)uv_enable_timeouts ();alloc_intr_gate (vector, uv_bau_message_intr1); +#ifdef CONFIG_IPIPE +for_each_possible_cpu (cur_cpu) +per_cpu (vector_irq, cur_cpu)[vector] = +ipipe_apic_vector_irq (vector); +#endif for_each_possible_blade (uvhub) {if (uv_blade_nr_possible_cpus (uvhub)) {
Signature · 1 line
1.7.1