Commit 3b11ce7f542e415c90267b4482d4611410b468e6
Committed by
Ingo Molnar
1 parent
a775a38b13
Exists in
master
and in
7 other branches
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>
Showing 3 changed files with 42 additions and 20 deletions Side-by-side Diff
Documentation/cpu-hotplug.txt
... | ... | @@ -50,16 +50,17 @@ |
50 | 50 | cpu_possible_map = cpu_present_map + additional_cpus |
51 | 51 | |
52 | 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 | |
56 | -to 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 | |
58 | -apicid values in those tables for disabled apics. In the event BIOS doesn't | |
59 | -mark such hot-pluggable cpus as disabled entries, one could use this | |
60 | -parameter "additional_cpus=x" to represent those cpus in the cpu_possible_map. | |
55 | +ia64 uses the number of disabled local apics in ACPI tables MADT to | |
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 | |
58 | +on the apicid values in those tables for disabled apics. In the event | |
59 | +BIOS doesn't mark such hot-pluggable cpus as disabled entries, one could | |
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 | 64 | This option sets possible_cpus bits in |
64 | 65 | cpu_possible_map. Thus keeping the numbers of bits set |
65 | 66 | constant even if the machine gets rebooted. |
arch/x86/kernel/apic.c
... | ... | @@ -1819,28 +1819,32 @@ |
1819 | 1819 | void __cpuinit generic_processor_info(int apicid, int version) |
1820 | 1820 | { |
1821 | 1821 | int cpu; |
1822 | - cpumask_t tmp_map; | |
1823 | 1822 | |
1824 | 1823 | /* |
1825 | 1824 | * Validate version |
1826 | 1825 | */ |
1827 | 1826 | if (version == 0x0) { |
1828 | 1827 | pr_warning("BIOS bug, APIC version is 0 for CPU#%d! " |
1829 | - "fixing up to 0x10. (tell your hw vendor)\n", | |
1830 | - version); | |
1828 | + "fixing up to 0x10. (tell your hw vendor)\n", | |
1829 | + version); | |
1831 | 1830 | version = 0x10; |
1832 | 1831 | } |
1833 | 1832 | apic_version[apicid] = version; |
1834 | 1833 | |
1835 | - if (num_processors >= NR_CPUS) { | |
1836 | - pr_warning("WARNING: NR_CPUS limit of %i reached." | |
1837 | - " Processor ignored.\n", NR_CPUS); | |
1834 | + if (num_processors >= nr_cpu_ids) { | |
1835 | + int max = nr_cpu_ids; | |
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 | 1843 | return; |
1839 | 1844 | } |
1840 | 1845 | |
1841 | 1846 | num_processors++; |
1842 | - cpus_complement(tmp_map, cpu_present_map); | |
1843 | - cpu = first_cpu(tmp_map); | |
1847 | + cpu = cpumask_next_zero(-1, cpu_present_mask); | |
1844 | 1848 | |
1845 | 1849 | physid_set(apicid, phys_cpu_present_map); |
1846 | 1850 | if (apicid == boot_cpu_physical_apicid) { |
arch/x86/kernel/smpboot.c
... | ... | @@ -1252,6 +1252,15 @@ |
1252 | 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 | 1265 | * cpu_possible_map should be static, it cannot change as cpu's |
1257 | 1266 | * are onlined, or offlined. The reason is per-cpu data-structures |
... | ... | @@ -1264,7 +1273,7 @@ |
1264 | 1273 | * |
1265 | 1274 | * Three ways to find out the number of additional hotplug CPUs: |
1266 | 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 | 1277 | * - Otherwise don't reserve additional CPUs. |
1269 | 1278 | * We do this because additional CPUs waste a lot of memory. |
1270 | 1279 | * -AK |
... | ... | @@ -1277,9 +1286,17 @@ |
1277 | 1286 | if (!num_processors) |
1278 | 1287 | num_processors = 1; |
1279 | 1288 | |
1280 | - possible = num_processors + disabled_cpus; | |
1281 | - if (possible > NR_CPUS) | |
1282 | - possible = NR_CPUS; | |
1289 | + if (setup_possible_cpus == -1) | |
1290 | + possible = num_processors + disabled_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 | 1301 | printk(KERN_INFO "SMP: Allowing %d CPUs, %d hotplug CPUs\n", |
1285 | 1302 | possible, max_t(int, possible - num_processors, 0)); |