Commit 3b11ce7f authored by Mike Travis's avatar Mike Travis Committed by Ingo Molnar

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: default avatarMike Travis <travis@sgi.com>
parent a775a38b
...@@ -50,16 +50,17 @@ additional_cpus=n (*) Use this to limit hotpluggable cpus. This option sets ...@@ -50,16 +50,17 @@ additional_cpus=n (*) Use this to limit hotpluggable cpus. This option sets
cpu_possible_map = cpu_present_map + additional_cpus cpu_possible_map = cpu_present_map + additional_cpus
(*) Option valid only for following architectures (*) Option valid only for following architectures
- x86_64, ia64 - ia64
ia64 and x86_64 use the number of disabled local apics in ACPI tables MADT ia64 uses the number of disabled local apics in ACPI tables MADT to
to determine the number of potentially hot-pluggable cpus. The implementation determine the number of potentially hot-pluggable cpus. The implementation
should only rely on this to count the # of cpus, but *MUST* not rely on the should only rely on this to count the # of cpus, but *MUST* not rely
apicid values in those tables for disabled apics. In the event BIOS doesn't on the apicid values in those tables for disabled apics. In the event
mark such hot-pluggable cpus as disabled entries, one could use this BIOS doesn't mark such hot-pluggable cpus as disabled entries, one could
parameter "additional_cpus=x" to represent those cpus in the cpu_possible_map. use this parameter "additional_cpus=x" to represent those cpus in the
cpu_possible_map.
possible_cpus=n [s390 only] use this to set hotpluggable cpus. possible_cpus=n [s390,x86_64] use this to set hotpluggable cpus.
This option sets possible_cpus bits in This option sets possible_cpus bits in
cpu_possible_map. Thus keeping the numbers of bits set cpu_possible_map. Thus keeping the numbers of bits set
constant even if the machine gets rebooted. constant even if the machine gets rebooted.
......
...@@ -1819,28 +1819,32 @@ void disconnect_bsp_APIC(int virt_wire_setup) ...@@ -1819,28 +1819,32 @@ void disconnect_bsp_APIC(int virt_wire_setup)
void __cpuinit generic_processor_info(int apicid, int version) void __cpuinit generic_processor_info(int apicid, int version)
{ {
int cpu; int cpu;
cpumask_t tmp_map;
/* /*
* Validate version * Validate version
*/ */
if (version == 0x0) { if (version == 0x0) {
pr_warning("BIOS bug, APIC version is 0 for CPU#%d! " pr_warning("BIOS bug, APIC version is 0 for CPU#%d! "
"fixing up to 0x10. (tell your hw vendor)\n", "fixing up to 0x10. (tell your hw vendor)\n",
version); version);
version = 0x10; version = 0x10;
} }
apic_version[apicid] = version; apic_version[apicid] = version;
if (num_processors >= NR_CPUS) { if (num_processors >= nr_cpu_ids) {
pr_warning("WARNING: NR_CPUS limit of %i reached." int max = nr_cpu_ids;
" Processor ignored.\n", NR_CPUS); int thiscpu = max + disabled_cpus;
pr_warning(
"ACPI: NR_CPUS/possible_cpus limit of %i reached."
" Processor %d/0x%x ignored.\n", max, thiscpu, apicid);
disabled_cpus++;
return; return;
} }
num_processors++; num_processors++;
cpus_complement(tmp_map, cpu_present_map); cpu = cpumask_next_zero(-1, cpu_present_mask);
cpu = first_cpu(tmp_map);
physid_set(apicid, phys_cpu_present_map); physid_set(apicid, phys_cpu_present_map);
if (apicid == boot_cpu_physical_apicid) { if (apicid == boot_cpu_physical_apicid) {
......
...@@ -1252,6 +1252,15 @@ void __init native_smp_cpus_done(unsigned int max_cpus) ...@@ -1252,6 +1252,15 @@ void __init native_smp_cpus_done(unsigned int max_cpus)
check_nmi_watchdog(); check_nmi_watchdog();
} }
static int __initdata setup_possible_cpus = -1;
static int __init _setup_possible_cpus(char *str)
{
get_option(&str, &setup_possible_cpus);
return 0;
}
early_param("possible_cpus", _setup_possible_cpus);
/* /*
* cpu_possible_map should be static, it cannot change as cpu's * cpu_possible_map should be static, it cannot change as cpu's
* are onlined, or offlined. The reason is per-cpu data-structures * 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,7 +1273,7 @@ void __init native_smp_cpus_done(unsigned int max_cpus)
* *
* Three ways to find out the number of additional hotplug CPUs: * Three ways to find out the number of additional hotplug CPUs:
* - If the BIOS specified disabled CPUs in ACPI/mptables use that. * - If the BIOS specified disabled CPUs in ACPI/mptables use that.
* - The user can overwrite it with additional_cpus=NUM * - The user can overwrite it with possible_cpus=NUM
* - Otherwise don't reserve additional CPUs. * - Otherwise don't reserve additional CPUs.
* We do this because additional CPUs waste a lot of memory. * We do this because additional CPUs waste a lot of memory.
* -AK * -AK
...@@ -1277,9 +1286,17 @@ __init void prefill_possible_map(void) ...@@ -1277,9 +1286,17 @@ __init void prefill_possible_map(void)
if (!num_processors) if (!num_processors)
num_processors = 1; num_processors = 1;
possible = num_processors + disabled_cpus; if (setup_possible_cpus == -1)
if (possible > NR_CPUS) possible = num_processors + disabled_cpus;
possible = NR_CPUS; else
possible = setup_possible_cpus;
if (possible > CONFIG_NR_CPUS) {
printk(KERN_WARNING
"%d Processors exceeds NR_CPUS limit of %d\n",
possible, CONFIG_NR_CPUS);
possible = CONFIG_NR_CPUS;
}
printk(KERN_INFO "SMP: Allowing %d CPUs, %d hotplug CPUs\n", printk(KERN_INFO "SMP: Allowing %d CPUs, %d hotplug CPUs\n",
possible, max_t(int, possible - num_processors, 0)); possible, max_t(int, possible - num_processors, 0));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment