diff options
author | Brian Gerst <brgerst@gmail.com> | 2009-01-18 10:38:58 -0500 |
---|---|---|
committer | Tejun Heo <tj@kernel.org> | 2009-01-18 10:38:58 -0500 |
commit | 26f80bd6a9ab17bc8a60b6092e7c0d05c5927ce5 (patch) | |
tree | 7456ba479397c986337b2bb9574a74710fddbdee /arch | |
parent | 9eb912d1aa6b8106e06a73ea6702ec3dab0d6a1a (diff) |
x86-64: Convert irqstacks to per-cpu
Move the irqstackptr variable from the PDA to per-cpu. Make the
stacks themselves per-cpu, removing some specific allocation code.
Add a seperate flag (is_boot_cpu) to simplify the per-cpu boot
adjustments.
tj: * sprinkle some underbars around.
* irq_stack_ptr is not used till traps_init(), no reason to
initialize it early. On SMP, just leaving it NULL till proper
initialization in setup_per_cpu_areas() works. Dropped
is_boot_cpu and early irq_stack_ptr initialization.
* do DECLARE/DEFINE_PER_CPU(char[IRQ_STACK_SIZE], irq_stack)
instead of (char, irq_stack[IRQ_STACK_SIZE]).
Signed-off-by: Brian Gerst <brgerst@gmail.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/include/asm/page_64.h | 4 | ||||
-rw-r--r-- | arch/x86/include/asm/pda.h | 1 | ||||
-rw-r--r-- | arch/x86/include/asm/processor.h | 3 | ||||
-rw-r--r-- | arch/x86/kernel/asm-offsets_64.c | 1 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/common.c | 19 | ||||
-rw-r--r-- | arch/x86/kernel/dumpstack_64.c | 33 | ||||
-rw-r--r-- | arch/x86/kernel/entry_64.S | 6 | ||||
-rw-r--r-- | arch/x86/kernel/setup_percpu.c | 4 |
8 files changed, 35 insertions, 36 deletions
diff --git a/arch/x86/include/asm/page_64.h b/arch/x86/include/asm/page_64.h index 5ebca29f44f0..e27fdbe5f9e4 100644 --- a/arch/x86/include/asm/page_64.h +++ b/arch/x86/include/asm/page_64.h | |||
@@ -13,8 +13,8 @@ | |||
13 | #define DEBUG_STACK_ORDER (EXCEPTION_STACK_ORDER + 1) | 13 | #define DEBUG_STACK_ORDER (EXCEPTION_STACK_ORDER + 1) |
14 | #define DEBUG_STKSZ (PAGE_SIZE << DEBUG_STACK_ORDER) | 14 | #define DEBUG_STKSZ (PAGE_SIZE << DEBUG_STACK_ORDER) |
15 | 15 | ||
16 | #define IRQSTACK_ORDER 2 | 16 | #define IRQ_STACK_ORDER 2 |
17 | #define IRQSTACKSIZE (PAGE_SIZE << IRQSTACK_ORDER) | 17 | #define IRQ_STACK_SIZE (PAGE_SIZE << IRQ_STACK_ORDER) |
18 | 18 | ||
19 | #define STACKFAULT_STACK 1 | 19 | #define STACKFAULT_STACK 1 |
20 | #define DOUBLEFAULT_STACK 2 | 20 | #define DOUBLEFAULT_STACK 2 |
diff --git a/arch/x86/include/asm/pda.h b/arch/x86/include/asm/pda.h index 8ee835ed10e1..09965f7a2165 100644 --- a/arch/x86/include/asm/pda.h +++ b/arch/x86/include/asm/pda.h | |||
@@ -22,7 +22,6 @@ struct x8664_pda { | |||
22 | /* gcc-ABI: this canary MUST be at | 22 | /* gcc-ABI: this canary MUST be at |
23 | offset 40!!! */ | 23 | offset 40!!! */ |
24 | #endif | 24 | #endif |
25 | char *irqstackptr; | ||
26 | short nodenumber; /* number of current node (32k max) */ | 25 | short nodenumber; /* number of current node (32k max) */ |
27 | short in_bootmem; /* pda lives in bootmem */ | 26 | short in_bootmem; /* pda lives in bootmem */ |
28 | short isidle; | 27 | short isidle; |
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index 091cd8855f2e..f511246fa6cd 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h | |||
@@ -378,6 +378,9 @@ union thread_xstate { | |||
378 | 378 | ||
379 | #ifdef CONFIG_X86_64 | 379 | #ifdef CONFIG_X86_64 |
380 | DECLARE_PER_CPU(struct orig_ist, orig_ist); | 380 | DECLARE_PER_CPU(struct orig_ist, orig_ist); |
381 | |||
382 | DECLARE_PER_CPU(char[IRQ_STACK_SIZE], irq_stack); | ||
383 | DECLARE_PER_CPU(char *, irq_stack_ptr); | ||
381 | #endif | 384 | #endif |
382 | 385 | ||
383 | extern void print_cpu_info(struct cpuinfo_x86 *); | 386 | extern void print_cpu_info(struct cpuinfo_x86 *); |
diff --git a/arch/x86/kernel/asm-offsets_64.c b/arch/x86/kernel/asm-offsets_64.c index f4cc81bfbf89..5b821fbdaf7b 100644 --- a/arch/x86/kernel/asm-offsets_64.c +++ b/arch/x86/kernel/asm-offsets_64.c | |||
@@ -54,7 +54,6 @@ int main(void) | |||
54 | ENTRY(pcurrent); | 54 | ENTRY(pcurrent); |
55 | ENTRY(irqcount); | 55 | ENTRY(irqcount); |
56 | ENTRY(cpunumber); | 56 | ENTRY(cpunumber); |
57 | ENTRY(irqstackptr); | ||
58 | DEFINE(pda_size, sizeof(struct x8664_pda)); | 57 | DEFINE(pda_size, sizeof(struct x8664_pda)); |
59 | BLANK(); | 58 | BLANK(); |
60 | #undef ENTRY | 59 | #undef ENTRY |
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 3d0cc6f17116..496f0a01919b 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c | |||
@@ -881,7 +881,13 @@ __setup("clearcpuid=", setup_disablecpuid); | |||
881 | #ifdef CONFIG_X86_64 | 881 | #ifdef CONFIG_X86_64 |
882 | struct desc_ptr idt_descr = { 256 * 16 - 1, (unsigned long) idt_table }; | 882 | struct desc_ptr idt_descr = { 256 * 16 - 1, (unsigned long) idt_table }; |
883 | 883 | ||
884 | static char boot_cpu_stack[IRQSTACKSIZE] __page_aligned_bss; | 884 | DEFINE_PER_CPU_PAGE_ALIGNED(char[IRQ_STACK_SIZE], irq_stack); |
885 | #ifdef CONFIG_SMP | ||
886 | DEFINE_PER_CPU(char *, irq_stack_ptr); /* will be set during per cpu init */ | ||
887 | #else | ||
888 | DEFINE_PER_CPU(char *, irq_stack_ptr) = | ||
889 | per_cpu_var(irq_stack) + IRQ_STACK_SIZE - 64; | ||
890 | #endif | ||
885 | 891 | ||
886 | void __cpuinit pda_init(int cpu) | 892 | void __cpuinit pda_init(int cpu) |
887 | { | 893 | { |
@@ -901,18 +907,7 @@ void __cpuinit pda_init(int cpu) | |||
901 | if (cpu == 0) { | 907 | if (cpu == 0) { |
902 | /* others are initialized in smpboot.c */ | 908 | /* others are initialized in smpboot.c */ |
903 | pda->pcurrent = &init_task; | 909 | pda->pcurrent = &init_task; |
904 | pda->irqstackptr = boot_cpu_stack; | ||
905 | pda->irqstackptr += IRQSTACKSIZE - 64; | ||
906 | } else { | 910 | } else { |
907 | if (!pda->irqstackptr) { | ||
908 | pda->irqstackptr = (char *) | ||
909 | __get_free_pages(GFP_ATOMIC, IRQSTACK_ORDER); | ||
910 | if (!pda->irqstackptr) | ||
911 | panic("cannot allocate irqstack for cpu %d", | ||
912 | cpu); | ||
913 | pda->irqstackptr += IRQSTACKSIZE - 64; | ||
914 | } | ||
915 | |||
916 | if (pda->nodenumber == 0 && cpu_to_node(cpu) != NUMA_NO_NODE) | 911 | if (pda->nodenumber == 0 && cpu_to_node(cpu) != NUMA_NO_NODE) |
917 | pda->nodenumber = cpu_to_node(cpu); | 912 | pda->nodenumber = cpu_to_node(cpu); |
918 | } | 913 | } |
diff --git a/arch/x86/kernel/dumpstack_64.c b/arch/x86/kernel/dumpstack_64.c index c302d0707048..28e26a4315df 100644 --- a/arch/x86/kernel/dumpstack_64.c +++ b/arch/x86/kernel/dumpstack_64.c | |||
@@ -106,7 +106,8 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs, | |||
106 | const struct stacktrace_ops *ops, void *data) | 106 | const struct stacktrace_ops *ops, void *data) |
107 | { | 107 | { |
108 | const unsigned cpu = get_cpu(); | 108 | const unsigned cpu = get_cpu(); |
109 | unsigned long *irqstack_end = (unsigned long *)cpu_pda(cpu)->irqstackptr; | 109 | unsigned long *irq_stack_end = |
110 | (unsigned long *)per_cpu(irq_stack_ptr, cpu); | ||
110 | unsigned used = 0; | 111 | unsigned used = 0; |
111 | struct thread_info *tinfo; | 112 | struct thread_info *tinfo; |
112 | int graph = 0; | 113 | int graph = 0; |
@@ -160,23 +161,23 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs, | |||
160 | stack = (unsigned long *) estack_end[-2]; | 161 | stack = (unsigned long *) estack_end[-2]; |
161 | continue; | 162 | continue; |
162 | } | 163 | } |
163 | if (irqstack_end) { | 164 | if (irq_stack_end) { |
164 | unsigned long *irqstack; | 165 | unsigned long *irq_stack; |
165 | irqstack = irqstack_end - | 166 | irq_stack = irq_stack_end - |
166 | (IRQSTACKSIZE - 64) / sizeof(*irqstack); | 167 | (IRQ_STACK_SIZE - 64) / sizeof(*irq_stack); |
167 | 168 | ||
168 | if (stack >= irqstack && stack < irqstack_end) { | 169 | if (stack >= irq_stack && stack < irq_stack_end) { |
169 | if (ops->stack(data, "IRQ") < 0) | 170 | if (ops->stack(data, "IRQ") < 0) |
170 | break; | 171 | break; |
171 | bp = print_context_stack(tinfo, stack, bp, | 172 | bp = print_context_stack(tinfo, stack, bp, |
172 | ops, data, irqstack_end, &graph); | 173 | ops, data, irq_stack_end, &graph); |
173 | /* | 174 | /* |
174 | * We link to the next stack (which would be | 175 | * We link to the next stack (which would be |
175 | * the process stack normally) the last | 176 | * the process stack normally) the last |
176 | * pointer (index -1 to end) in the IRQ stack: | 177 | * pointer (index -1 to end) in the IRQ stack: |
177 | */ | 178 | */ |
178 | stack = (unsigned long *) (irqstack_end[-1]); | 179 | stack = (unsigned long *) (irq_stack_end[-1]); |
179 | irqstack_end = NULL; | 180 | irq_stack_end = NULL; |
180 | ops->stack(data, "EOI"); | 181 | ops->stack(data, "EOI"); |
181 | continue; | 182 | continue; |
182 | } | 183 | } |
@@ -199,10 +200,10 @@ show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs, | |||
199 | unsigned long *stack; | 200 | unsigned long *stack; |
200 | int i; | 201 | int i; |
201 | const int cpu = smp_processor_id(); | 202 | const int cpu = smp_processor_id(); |
202 | unsigned long *irqstack_end = | 203 | unsigned long *irq_stack_end = |
203 | (unsigned long *) (cpu_pda(cpu)->irqstackptr); | 204 | (unsigned long *)(per_cpu(irq_stack_ptr, cpu)); |
204 | unsigned long *irqstack = | 205 | unsigned long *irq_stack = |
205 | (unsigned long *) (cpu_pda(cpu)->irqstackptr - IRQSTACKSIZE); | 206 | (unsigned long *)(per_cpu(irq_stack_ptr, cpu) - IRQ_STACK_SIZE); |
206 | 207 | ||
207 | /* | 208 | /* |
208 | * debugging aid: "show_stack(NULL, NULL);" prints the | 209 | * debugging aid: "show_stack(NULL, NULL);" prints the |
@@ -218,9 +219,9 @@ show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs, | |||
218 | 219 | ||
219 | stack = sp; | 220 | stack = sp; |
220 | for (i = 0; i < kstack_depth_to_print; i++) { | 221 | for (i = 0; i < kstack_depth_to_print; i++) { |
221 | if (stack >= irqstack && stack <= irqstack_end) { | 222 | if (stack >= irq_stack && stack <= irq_stack_end) { |
222 | if (stack == irqstack_end) { | 223 | if (stack == irq_stack_end) { |
223 | stack = (unsigned long *) (irqstack_end[-1]); | 224 | stack = (unsigned long *) (irq_stack_end[-1]); |
224 | printk(" <EOI> "); | 225 | printk(" <EOI> "); |
225 | } | 226 | } |
226 | } else { | 227 | } else { |
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index 4833f3a19650..d22677a66438 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S | |||
@@ -345,7 +345,7 @@ ENTRY(save_args) | |||
345 | 1: incl %gs:pda_irqcount | 345 | 1: incl %gs:pda_irqcount |
346 | jne 2f | 346 | jne 2f |
347 | popq_cfi %rax /* move return address... */ | 347 | popq_cfi %rax /* move return address... */ |
348 | mov %gs:pda_irqstackptr,%rsp | 348 | mov PER_CPU_VAR(irq_stack_ptr),%rsp |
349 | EMPTY_FRAME 0 | 349 | EMPTY_FRAME 0 |
350 | pushq_cfi %rax /* ... to the new stack */ | 350 | pushq_cfi %rax /* ... to the new stack */ |
351 | /* | 351 | /* |
@@ -1261,7 +1261,7 @@ ENTRY(call_softirq) | |||
1261 | mov %rsp,%rbp | 1261 | mov %rsp,%rbp |
1262 | CFI_DEF_CFA_REGISTER rbp | 1262 | CFI_DEF_CFA_REGISTER rbp |
1263 | incl %gs:pda_irqcount | 1263 | incl %gs:pda_irqcount |
1264 | cmove %gs:pda_irqstackptr,%rsp | 1264 | cmove PER_CPU_VAR(irq_stack_ptr),%rsp |
1265 | push %rbp # backlink for old unwinder | 1265 | push %rbp # backlink for old unwinder |
1266 | call __do_softirq | 1266 | call __do_softirq |
1267 | leaveq | 1267 | leaveq |
@@ -1300,7 +1300,7 @@ ENTRY(xen_do_hypervisor_callback) # do_hypervisor_callback(struct *pt_regs) | |||
1300 | 11: incl %gs:pda_irqcount | 1300 | 11: incl %gs:pda_irqcount |
1301 | movq %rsp,%rbp | 1301 | movq %rsp,%rbp |
1302 | CFI_DEF_CFA_REGISTER rbp | 1302 | CFI_DEF_CFA_REGISTER rbp |
1303 | cmovzq %gs:pda_irqstackptr,%rsp | 1303 | cmovzq PER_CPU_VAR(irq_stack_ptr),%rsp |
1304 | pushq %rbp # backlink for old unwinder | 1304 | pushq %rbp # backlink for old unwinder |
1305 | call xen_evtchn_do_upcall | 1305 | call xen_evtchn_do_upcall |
1306 | popq %rsp | 1306 | popq %rsp |
diff --git a/arch/x86/kernel/setup_percpu.c b/arch/x86/kernel/setup_percpu.c index b5c35af2011d..8b53ef83c611 100644 --- a/arch/x86/kernel/setup_percpu.c +++ b/arch/x86/kernel/setup_percpu.c | |||
@@ -192,7 +192,10 @@ void __init setup_per_cpu_areas(void) | |||
192 | 192 | ||
193 | memcpy(ptr, __per_cpu_load, __per_cpu_end - __per_cpu_start); | 193 | memcpy(ptr, __per_cpu_load, __per_cpu_end - __per_cpu_start); |
194 | per_cpu_offset(cpu) = ptr - __per_cpu_start; | 194 | per_cpu_offset(cpu) = ptr - __per_cpu_start; |
195 | per_cpu(this_cpu_off, cpu) = per_cpu_offset(cpu); | ||
195 | #ifdef CONFIG_X86_64 | 196 | #ifdef CONFIG_X86_64 |
197 | per_cpu(irq_stack_ptr, cpu) = | ||
198 | (char *)per_cpu(irq_stack, cpu) + IRQ_STACK_SIZE - 64; | ||
196 | /* | 199 | /* |
197 | * CPU0 modified pda in the init data area, reload pda | 200 | * CPU0 modified pda in the init data area, reload pda |
198 | * offset for CPU0 and clear the area for others. | 201 | * offset for CPU0 and clear the area for others. |
@@ -202,7 +205,6 @@ void __init setup_per_cpu_areas(void) | |||
202 | else | 205 | else |
203 | memset(cpu_pda(cpu), 0, sizeof(*cpu_pda(cpu))); | 206 | memset(cpu_pda(cpu), 0, sizeof(*cpu_pda(cpu))); |
204 | #endif | 207 | #endif |
205 | per_cpu(this_cpu_off, cpu) = per_cpu_offset(cpu); | ||
206 | 208 | ||
207 | DBG("PERCPU: cpu %4d %p\n", cpu, ptr); | 209 | DBG("PERCPU: cpu %4d %p\n", cpu, ptr); |
208 | } | 210 | } |