Commit b7c6244f authored by H. Peter Anvin's avatar H. Peter Anvin

x86: 32 bits: shrink and align IRQ stubs

Shrink the IRQ stubs on 32 bits down to just over four bytes per (we
fit seven into a 32-byte chunk.)  This shrinks the total icache
consumption of the IRQ stubs down to an even kilobyte, if all of them
are in active use.

The downside is that we end up with a double jump, which could have a
negative effect on some pipelines.  The double jump is always inside
the same cacheline on any modern chips (the exception being
486/Elan/Geode which have only 16-byte cachelines, but are unlikely to
have too many interrupt sources.)

To get the most effect, cache-align the IRQ stubs.
Signed-off-by: default avatarH. Peter Anvin <hpa@zytor.com>
parent 4687518c
...@@ -619,28 +619,37 @@ END(syscall_badsys) ...@@ -619,28 +619,37 @@ END(syscall_badsys)
27:; 27:;
/* /*
* Build the entry stubs and pointer table with * Build the entry stubs and pointer table with some assembler magic.
* some assembler magic. * We pack 7 stubs into a single 32-byte chunk, which will fit in a
* single cache line on all modern x86 implementations.
*/ */
.section .init.rodata,"a" .section .init.rodata,"a"
ENTRY(interrupt) ENTRY(interrupt)
.text .text
.p2align 5
.p2align CONFIG_X86_L1_CACHE_SHIFT
ENTRY(irq_entries_start) ENTRY(irq_entries_start)
RING0_INT_FRAME RING0_INT_FRAME
vector=FIRST_EXTERNAL_VECTOR vector=FIRST_EXTERNAL_VECTOR
.rept NR_VECTORS .rept (NR_VECTORS-FIRST_EXTERNAL_VECTOR+6)/7
ALIGN .balign 32
.if vector != FIRST_EXTERNAL_VECTOR .rept 7
.if vector < NR_VECTORS
.if vector != FIRST_EXTERNAL_VECTOR
CFI_ADJUST_CFA_OFFSET -4 CFI_ADJUST_CFA_OFFSET -4
.endif .endif
1: pushl $~(vector) 1: pushl $(~vector+0x80) /* Note: always in signed byte range */
CFI_ADJUST_CFA_OFFSET 4 CFI_ADJUST_CFA_OFFSET 4
jmp common_interrupt .if ((vector-FIRST_EXTERNAL_VECTOR)%7) != 6
.previous jmp 2f
.endif
.previous
.long 1b .long 1b
.text .text
vector=vector+1 vector=vector+1
.endif
.endr
2: jmp common_interrupt
.endr .endr
END(irq_entries_start) END(irq_entries_start)
...@@ -652,8 +661,9 @@ END(interrupt) ...@@ -652,8 +661,9 @@ END(interrupt)
* the CPU automatically disables interrupts when executing an IRQ vector, * the CPU automatically disables interrupts when executing an IRQ vector,
* so IRQ-flags tracing has to follow that: * so IRQ-flags tracing has to follow that:
*/ */
ALIGN .p2align CONFIG_X86_L1_CACHE_SHIFT
common_interrupt: common_interrupt:
addl $-0x80,(%esp) /* Adjust vector into the [-256,-1] range */
SAVE_ALL SAVE_ALL
TRACE_IRQS_OFF TRACE_IRQS_OFF
movl %esp,%eax movl %esp,%eax
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment