From: Anton Blanchard Now we set up cpu_possible_map early we can dynamically allocate the emergency stacks. Previously we would allocate NR_CPUS * PAGE_SIZE, potentially wasting quite a lot of memory. Clean a comment up in irqstack_early_init and use unsigned int for cpu ids while in the area. Signed-off-by: Anton Blanchard Signed-off-by: Andrew Morton --- 25-akpm/arch/ppc64/kernel/pacaData.c | 8 -------- 25-akpm/arch/ppc64/kernel/setup.c | 26 ++++++++++++++++++++++++-- 2 files changed, 24 insertions(+), 10 deletions(-) diff -puN arch/ppc64/kernel/pacaData.c~ppc64-dynamically-allocate-emergency-stacks arch/ppc64/kernel/pacaData.c --- 25/arch/ppc64/kernel/pacaData.c~ppc64-dynamically-allocate-emergency-stacks 2004-09-02 15:55:38.842925696 -0700 +++ 25-akpm/arch/ppc64/kernel/pacaData.c 2004-09-02 15:55:38.847924936 -0700 @@ -27,13 +27,6 @@ struct systemcfg *systemcfg; * field correctly */ extern unsigned long __toc_start; -/* Stack space used when we detect a bad kernel stack pointer, and - * early in SMP boots before relocation is enabled. - * - * ABI requires stack to be 128-byte aligned - */ -char emergency_stack[PAGE_SIZE * NR_CPUS] __attribute__((aligned(128))); - /* The Paca is an array with one entry per processor. Each contains an * ItLpPaca, which contains the information shared between the * hypervisor and Linux. Each also contains an ItLpRegSave area which @@ -55,7 +48,6 @@ char emergency_stack[PAGE_SIZE * NR_CPUS .kernel_toc = (unsigned long)(&__toc_start) + 0x8000UL, \ .stab_real = (asrr), /* Real pointer to segment table */ \ .stab_addr = (asrv), /* Virt pointer to segment table */ \ - .emergency_sp = &emergency_stack[((number)+1) * PAGE_SIZE], \ .cpu_start = (start), /* Processor start */ \ .lppaca = { \ .xDesc = 0xd397d781, /* "LpPa" */ \ diff -puN arch/ppc64/kernel/setup.c~ppc64-dynamically-allocate-emergency-stacks arch/ppc64/kernel/setup.c --- 25/arch/ppc64/kernel/setup.c~ppc64-dynamically-allocate-emergency-stacks 2004-09-02 15:55:38.843925544 -0700 +++ 25-akpm/arch/ppc64/kernel/setup.c 2004-09-02 15:55:38.848924784 -0700 @@ -701,9 +701,12 @@ extern void (*calibrate_delay)(void); #ifdef CONFIG_IRQSTACKS static void __init irqstack_early_init(void) { - int i; + unsigned int i; - /* interrupt stacks must be under 256MB, we cannot afford to take SLB misses on them */ + /* + * interrupt stacks must be under 256MB, we cannot afford to take + * SLB misses on them. + */ for_each_cpu(i) { softirq_ctx[i] = (struct thread_info *)__va(lmb_alloc_base(THREAD_SIZE, THREAD_SIZE, 0x10000000)); @@ -716,6 +719,24 @@ static void __init irqstack_early_init(v #endif /* + * Stack space used when we detect a bad kernel stack pointer, and + * early in SMP boots before relocation is enabled. + */ +static void __init emergency_stack_init(void) +{ + unsigned int i; + + /* + * Emergency stacks must be under 256MB, we cannot afford to take + * SLB misses on them. The ABI also requires them to be 128-byte + * aligned. + */ + for_each_cpu(i) + paca[i].emergency_sp = __va(lmb_alloc_base(PAGE_SIZE, 128, + 0x10000000)) + PAGE_SIZE; +} + +/* * Called into from start_kernel, after lock_kernel has been called. * Initializes bootmem, which is unsed to manage page allocation until * mem_init is called. @@ -761,6 +782,7 @@ void __init setup_arch(char **cmdline_p) *cmdline_p = cmd_line; irqstack_early_init(); + emergency_stack_init(); /* set up the bootmem stuff with available memory */ do_init_bootmem(); _