diff options
| author | Tejun Heo <tj@kernel.org> | 2009-08-03 01:12:19 -0400 |
|---|---|---|
| committer | Tejun Heo <tj@kernel.org> | 2009-08-03 12:29:34 -0400 |
| commit | bdf977b37418cdf8a2252504779a7e12a09b7575 (patch) | |
| tree | 0f3896a5b39c35f3018d3cb16f797ae7d6c4a66b /arch | |
| parent | 3e352aa8ee2bd48f1a19c7742810b3a4a7ba605e (diff) | |
x86, percpu: Collect hot percpu variables into one cacheline
On x86_64, percpu variables current_task and kernel_stack are used for
get_current() and current_thread_info() respectively and thus are
often used close to each other. Move definition of current_task to
kernel/cpu/common.c right above kernel_stack definition and align it
to cacheline so that they always fall into the same cacheline. Two
percpu variables defined there together - irq_stack_ptr and irq_count
- are also pretty hot and will benefit from sharing the cacheline.
For consistency, current_task definition for x86_32 is also moved to
kernel/cpu/common.c.
Putting current_task and kernel_stack into the same cacheline was
suggested by Linus Torvalds.
Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Ingo Molnar <mingo@elte.hu>
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Diffstat (limited to 'arch')
| -rw-r--r-- | arch/x86/kernel/cpu/common.c | 15 | ||||
| -rw-r--r-- | arch/x86/kernel/process_32.c | 3 | ||||
| -rw-r--r-- | arch/x86/kernel/process_64.c | 3 |
3 files changed, 13 insertions, 8 deletions
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 12493c5485e5..1bd88ed978bd 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c | |||
| @@ -987,13 +987,21 @@ struct desc_ptr idt_descr = { 256 * 16 - 1, (unsigned long) idt_table }; | |||
| 987 | DEFINE_PER_CPU_FIRST(union irq_stack_union, | 987 | DEFINE_PER_CPU_FIRST(union irq_stack_union, |
| 988 | irq_stack_union) __aligned(PAGE_SIZE); | 988 | irq_stack_union) __aligned(PAGE_SIZE); |
| 989 | 989 | ||
| 990 | DEFINE_PER_CPU(char *, irq_stack_ptr) = | 990 | /* |
| 991 | init_per_cpu_var(irq_stack_union.irq_stack) + IRQ_STACK_SIZE - 64; | 991 | * The following four percpu variables are hot. Align current_task to |
| 992 | * cacheline size such that all four fall in the same cacheline. | ||
| 993 | */ | ||
| 994 | DEFINE_PER_CPU(struct task_struct *, current_task) ____cacheline_aligned = | ||
| 995 | &init_task; | ||
| 996 | EXPORT_PER_CPU_SYMBOL(current_task); | ||
| 992 | 997 | ||
| 993 | DEFINE_PER_CPU(unsigned long, kernel_stack) = | 998 | DEFINE_PER_CPU(unsigned long, kernel_stack) = |
| 994 | (unsigned long)&init_thread_union - KERNEL_STACK_OFFSET + THREAD_SIZE; | 999 | (unsigned long)&init_thread_union - KERNEL_STACK_OFFSET + THREAD_SIZE; |
| 995 | EXPORT_PER_CPU_SYMBOL(kernel_stack); | 1000 | EXPORT_PER_CPU_SYMBOL(kernel_stack); |
| 996 | 1001 | ||
| 1002 | DEFINE_PER_CPU(char *, irq_stack_ptr) = | ||
| 1003 | init_per_cpu_var(irq_stack_union.irq_stack) + IRQ_STACK_SIZE - 64; | ||
| 1004 | |||
| 997 | DEFINE_PER_CPU(unsigned int, irq_count) = -1; | 1005 | DEFINE_PER_CPU(unsigned int, irq_count) = -1; |
| 998 | 1006 | ||
| 999 | /* | 1007 | /* |
| @@ -1041,6 +1049,9 @@ DEFINE_PER_CPU(struct orig_ist, orig_ist); | |||
| 1041 | 1049 | ||
| 1042 | #else /* CONFIG_X86_64 */ | 1050 | #else /* CONFIG_X86_64 */ |
| 1043 | 1051 | ||
| 1052 | DEFINE_PER_CPU(struct task_struct *, current_task) = &init_task; | ||
| 1053 | EXPORT_PER_CPU_SYMBOL(current_task); | ||
| 1054 | |||
| 1044 | #ifdef CONFIG_CC_STACKPROTECTOR | 1055 | #ifdef CONFIG_CC_STACKPROTECTOR |
| 1045 | DEFINE_PER_CPU(unsigned long, stack_canary); | 1056 | DEFINE_PER_CPU(unsigned long, stack_canary); |
| 1046 | #endif | 1057 | #endif |
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c index 59f4524984af..daa4107be3b4 100644 --- a/arch/x86/kernel/process_32.c +++ b/arch/x86/kernel/process_32.c | |||
| @@ -61,9 +61,6 @@ | |||
| 61 | 61 | ||
| 62 | asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); | 62 | asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); |
| 63 | 63 | ||
| 64 | DEFINE_PER_CPU(struct task_struct *, current_task) = &init_task; | ||
| 65 | EXPORT_PER_CPU_SYMBOL(current_task); | ||
| 66 | |||
| 67 | /* | 64 | /* |
| 68 | * Return saved PC of a blocked thread. | 65 | * Return saved PC of a blocked thread. |
| 69 | */ | 66 | */ |
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index ebefb5407b9d..c4c675d5ba1a 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c | |||
| @@ -55,9 +55,6 @@ | |||
| 55 | 55 | ||
| 56 | asmlinkage extern void ret_from_fork(void); | 56 | asmlinkage extern void ret_from_fork(void); |
| 57 | 57 | ||
| 58 | DEFINE_PER_CPU(struct task_struct *, current_task) = &init_task; | ||
| 59 | EXPORT_PER_CPU_SYMBOL(current_task); | ||
| 60 | |||
| 61 | DEFINE_PER_CPU(unsigned long, old_rsp); | 58 | DEFINE_PER_CPU(unsigned long, old_rsp); |
| 62 | static DEFINE_PER_CPU(unsigned char, is_idle); | 59 | static DEFINE_PER_CPU(unsigned char, is_idle); |
| 63 | 60 | ||
