aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/x86_64/boot-options.txt3
-rw-r--r--arch/x86_64/kernel/mpparse.c8
-rw-r--r--arch/x86_64/kernel/smpboot.c39
-rw-r--r--include/asm-x86_64/smp.h2
4 files changed, 47 insertions, 5 deletions
diff --git a/Documentation/x86_64/boot-options.txt b/Documentation/x86_64/boot-options.txt
index ffe1c062088b..a83139692cdf 100644
--- a/Documentation/x86_64/boot-options.txt
+++ b/Documentation/x86_64/boot-options.txt
@@ -122,6 +122,9 @@ SMP
122 122
123 cpumask=MASK only use cpus with bits set in mask 123 cpumask=MASK only use cpus with bits set in mask
124 124
125 additional_cpus=NUM Allow NUM more CPUs for hotplug
126 (defaults are specified by the BIOS or half the available CPUs)
127
125NUMA 128NUMA
126 129
127 numa=off Only set up a single NUMA node spanning all memory. 130 numa=off Only set up a single NUMA node spanning all memory.
diff --git a/arch/x86_64/kernel/mpparse.c b/arch/x86_64/kernel/mpparse.c
index 4a581d1cefbd..1d61f10a92c6 100644
--- a/arch/x86_64/kernel/mpparse.c
+++ b/arch/x86_64/kernel/mpparse.c
@@ -65,7 +65,9 @@ unsigned long mp_lapic_addr = 0;
65/* Processor that is doing the boot up */ 65/* Processor that is doing the boot up */
66unsigned int boot_cpu_id = -1U; 66unsigned int boot_cpu_id = -1U;
67/* Internal processor count */ 67/* Internal processor count */
68static unsigned int num_processors = 0; 68unsigned int num_processors __initdata = 0;
69
70unsigned disabled_cpus __initdata;
69 71
70/* Bitmask of physically existing CPUs */ 72/* Bitmask of physically existing CPUs */
71physid_mask_t phys_cpu_present_map = PHYSID_MASK_NONE; 73physid_mask_t phys_cpu_present_map = PHYSID_MASK_NONE;
@@ -109,8 +111,10 @@ static void __init MP_processor_info (struct mpc_config_processor *m)
109 int ver, cpu; 111 int ver, cpu;
110 static int found_bsp=0; 112 static int found_bsp=0;
111 113
112 if (!(m->mpc_cpuflag & CPU_ENABLED)) 114 if (!(m->mpc_cpuflag & CPU_ENABLED)) {
115 disabled_cpus++;
113 return; 116 return;
117 }
114 118
115 printk(KERN_INFO "Processor #%d %d:%d APIC version %d\n", 119 printk(KERN_INFO "Processor #%d %d:%d APIC version %d\n",
116 m->mpc_apicid, 120 m->mpc_apicid,
diff --git a/arch/x86_64/kernel/smpboot.c b/arch/x86_64/kernel/smpboot.c
index 3393fc08823b..f74319a80659 100644
--- a/arch/x86_64/kernel/smpboot.c
+++ b/arch/x86_64/kernel/smpboot.c
@@ -880,6 +880,9 @@ static __init void disable_smp(void)
880} 880}
881 881
882#ifdef CONFIG_HOTPLUG_CPU 882#ifdef CONFIG_HOTPLUG_CPU
883
884int additional_cpus __initdata = -1;
885
883/* 886/*
884 * cpu_possible_map should be static, it cannot change as cpu's 887 * cpu_possible_map should be static, it cannot change as cpu's
885 * are onlined, or offlined. The reason is per-cpu data-structures 888 * are onlined, or offlined. The reason is per-cpu data-structures
@@ -888,14 +891,38 @@ static __init void disable_smp(void)
888 * cpu_present_map on the other hand can change dynamically. 891 * cpu_present_map on the other hand can change dynamically.
889 * In case when cpu_hotplug is not compiled, then we resort to current 892 * In case when cpu_hotplug is not compiled, then we resort to current
890 * behaviour, which is cpu_possible == cpu_present. 893 * behaviour, which is cpu_possible == cpu_present.
891 * If cpu-hotplug is supported, then we need to preallocate for all
892 * those NR_CPUS, hence cpu_possible_map represents entire NR_CPUS range.
893 * - Ashok Raj 894 * - Ashok Raj
895 *
896 * Three ways to find out the number of additional hotplug CPUs:
897 * - If the BIOS specified disabled CPUs in ACPI/mptables use that.
898 * - otherwise use half of the available CPUs or 2, whatever is more.
899 * - The user can overwrite it with additional_cpus=NUM
900 * We do this because additional CPUs waste a lot of memory.
901 * -AK
894 */ 902 */
895__init void prefill_possible_map(void) 903__init void prefill_possible_map(void)
896{ 904{
897 int i; 905 int i;
898 for (i = 0; i < NR_CPUS; i++) 906 int possible;
907
908 if (additional_cpus == -1) {
909 if (disabled_cpus > 0) {
910 additional_cpus = disabled_cpus;
911 } else {
912 additional_cpus = num_processors / 2;
913 if (additional_cpus == 0)
914 additional_cpus = 2;
915 }
916 }
917 possible = num_processors + additional_cpus;
918 if (possible > NR_CPUS)
919 possible = NR_CPUS;
920
921 printk(KERN_INFO "SMP: Allowing %d CPUs, %d hotplug CPUs\n",
922 possible,
923 max_t(int, possible - num_processors, 0));
924
925 for (i = 0; i < possible; i++)
899 cpu_set(i, cpu_possible_map); 926 cpu_set(i, cpu_possible_map);
900} 927}
901#endif 928#endif
@@ -1151,6 +1178,12 @@ void __cpu_die(unsigned int cpu)
1151 printk(KERN_ERR "CPU %u didn't die...\n", cpu); 1178 printk(KERN_ERR "CPU %u didn't die...\n", cpu);
1152} 1179}
1153 1180
1181static __init int setup_additional_cpus(char *s)
1182{
1183 return get_option(&s, &additional_cpus);
1184}
1185__setup("additional_cpus=", setup_additional_cpus);
1186
1154#else /* ... !CONFIG_HOTPLUG_CPU */ 1187#else /* ... !CONFIG_HOTPLUG_CPU */
1155 1188
1156int __cpu_disable(void) 1189int __cpu_disable(void)
diff --git a/include/asm-x86_64/smp.h b/include/asm-x86_64/smp.h
index 592161e979e5..cf8f969f9020 100644
--- a/include/asm-x86_64/smp.h
+++ b/include/asm-x86_64/smp.h
@@ -81,6 +81,8 @@ extern int safe_smp_processor_id(void);
81extern int __cpu_disable(void); 81extern int __cpu_disable(void);
82extern void __cpu_die(unsigned int cpu); 82extern void __cpu_die(unsigned int cpu);
83extern void prefill_possible_map(void); 83extern void prefill_possible_map(void);
84extern unsigned num_processors;
85extern unsigned disabled_cpus;
84 86
85#endif /* !ASSEMBLY */ 87#endif /* !ASSEMBLY */
86 88