[PATCH] x86_64: Allocate PDAs in the local node

Patch uses a static PDA array early at boot and reallocates processor PDA
with node local memory when kmalloc is ready, just before pda_init.
The boot_cpu_pda is needed since the cpu_pda is used even before pda_init for
that cpu is called (to set the static per-cpu areas offset table etc)

Signed-off-by: Ravikiran Thirumalai <kiran@scalex86.org>
Signed-off-by: Shai Fultheim <shai@scalex86.org>
Signed-off-by: Andi Kleen <ak@suse.de>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

authored by

Ravikiran G Thirumalai and committed by
Linus Torvalds
365ba917 df79efde

+25 -3
+3
arch/x86_64/kernel/head64.c
··· 92 92 memcpy(init_level4_pgt, boot_level4_pgt, PTRS_PER_PGD*sizeof(pgd_t)); 93 93 asm volatile("movq %0,%%cr3" :: "r" (__pa_symbol(&init_level4_pgt))); 94 94 95 + for (i = 0; i < NR_CPUS; i++) 96 + cpu_pda(i) = &boot_cpu_pda[i]; 97 + 95 98 pda_init(0); 96 99 copy_bootdata(real_mode_data); 97 100 #ifdef CONFIG_SMP
+2 -1
arch/x86_64/kernel/setup64.c
··· 30 30 31 31 cpumask_t cpu_initialized __cpuinitdata = CPU_MASK_NONE; 32 32 33 - struct x8664_pda _cpu_pda[NR_CPUS] __cacheline_aligned; 33 + struct x8664_pda *_cpu_pda[NR_CPUS] __read_mostly; 34 + struct x8664_pda boot_cpu_pda[NR_CPUS] __cacheline_aligned; 34 35 35 36 struct desc_ptr idt_descr = { 256 * 16, (unsigned long) idt_table }; 36 37
+17
arch/x86_64/kernel/smpboot.c
··· 757 757 return -1; 758 758 } 759 759 760 + /* Allocate node local memory for AP pdas */ 761 + if (cpu_pda(cpu) == &boot_cpu_pda[cpu]) { 762 + struct x8664_pda *newpda, *pda; 763 + int node = cpu_to_node(cpu); 764 + pda = cpu_pda(cpu); 765 + newpda = kmalloc_node(sizeof (struct x8664_pda), GFP_ATOMIC, 766 + node); 767 + if (newpda) { 768 + memcpy(newpda, pda, sizeof (struct x8664_pda)); 769 + cpu_pda(cpu) = newpda; 770 + } else 771 + printk(KERN_ERR 772 + "Could not allocate node local PDA for CPU %d on node %d\n", 773 + cpu, node); 774 + } 775 + 776 + 760 777 c_idle.idle = get_idle_for_cpu(cpu); 761 778 762 779 if (c_idle.idle) {
+3 -2
include/asm-x86_64/pda.h
··· 27 27 unsigned apic_timer_irqs; 28 28 } ____cacheline_aligned_in_smp; 29 29 30 - extern struct x8664_pda _cpu_pda[]; 30 + extern struct x8664_pda *_cpu_pda[]; 31 + extern struct x8664_pda boot_cpu_pda[]; 31 32 32 - #define cpu_pda(i) (&_cpu_pda[i]) 33 + #define cpu_pda(i) (_cpu_pda[i]) 33 34 34 35 /* 35 36 * There is no fast way to get the base address of the PDA, all the accesses