x86, apic: Don't use logical-flat mode when CPU hotplug may exceed 8 CPUs
We need to fall back from logical-flat APIC mode to physical-flat mode when we have more than 8 CPUs. However, in the presence of CPU hotplug(with bios listing not enabled but possible cpus as disabled cpus in MADT), we have to consider the number of possible CPUs rather than the number of current CPUs; otherwise we may cross the 8-CPU boundary when CPUs are added later. 32bit apic code can use more cleanups (like the removal of vendor checks in 32bit default_setup_apic_routing()) and more unifications with 64bit code. Yinghai has some patches in works already. This patch addresses the boot issue that is reported in the virtualization guest context. [ hpa: incorporated function annotation feedback from Yinghai Lu ] Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com> LKML-Reference: <1265767304.2833.19.camel@sbs-t61.sc.intel.com> Acked-by: Shaohui Zheng <shaohui.zheng@intel.com> Reviewed-by: Yinghai Lu <yinghai@kernel.org> Cc: <stable@kernel.org> Signed-off-by: H. Peter Anvin <hpa@zytor.com>
This commit is contained in:
Родитель
cf9db6c41f
Коммит
681ee44d40
|
@ -1185,9 +1185,6 @@ static void __init acpi_process_madt(void)
|
||||||
if (!error) {
|
if (!error) {
|
||||||
acpi_lapic = 1;
|
acpi_lapic = 1;
|
||||||
|
|
||||||
#ifdef CONFIG_X86_BIGSMP
|
|
||||||
generic_bigsmp_probe();
|
|
||||||
#endif
|
|
||||||
/*
|
/*
|
||||||
* Parse MADT IO-APIC entries
|
* Parse MADT IO-APIC entries
|
||||||
*/
|
*/
|
||||||
|
@ -1197,8 +1194,6 @@ static void __init acpi_process_madt(void)
|
||||||
acpi_ioapic = 1;
|
acpi_ioapic = 1;
|
||||||
|
|
||||||
smp_found_config = 1;
|
smp_found_config = 1;
|
||||||
if (apic->setup_apic_routing)
|
|
||||||
apic->setup_apic_routing();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (error == -EINVAL) {
|
if (error == -EINVAL) {
|
||||||
|
|
|
@ -1641,9 +1641,7 @@ int __init APIC_init_uniprocessor(void)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
enable_IR_x2apic();
|
enable_IR_x2apic();
|
||||||
#ifdef CONFIG_X86_64
|
|
||||||
default_setup_apic_routing();
|
default_setup_apic_routing();
|
||||||
#endif
|
|
||||||
|
|
||||||
verify_local_APIC();
|
verify_local_APIC();
|
||||||
connect_bsp_APIC();
|
connect_bsp_APIC();
|
||||||
|
@ -1891,21 +1889,6 @@ void __cpuinit generic_processor_info(int apicid, int version)
|
||||||
if (apicid > max_physical_apicid)
|
if (apicid > max_physical_apicid)
|
||||||
max_physical_apicid = apicid;
|
max_physical_apicid = apicid;
|
||||||
|
|
||||||
#ifdef CONFIG_X86_32
|
|
||||||
if (num_processors > 8) {
|
|
||||||
switch (boot_cpu_data.x86_vendor) {
|
|
||||||
case X86_VENDOR_INTEL:
|
|
||||||
if (!APIC_XAPIC(version)) {
|
|
||||||
def_to_bigsmp = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
/* If P4 and above fall through */
|
|
||||||
case X86_VENDOR_AMD:
|
|
||||||
def_to_bigsmp = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(CONFIG_SMP) || defined(CONFIG_X86_64)
|
#if defined(CONFIG_SMP) || defined(CONFIG_X86_64)
|
||||||
early_per_cpu(x86_cpu_to_apicid, cpu) = apicid;
|
early_per_cpu(x86_cpu_to_apicid, cpu) = apicid;
|
||||||
early_per_cpu(x86_bios_cpu_apicid, cpu) = apicid;
|
early_per_cpu(x86_bios_cpu_apicid, cpu) = apicid;
|
||||||
|
|
|
@ -52,7 +52,32 @@ static int __init print_ipi_mode(void)
|
||||||
}
|
}
|
||||||
late_initcall(print_ipi_mode);
|
late_initcall(print_ipi_mode);
|
||||||
|
|
||||||
void default_setup_apic_routing(void)
|
void __init default_setup_apic_routing(void)
|
||||||
|
{
|
||||||
|
int version = apic_version[boot_cpu_physical_apicid];
|
||||||
|
|
||||||
|
if (num_possible_cpus() > 8) {
|
||||||
|
switch (boot_cpu_data.x86_vendor) {
|
||||||
|
case X86_VENDOR_INTEL:
|
||||||
|
if (!APIC_XAPIC(version)) {
|
||||||
|
def_to_bigsmp = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* If P4 and above fall through */
|
||||||
|
case X86_VENDOR_AMD:
|
||||||
|
def_to_bigsmp = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_X86_BIGSMP
|
||||||
|
generic_bigsmp_probe();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (apic->setup_apic_routing)
|
||||||
|
apic->setup_apic_routing();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void setup_apic_flat_routing(void)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_X86_IO_APIC
|
#ifdef CONFIG_X86_IO_APIC
|
||||||
printk(KERN_INFO
|
printk(KERN_INFO
|
||||||
|
@ -103,7 +128,7 @@ struct apic apic_default = {
|
||||||
.init_apic_ldr = default_init_apic_ldr,
|
.init_apic_ldr = default_init_apic_ldr,
|
||||||
|
|
||||||
.ioapic_phys_id_map = default_ioapic_phys_id_map,
|
.ioapic_phys_id_map = default_ioapic_phys_id_map,
|
||||||
.setup_apic_routing = default_setup_apic_routing,
|
.setup_apic_routing = setup_apic_flat_routing,
|
||||||
.multi_timer_check = NULL,
|
.multi_timer_check = NULL,
|
||||||
.apicid_to_node = default_apicid_to_node,
|
.apicid_to_node = default_apicid_to_node,
|
||||||
.cpu_to_logical_apicid = default_cpu_to_logical_apicid,
|
.cpu_to_logical_apicid = default_cpu_to_logical_apicid,
|
||||||
|
|
|
@ -67,7 +67,7 @@ void __init default_setup_apic_routing(void)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (apic == &apic_flat && num_processors > 8)
|
if (apic == &apic_flat && num_possible_cpus() > 8)
|
||||||
apic = &apic_physflat;
|
apic = &apic_physflat;
|
||||||
|
|
||||||
printk(KERN_INFO "Setting APIC routing to %s\n", apic->name);
|
printk(KERN_INFO "Setting APIC routing to %s\n", apic->name);
|
||||||
|
|
|
@ -359,13 +359,6 @@ static int __init smp_read_mpc(struct mpc_table *mpc, unsigned early)
|
||||||
x86_init.mpparse.mpc_record(1);
|
x86_init.mpparse.mpc_record(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_X86_BIGSMP
|
|
||||||
generic_bigsmp_probe();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (apic->setup_apic_routing)
|
|
||||||
apic->setup_apic_routing();
|
|
||||||
|
|
||||||
if (!num_processors)
|
if (!num_processors)
|
||||||
printk(KERN_ERR "MPTABLE: no processors registered!\n");
|
printk(KERN_ERR "MPTABLE: no processors registered!\n");
|
||||||
return num_processors;
|
return num_processors;
|
||||||
|
|
|
@ -1083,9 +1083,7 @@ void __init native_smp_prepare_cpus(unsigned int max_cpus)
|
||||||
set_cpu_sibling_map(0);
|
set_cpu_sibling_map(0);
|
||||||
|
|
||||||
enable_IR_x2apic();
|
enable_IR_x2apic();
|
||||||
#ifdef CONFIG_X86_64
|
|
||||||
default_setup_apic_routing();
|
default_setup_apic_routing();
|
||||||
#endif
|
|
||||||
|
|
||||||
if (smp_sanity_check(max_cpus) < 0) {
|
if (smp_sanity_check(max_cpus) < 0) {
|
||||||
printk(KERN_INFO "SMP disabled\n");
|
printk(KERN_INFO "SMP disabled\n");
|
||||||
|
|
Загрузка…
Ссылка в новой задаче