diff options
author | Andi Kleen <ak@suse.de> | 2005-09-12 12:49:24 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-09-12 13:49:58 -0400 |
commit | e5bc8b6baf86538f3d0407cf0880f86aec828a13 (patch) | |
tree | b67a98a866a51286fd342d08b27b511826875138 /arch/x86_64/kernel/i8259.c | |
parent | 83b942bd3437d84d6ddf582477120b6b86369052 (diff) |
[PATCH] x86-64: Make remote TLB flush more scalable
Instead of using a global spinlock to protect the state
of the remote TLB flush use a lock and state for each sending CPU.
To tell the receiver where to look for the state use 8 different
call vectors. Each CPU uses a specific vector to trigger flushes on other
CPUs. Depending on the received vector the target CPUs look into
the right per cpu variable for the flush data.
When the system has more than 8 CPUs they are hashed to the 8 available
vectors. The limited global vector space forces us to this right now.
In future when interrupts are split into per CPU domains this could be
fixed, at the cost of needing more IPIs in flat mode.
Also some minor cleanup in the smp flush code and remove some outdated
debug code.
Requires patch to move cpu_possible_map setup earlier.
Signed-off-by: Andi Kleen <ak@suse.de>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/x86_64/kernel/i8259.c')
-rw-r--r-- | arch/x86_64/kernel/i8259.c | 20 |
1 files changed, 17 insertions, 3 deletions
diff --git a/arch/x86_64/kernel/i8259.c b/arch/x86_64/kernel/i8259.c index a89169095129..909fc63c03b6 100644 --- a/arch/x86_64/kernel/i8259.c +++ b/arch/x86_64/kernel/i8259.c | |||
@@ -486,7 +486,14 @@ void spurious_interrupt(void); | |||
486 | void error_interrupt(void); | 486 | void error_interrupt(void); |
487 | void reschedule_interrupt(void); | 487 | void reschedule_interrupt(void); |
488 | void call_function_interrupt(void); | 488 | void call_function_interrupt(void); |
489 | void invalidate_interrupt(void); | 489 | void invalidate_interrupt0(void); |
490 | void invalidate_interrupt1(void); | ||
491 | void invalidate_interrupt2(void); | ||
492 | void invalidate_interrupt3(void); | ||
493 | void invalidate_interrupt4(void); | ||
494 | void invalidate_interrupt5(void); | ||
495 | void invalidate_interrupt6(void); | ||
496 | void invalidate_interrupt7(void); | ||
490 | void thermal_interrupt(void); | 497 | void thermal_interrupt(void); |
491 | void i8254_timer_resume(void); | 498 | void i8254_timer_resume(void); |
492 | 499 | ||
@@ -562,8 +569,15 @@ void __init init_IRQ(void) | |||
562 | */ | 569 | */ |
563 | set_intr_gate(RESCHEDULE_VECTOR, reschedule_interrupt); | 570 | set_intr_gate(RESCHEDULE_VECTOR, reschedule_interrupt); |
564 | 571 | ||
565 | /* IPI for invalidation */ | 572 | /* IPIs for invalidation */ |
566 | set_intr_gate(INVALIDATE_TLB_VECTOR, invalidate_interrupt); | 573 | set_intr_gate(INVALIDATE_TLB_VECTOR_START+0, invalidate_interrupt0); |
574 | set_intr_gate(INVALIDATE_TLB_VECTOR_START+1, invalidate_interrupt1); | ||
575 | set_intr_gate(INVALIDATE_TLB_VECTOR_START+2, invalidate_interrupt2); | ||
576 | set_intr_gate(INVALIDATE_TLB_VECTOR_START+3, invalidate_interrupt3); | ||
577 | set_intr_gate(INVALIDATE_TLB_VECTOR_START+4, invalidate_interrupt4); | ||
578 | set_intr_gate(INVALIDATE_TLB_VECTOR_START+5, invalidate_interrupt5); | ||
579 | set_intr_gate(INVALIDATE_TLB_VECTOR_START+6, invalidate_interrupt6); | ||
580 | set_intr_gate(INVALIDATE_TLB_VECTOR_START+7, invalidate_interrupt7); | ||
567 | 581 | ||
568 | /* IPI for generic function call */ | 582 | /* IPI for generic function call */ |
569 | set_intr_gate(CALL_FUNCTION_VECTOR, call_function_interrupt); | 583 | set_intr_gate(CALL_FUNCTION_VECTOR, call_function_interrupt); |