Fix alignment of i386 interrupt entry stubs
PATCH 1/1 Fix alignment of i386 interrupt entry stubs
This patch provides for improved alignment of the entry stubs, to avoid crossing cache lines. This is accomplished by using a fixed size for each stub (16 bytes for IO-APIC, 8 bytes otherwise). The fixed size allows for removal of the pointer table. Also, subtracting 256 from the irq number is no longer necessary. orig_eax is no longer used by the exit code to distinguish between interrupts and system calls.
--
Brian Gerst
arch/i386/kernel/entry.S +5 -15
@@ -374,27 +374,17 @@ movl $-ENOSYS,EAX(%esp) jmp resume_userspace -/* - * Build the entry stubs and pointer table with - * some assembler magic. - */ -.data -ENTRY(interrupt) -.text - +/* Build the IRQ entry stubs */ vector=0 -ENTRY(irq_entries_start) + .align IRQ_STUB_SIZE,0x90 +ENTRY(irq_entries) .rept NR_IRQS - ALIGN -1: pushl $vector-256 +1: pushl $vector jmp common_interrupt -.data - .long 1b -.text + .align IRQ_STUB_SIZE,0x90 vector=vector+1 .endr - ALIGN common_interrupt: SAVE_ALL call do_IRQ
arch/i386/kernel/i8259.c +1 -1
@@ -425,7 +425,7 @@for (i =0 ; i <NR_IRQS ; i++) {int vector =FIRST_EXTERNAL_VECTOR + i;if (vector !=SYSCALL_VECTOR ) -set_intr_gate (vector, interrupt[i]); +set_intr_gate (vector, &irq_entries[i]); }/* setup after call gates are initialised (usually add in
arch/i386/kernel/io_apic.c +3 -3
@@ -1190,7 +1190,7 @@else irq_desc[irq].handler = &ioapic_edge_irq_type; -set_intr_gate (vector, interrupt[irq]); +set_intr_gate (vector, &irq_entries[irq]);if (!apic && (irq <16 ))disable_8259A_irq (irq);
@@ -2024,7 +2024,7 @@*/ disable_8259A_irq (0 ); vector =assign_irq_vector (0 ); -set_intr_gate (vector, interrupt[0 ]); +set_intr_gate (vector, &irq_entries[0 ]);/* * Subtle, code in do_timer_interrupt() expects an AEOI
@@ -2312,7 +2312,7 @@ irq_desc[irq].handler = &ioapic_level_irq_type; -set_intr_gate (entry.vector, interrupt[irq]); +set_intr_gate (entry.vector, &irq_entries[irq]);if (!ioapic && (irq <16 ))disable_8259A_irq (irq);
arch/i386/kernel/irq.c +1 -1
@@ -354,7 +354,7 @@* 0 return value means that this irq is already being * handled by some other CPU. (or is disabled) */ -int irq = regs.orig_eax &0xff ;/* high bits used in ret_from_ code */ +int irq = regs.orig_eax;int cpu =smp_processor_id ();irq_desc_t *desc = irq_desc + irq;struct irqaction * action;
arch/i386/kernel/smpboot.c +1 -1
@@ -1159,7 +1159,7 @@* IRQ0 must be given a fixed assignment and initialized, * because it's used before the IO-APIC is set up. */ -set_intr_gate (FIRST_DEVICE_VECTOR , interrupt[0 ]); +set_intr_gate (FIRST_DEVICE_VECTOR , &irq_entries[0 ]);/* * The reschedule interrupt is a CPU-to-CPU reschedule-helper
include/asm-i386/hw_irq.h +1 -1
@@ -27,7 +27,7 @@extern int irq_vector[NR_IRQS ];#define IO_APIC_VECTOR (irq) irq_vector[irq] -extern void (*interrupt[NR_IRQS ])(void ); +extern char irq_entries[NR_IRQS ][IRQ_STUB_SIZE ];#ifdef CONFIG_SMP extern asmlinkage void reschedule_interrupt(void);
include/asm-i386/mach-default/irq_vectors.h +2 -0
@@ -78,8 +78,10 @@*/ #ifdef CONFIG_X86_IO_APIC #define NR_IRQS 224 +#define IRQ_STUB_SIZE 16#else #define NR_IRQS 16 +#define IRQ_STUB_SIZE 8#endif #define FPU_IRQ 13
include/asm-i386/mach-pc9800/irq_vectors.h +2 -0
@@ -78,8 +78,10 @@*/ #ifdef CONFIG_X86_IO_APIC #define NR_IRQS 224 +#define IRQ_STUB_SIZE 16#else #define NR_IRQS 16 +#define IRQ_STUB_SIZE 8#endif #define FPU_IRQ 8
include/asm-i386/mach-visws/irq_vectors.h +1 -0
@@ -50,6 +50,7 @@* */ #define NR_IRQS 224 +#define IRQ_STUB_SIZE 16#define FPU_IRQ 13
include/asm-i386/mach-voyager/irq_vectors.h +1 -0
@@ -56,6 +56,7 @@#define VIC_CPU_BOOT_ERRATA_CPI (VIC_CPI_LEVEL0 + 8)#define NR_IRQS 224 +#define IRQ_STUB_SIZE 16#define FPU_IRQ 13