aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Gerst <brgerst@gmail.com>2009-01-18 10:38:58 -0500
committerTejun Heo <tj@kernel.org>2009-01-18 10:38:58 -0500
commit26f80bd6a9ab17bc8a60b6092e7c0d05c5927ce5 (patch)
tree7456ba479397c986337b2bb9574a74710fddbdee
parent9eb912d1aa6b8106e06a73ea6702ec3dab0d6a1a (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>
-rw-r--r--arch/x86/include/asm/page_64.h4
-rw-r--r--arch/x86/include/asm/pda.h1
-rw-r--r--arch/x86/include/asm/processor.h3
-rw-r--r--arch/x86/kernel/asm-offsets_64.c1
-rw-r--r--arch/x86/kernel/cpu/common.c19
-rw-r--r--arch/x86/kernel/dumpstack_64.c33
-rw-r--r--arch/x86/kernel/entry_64.S6
-rw-r--r--arch/x86/kernel/setup_percpu.c4
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
380DECLARE_PER_CPU(struct orig_ist, orig_ist); 380DECLARE_PER_CPU(struct orig_ist, orig_ist);
381
382DECLARE_PER_CPU(char[IRQ_STACK_SIZE], irq_stack);
383DECLARE_PER_CPU(char *, irq_stack_ptr);
381#endif 384#endif
382 385
383extern void print_cpu_info(struct cpuinfo_x86 *); 386extern 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
882struct desc_ptr idt_descr = { 256 * 16 - 1, (unsigned long) idt_table }; 882struct desc_ptr idt_descr = { 256 * 16 - 1, (unsigned long) idt_table };
883 883
884static char boot_cpu_stack[IRQSTACKSIZE] __page_aligned_bss; 884DEFINE_PER_CPU_PAGE_ALIGNED(char[IRQ_STACK_SIZE], irq_stack);
885#ifdef CONFIG_SMP
886DEFINE_PER_CPU(char *, irq_stack_ptr); /* will be set during per cpu init */
887#else
888DEFINE_PER_CPU(char *, irq_stack_ptr) =
889 per_cpu_var(irq_stack) + IRQ_STACK_SIZE - 64;
890#endif
885 891
886void __cpuinit pda_init(int cpu) 892void __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)
3451: incl %gs:pda_irqcount 3451: 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)
130011: incl %gs:pda_irqcount 130011: 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 }