aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/smpboot.c
diff options
context:
space:
mode:
authorMike Travis <travis@sgi.com>2008-05-12 15:21:13 -0400
committerIngo Molnar <mingo@elte.hu>2008-07-08 05:31:25 -0400
commit3461b0af025251bbc6b3d56c821c6ac2de6f7209 (patch)
tree5350ad712311a69b4b59deec1ec60d8573db8817 /arch/x86/kernel/smpboot.c
parent9f248bde9d47cc177011198c9a15fb339b9f3215 (diff)
x86: remove static boot_cpu_pda array v2
* Remove the boot_cpu_pda array and pointer table from the data section. Allocate the pointer table and array during init. do_boot_cpu() will reallocate the pda in node local memory and if the cpu is being brought up before the bootmem array is released (after_bootmem = 0), then it will free the initial pda. This will happen for all cpus present at system startup. This removes 512k + 32k bytes from the data section. For inclusion into sched-devel/latest tree. Based on: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git + sched-devel/latest .../mingo/linux-2.6-sched-devel.git Signed-off-by: Mike Travis <travis@sgi.com> Signed-off-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'arch/x86/kernel/smpboot.c')
-rw-r--r--arch/x86/kernel/smpboot.c59
1 files changed, 46 insertions, 13 deletions
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index 036604d3daed..bf0833487455 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -816,6 +816,43 @@ static void __cpuinit do_fork_idle(struct work_struct *work)
816 complete(&c_idle->done); 816 complete(&c_idle->done);
817} 817}
818 818
819/*
820 * Allocate node local memory for the AP pda.
821 *
822 * Must be called after the _cpu_pda pointer table is initialized.
823 */
824static int __cpuinit get_local_pda(int cpu)
825{
826 struct x8664_pda *oldpda, *newpda;
827 unsigned long size = sizeof(struct x8664_pda);
828 int node = cpu_to_node(cpu);
829
830 if (cpu_pda(cpu) && !cpu_pda(cpu)->in_bootmem)
831 return 0;
832
833 oldpda = cpu_pda(cpu);
834 newpda = kmalloc_node(size, GFP_ATOMIC, node);
835 if (!newpda) {
836 printk(KERN_ERR "Could not allocate node local PDA "
837 "for CPU %d on node %d\n", cpu, node);
838
839 if (oldpda)
840 return 0; /* have a usable pda */
841 else
842 return -1;
843 }
844
845 if (oldpda) {
846 memcpy(newpda, oldpda, size);
847 if (!after_bootmem)
848 free_bootmem((unsigned long)oldpda, size);
849 }
850
851 newpda->in_bootmem = 0;
852 cpu_pda(cpu) = newpda;
853 return 0;
854}
855
819static int __cpuinit do_boot_cpu(int apicid, int cpu) 856static int __cpuinit do_boot_cpu(int apicid, int cpu)
820/* 857/*
821 * NOTE - on most systems this is a PHYSICAL apic ID, but on multiquad 858 * NOTE - on most systems this is a PHYSICAL apic ID, but on multiquad
@@ -841,19 +878,11 @@ static int __cpuinit do_boot_cpu(int apicid, int cpu)
841 } 878 }
842 879
843 /* Allocate node local memory for AP pdas */ 880 /* Allocate node local memory for AP pdas */
844 if (cpu_pda(cpu) == &boot_cpu_pda[cpu]) { 881 if (cpu > 0) {
845 struct x8664_pda *newpda, *pda; 882 boot_error = get_local_pda(cpu);
846 int node = cpu_to_node(cpu); 883 if (boot_error)
847 pda = cpu_pda(cpu); 884 goto restore_state;
848 newpda = kmalloc_node(sizeof(struct x8664_pda), GFP_ATOMIC, 885 /* if can't get pda memory, can't start cpu */
849 node);
850 if (newpda) {
851 memcpy(newpda, pda, sizeof(struct x8664_pda));
852 cpu_pda(cpu) = newpda;
853 } else
854 printk(KERN_ERR
855 "Could not allocate node local PDA for CPU %d on node %d\n",
856 cpu, node);
857 } 886 }
858#endif 887#endif
859 888
@@ -972,6 +1001,8 @@ do_rest:
972 } 1001 }
973 } 1002 }
974 1003
1004restore_state:
1005
975 if (boot_error) { 1006 if (boot_error) {
976 /* Try to put things back the way they were before ... */ 1007 /* Try to put things back the way they were before ... */
977 unmap_cpu_to_logical_apicid(cpu); 1008 unmap_cpu_to_logical_apicid(cpu);
@@ -1347,6 +1378,8 @@ __init void prefill_possible_map(void)
1347 1378
1348 for (i = 0; i < possible; i++) 1379 for (i = 0; i < possible; i++)
1349 cpu_set(i, cpu_possible_map); 1380 cpu_set(i, cpu_possible_map);
1381
1382 nr_cpu_ids = possible;
1350} 1383}
1351 1384
1352static void __ref remove_cpu_from_maps(int cpu) 1385static void __ref remove_cpu_from_maps(int cpu)