diff options
author | Mike Travis <travis@sgi.com> | 2008-12-17 18:21:39 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-12-18 06:08:05 -0500 |
commit | 3b11ce7f542e415c90267b4482d4611410b468e6 (patch) | |
tree | 26366b9f25af830b71c78504bbadd94896a8b82a | |
parent | a775a38b1353161a6d7af86b667d6523c12c1a37 (diff) |
x86: use possible_cpus=NUM to extend the possible cpus allowed
Impact: add new boot parameter
Use possible_cpus=NUM kernel parameter to extend the number of possible
cpus.
The ability to HOTPLUG ON cpus that are "possible" but not "present" is
dealt with in a later patch.
Signed-off-by: Mike Travis <travis@sgi.com>
-rw-r--r-- | Documentation/cpu-hotplug.txt | 17 | ||||
-rw-r--r-- | arch/x86/kernel/apic.c | 20 | ||||
-rw-r--r-- | arch/x86/kernel/smpboot.c | 25 |
3 files changed, 42 insertions, 20 deletions
diff --git a/Documentation/cpu-hotplug.txt b/Documentation/cpu-hotplug.txt index 94bbc27ddd4f..9d620c153b04 100644 --- a/Documentation/cpu-hotplug.txt +++ b/Documentation/cpu-hotplug.txt | |||
@@ -50,16 +50,17 @@ additional_cpus=n (*) Use this to limit hotpluggable cpus. This option sets | |||
50 | cpu_possible_map = cpu_present_map + additional_cpus | 50 | cpu_possible_map = cpu_present_map + additional_cpus |
51 | 51 | ||
52 | (*) Option valid only for following architectures | 52 | (*) Option valid only for following architectures |
53 | - x86_64, ia64 | 53 | - ia64 |
54 | 54 | ||
55 | ia64 and x86_64 use the number of disabled local apics in ACPI tables MADT | 55 | ia64 uses the number of disabled local apics in ACPI tables MADT to |
56 | to determine the number of potentially hot-pluggable cpus. The implementation | 56 | determine the number of potentially hot-pluggable cpus. The implementation |
57 | should only rely on this to count the # of cpus, but *MUST* not rely on the | 57 | should only rely on this to count the # of cpus, but *MUST* not rely |
58 | apicid values in those tables for disabled apics. In the event BIOS doesn't | 58 | on the apicid values in those tables for disabled apics. In the event |
59 | mark such hot-pluggable cpus as disabled entries, one could use this | 59 | BIOS doesn't mark such hot-pluggable cpus as disabled entries, one could |
60 | parameter "additional_cpus=x" to represent those cpus in the cpu_possible_map. | 60 | use this parameter "additional_cpus=x" to represent those cpus in the |
61 | cpu_possible_map. | ||
61 | 62 | ||
62 | possible_cpus=n [s390 only] use this to set hotpluggable cpus. | 63 | possible_cpus=n [s390,x86_64] use this to set hotpluggable cpus. |
63 | This option sets possible_cpus bits in | 64 | This option sets possible_cpus bits in |
64 | cpu_possible_map. Thus keeping the numbers of bits set | 65 | cpu_possible_map. Thus keeping the numbers of bits set |
65 | constant even if the machine gets rebooted. | 66 | constant even if the machine gets rebooted. |
diff --git a/arch/x86/kernel/apic.c b/arch/x86/kernel/apic.c index 93cf2d13f335..f7a32a3beb2f 100644 --- a/arch/x86/kernel/apic.c +++ b/arch/x86/kernel/apic.c | |||
@@ -1819,28 +1819,32 @@ void disconnect_bsp_APIC(int virt_wire_setup) | |||
1819 | void __cpuinit generic_processor_info(int apicid, int version) | 1819 | void __cpuinit generic_processor_info(int apicid, int version) |
1820 | { | 1820 | { |
1821 | int cpu; | 1821 | int cpu; |
1822 | cpumask_t tmp_map; | ||
1823 | 1822 | ||
1824 | /* | 1823 | /* |
1825 | * Validate version | 1824 | * Validate version |
1826 | */ | 1825 | */ |
1827 | if (version == 0x0) { | 1826 | if (version == 0x0) { |
1828 | pr_warning("BIOS bug, APIC version is 0 for CPU#%d! " | 1827 | pr_warning("BIOS bug, APIC version is 0 for CPU#%d! " |
1829 | "fixing up to 0x10. (tell your hw vendor)\n", | 1828 | "fixing up to 0x10. (tell your hw vendor)\n", |
1830 | version); | 1829 | version); |
1831 | version = 0x10; | 1830 | version = 0x10; |
1832 | } | 1831 | } |
1833 | apic_version[apicid] = version; | 1832 | apic_version[apicid] = version; |
1834 | 1833 | ||
1835 | if (num_processors >= NR_CPUS) { | 1834 | if (num_processors >= nr_cpu_ids) { |
1836 | pr_warning("WARNING: NR_CPUS limit of %i reached." | 1835 | int max = nr_cpu_ids; |
1837 | " Processor ignored.\n", NR_CPUS); | 1836 | int thiscpu = max + disabled_cpus; |
1837 | |||
1838 | pr_warning( | ||
1839 | "ACPI: NR_CPUS/possible_cpus limit of %i reached." | ||
1840 | " Processor %d/0x%x ignored.\n", max, thiscpu, apicid); | ||
1841 | |||
1842 | disabled_cpus++; | ||
1838 | return; | 1843 | return; |
1839 | } | 1844 | } |
1840 | 1845 | ||
1841 | num_processors++; | 1846 | num_processors++; |
1842 | cpus_complement(tmp_map, cpu_present_map); | 1847 | cpu = cpumask_next_zero(-1, cpu_present_mask); |
1843 | cpu = first_cpu(tmp_map); | ||
1844 | 1848 | ||
1845 | physid_set(apicid, phys_cpu_present_map); | 1849 | physid_set(apicid, phys_cpu_present_map); |
1846 | if (apicid == boot_cpu_physical_apicid) { | 1850 | if (apicid == boot_cpu_physical_apicid) { |
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index be9466788043..1a9941b11150 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c | |||
@@ -1252,6 +1252,15 @@ void __init native_smp_cpus_done(unsigned int max_cpus) | |||
1252 | check_nmi_watchdog(); | 1252 | check_nmi_watchdog(); |
1253 | } | 1253 | } |
1254 | 1254 | ||
1255 | static int __initdata setup_possible_cpus = -1; | ||
1256 | static int __init _setup_possible_cpus(char *str) | ||
1257 | { | ||
1258 | get_option(&str, &setup_possible_cpus); | ||
1259 | return 0; | ||
1260 | } | ||
1261 | early_param("possible_cpus", _setup_possible_cpus); | ||
1262 | |||
1263 | |||
1255 | /* | 1264 | /* |
1256 | * cpu_possible_map should be static, it cannot change as cpu's | 1265 | * cpu_possible_map should be static, it cannot change as cpu's |
1257 | * are onlined, or offlined. The reason is per-cpu data-structures | 1266 | * are onlined, or offlined. The reason is per-cpu data-structures |
@@ -1264,7 +1273,7 @@ void __init native_smp_cpus_done(unsigned int max_cpus) | |||
1264 | * | 1273 | * |
1265 | * Three ways to find out the number of additional hotplug CPUs: | 1274 | * Three ways to find out the number of additional hotplug CPUs: |
1266 | * - If the BIOS specified disabled CPUs in ACPI/mptables use that. | 1275 | * - If the BIOS specified disabled CPUs in ACPI/mptables use that. |
1267 | * - The user can overwrite it with additional_cpus=NUM | 1276 | * - The user can overwrite it with possible_cpus=NUM |
1268 | * - Otherwise don't reserve additional CPUs. | 1277 | * - Otherwise don't reserve additional CPUs. |
1269 | * We do this because additional CPUs waste a lot of memory. | 1278 | * We do this because additional CPUs waste a lot of memory. |
1270 | * -AK | 1279 | * -AK |
@@ -1277,9 +1286,17 @@ __init void prefill_possible_map(void) | |||
1277 | if (!num_processors) | 1286 | if (!num_processors) |
1278 | num_processors = 1; | 1287 | num_processors = 1; |
1279 | 1288 | ||
1280 | possible = num_processors + disabled_cpus; | 1289 | if (setup_possible_cpus == -1) |
1281 | if (possible > NR_CPUS) | 1290 | possible = num_processors + disabled_cpus; |
1282 | possible = NR_CPUS; | 1291 | else |
1292 | possible = setup_possible_cpus; | ||
1293 | |||
1294 | if (possible > CONFIG_NR_CPUS) { | ||
1295 | printk(KERN_WARNING | ||
1296 | "%d Processors exceeds NR_CPUS limit of %d\n", | ||
1297 | possible, CONFIG_NR_CPUS); | ||
1298 | possible = CONFIG_NR_CPUS; | ||
1299 | } | ||
1283 | 1300 | ||
1284 | printk(KERN_INFO "SMP: Allowing %d CPUs, %d hotplug CPUs\n", | 1301 | printk(KERN_INFO "SMP: Allowing %d CPUs, %d hotplug CPUs\n", |
1285 | possible, max_t(int, possible - num_processors, 0)); | 1302 | possible, max_t(int, possible - num_processors, 0)); |