diff options
-rw-r--r-- | Documentation/x86_64/boot-options.txt | 3 | ||||
-rw-r--r-- | arch/x86_64/kernel/mpparse.c | 8 | ||||
-rw-r--r-- | arch/x86_64/kernel/smpboot.c | 39 | ||||
-rw-r--r-- | include/asm-x86_64/smp.h | 2 |
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 | |||
125 | NUMA | 128 | NUMA |
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 */ |
66 | unsigned int boot_cpu_id = -1U; | 66 | unsigned int boot_cpu_id = -1U; |
67 | /* Internal processor count */ | 67 | /* Internal processor count */ |
68 | static unsigned int num_processors = 0; | 68 | unsigned int num_processors __initdata = 0; |
69 | |||
70 | unsigned disabled_cpus __initdata; | ||
69 | 71 | ||
70 | /* Bitmask of physically existing CPUs */ | 72 | /* Bitmask of physically existing CPUs */ |
71 | physid_mask_t phys_cpu_present_map = PHYSID_MASK_NONE; | 73 | physid_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 | |||
884 | int 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 | ||
1181 | static __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 | ||
1156 | int __cpu_disable(void) | 1189 | int __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); | |||
81 | extern int __cpu_disable(void); | 81 | extern int __cpu_disable(void); |
82 | extern void __cpu_die(unsigned int cpu); | 82 | extern void __cpu_die(unsigned int cpu); |
83 | extern void prefill_possible_map(void); | 83 | extern void prefill_possible_map(void); |
84 | extern unsigned num_processors; | ||
85 | extern unsigned disabled_cpus; | ||
84 | 86 | ||
85 | #endif /* !ASSEMBLY */ | 87 | #endif /* !ASSEMBLY */ |
86 | 88 | ||