X86_64: Declare pda as per cpu data thereby moving it into the cpu area Declare the pda as a per cpu variable. This will have the effect of moving the pda data into the cpu area managed by cpu alloc. The boot_pdas are only needed in head64.c so move the declaration over there and make it static. Remove the code that allocates special pda data structures. Signed-off-by: Christoph Lameter --- arch/x86/kernel/head64.c | 6 ++++++ arch/x86/kernel/setup64.c | 12 ++++++++++-- arch/x86/kernel/smpboot_64.c | 16 ---------------- include/asm-x86/pda.h | 1 - 4 files changed, 16 insertions(+), 19 deletions(-) Index: linux-2.6/arch/x86/kernel/setup64.c =================================================================== --- linux-2.6.orig/arch/x86/kernel/setup64.c 2007-11-24 10:26:27.621850654 -0800 +++ linux-2.6/arch/x86/kernel/setup64.c 2007-11-24 23:23:30.116629291 -0800 @@ -30,7 +30,9 @@ cpumask_t cpu_initialized __cpuinitdata struct x8664_pda *_cpu_pda[NR_CPUS] __read_mostly; EXPORT_SYMBOL(_cpu_pda); -struct x8664_pda boot_cpu_pda[NR_CPUS] __cacheline_aligned; + +DEFINE_PER_CPU(struct x8664_pda, pda); +EXPORT_PER_CPU_SYMBOL(pda); struct desc_ptr idt_descr = { 256 * 16 - 1, (unsigned long) idt_table }; @@ -111,8 +113,13 @@ void __init setup_per_cpu_areas(void) panic("Cannot allocate cpu data for CPU %d\n", i); cpu_pda(i)->data_offset = ptr - __per_cpu_start; memcpy(ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start); + /* Relocate the pda */ + memcpy(&per_cpu(pda, i), cpu_pda(i), sizeof(struct x8664_pda)); + cpu_pda(i) = &per_cpu(pda, i); } -} + /* Fix up pda for this processor .... */ + pda_init(0); +} void pda_init(int cpu) { @@ -125,6 +132,7 @@ void pda_init(int cpu) wrmsrl(MSR_GS_BASE, pda); mb(); + printk(KERN_INFO "Processor #%d: GS for cpu variable access set to %p\n",cpu, pda); pda->cpunumber = cpu; pda->irqcount = -1; pda->kernelstack = Index: linux-2.6/arch/x86/kernel/smpboot_64.c =================================================================== --- linux-2.6.orig/arch/x86/kernel/smpboot_64.c 2007-11-21 09:45:30.833037940 -0800 +++ linux-2.6/arch/x86/kernel/smpboot_64.c 2007-11-24 23:21:43.777601109 -0800 @@ -556,22 +556,6 @@ static int __cpuinit do_boot_cpu(int cpu return -1; } - /* Allocate node local memory for AP pdas */ - if (cpu_pda(cpu) == &boot_cpu_pda[cpu]) { - struct x8664_pda *newpda, *pda; - int node = cpu_to_node(cpu); - pda = cpu_pda(cpu); - newpda = kmalloc_node(sizeof (struct x8664_pda), GFP_ATOMIC, - node); - if (newpda) { - memcpy(newpda, pda, sizeof (struct x8664_pda)); - cpu_pda(cpu) = newpda; - } else - printk(KERN_ERR - "Could not allocate node local PDA for CPU %d on node %d\n", - cpu, node); - } - alternatives_smp_switch(1); c_idle.idle = get_idle_for_cpu(cpu); Index: linux-2.6/arch/x86/kernel/head64.c =================================================================== --- linux-2.6.orig/arch/x86/kernel/head64.c 2007-11-21 09:45:30.845038067 -0800 +++ linux-2.6/arch/x86/kernel/head64.c 2007-11-24 23:21:43.781601356 -0800 @@ -20,6 +20,12 @@ #include #include +/* + * Only used before the per cpu areas are setup. The use for the non possible + * cpus continues after boot + */ +static struct x8664_pda boot_cpu_pda[NR_CPUS]; + static void __init zap_identity_mappings(void) { pgd_t *pgd = pgd_offset_k(0UL); Index: linux-2.6/include/asm-x86/pda.h =================================================================== --- linux-2.6.orig/include/asm-x86/pda.h 2007-11-21 09:45:30.849038061 -0800 +++ linux-2.6/include/asm-x86/pda.h 2007-11-24 23:21:43.781601356 -0800 @@ -39,7 +39,6 @@ struct x8664_pda { } ____cacheline_aligned_in_smp; extern struct x8664_pda *_cpu_pda[]; -extern struct x8664_pda boot_cpu_pda[]; #define cpu_pda(i) (_cpu_pda[i])