Skip to content

Commit

Permalink
x86, apic: Don't use logical-flat mode when CPU hotplug may exceed 8 …
Browse files Browse the repository at this point in the history
…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>
  • Loading branch information
Suresh Siddha authored and H. Peter Anvin committed Feb 10, 2010
1 parent cf9db6c commit 681ee44
Show file tree
Hide file tree
Showing 6 changed files with 28 additions and 34 deletions.
5 changes: 0 additions & 5 deletions arch/x86/kernel/acpi/boot.c
Original file line number Diff line number Diff line change
Expand Up @@ -1185,9 +1185,6 @@ static void __init acpi_process_madt(void)
if (!error) {
acpi_lapic = 1;

#ifdef CONFIG_X86_BIGSMP
generic_bigsmp_probe();
#endif
/*
* Parse MADT IO-APIC entries
*/
Expand All @@ -1197,8 +1194,6 @@ static void __init acpi_process_madt(void)
acpi_ioapic = 1;

smp_found_config = 1;
if (apic->setup_apic_routing)
apic->setup_apic_routing();
}
}
if (error == -EINVAL) {
Expand Down
17 changes: 0 additions & 17 deletions arch/x86/kernel/apic/apic.c
Original file line number Diff line number Diff line change
Expand Up @@ -1641,9 +1641,7 @@ int __init APIC_init_uniprocessor(void)
#endif

enable_IR_x2apic();
#ifdef CONFIG_X86_64
default_setup_apic_routing();
#endif

verify_local_APIC();
connect_bsp_APIC();
Expand Down Expand Up @@ -1891,21 +1889,6 @@ void __cpuinit generic_processor_info(int apicid, int version)
if (apicid > max_physical_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)
early_per_cpu(x86_cpu_to_apicid, cpu) = apicid;
early_per_cpu(x86_bios_cpu_apicid, cpu) = apicid;
Expand Down
29 changes: 27 additions & 2 deletions arch/x86/kernel/apic/probe_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,32 @@ static int __init print_ipi_mode(void)
}
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
printk(KERN_INFO
Expand Down Expand Up @@ -103,7 +128,7 @@ struct apic apic_default = {
.init_apic_ldr = default_init_apic_ldr,

.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,
.apicid_to_node = default_apicid_to_node,
.cpu_to_logical_apicid = default_cpu_to_logical_apicid,
Expand Down
2 changes: 1 addition & 1 deletion arch/x86/kernel/apic/probe_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ void __init default_setup_apic_routing(void)
}
#endif

if (apic == &apic_flat && num_processors > 8)
if (apic == &apic_flat && num_possible_cpus() > 8)
apic = &apic_physflat;

printk(KERN_INFO "Setting APIC routing to %s\n", apic->name);
Expand Down
7 changes: 0 additions & 7 deletions arch/x86/kernel/mpparse.c
Original file line number Diff line number Diff line change
Expand Up @@ -359,13 +359,6 @@ static int __init smp_read_mpc(struct mpc_table *mpc, unsigned early)
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)
printk(KERN_ERR "MPTABLE: no processors registered!\n");
return num_processors;
Expand Down
2 changes: 0 additions & 2 deletions arch/x86/kernel/smpboot.c
Original file line number Diff line number Diff line change
Expand Up @@ -1083,9 +1083,7 @@ void __init native_smp_prepare_cpus(unsigned int max_cpus)
set_cpu_sibling_map(0);

enable_IR_x2apic();
#ifdef CONFIG_X86_64
default_setup_apic_routing();
#endif

if (smp_sanity_check(max_cpus) < 0) {
printk(KERN_INFO "SMP disabled\n");
Expand Down

0 comments on commit 681ee44

Please sign in to comment.