Commit 5ce4469b authored by Suresh B. Siddha's avatar Suresh B. Siddha Committed by Linus Torvalds

[PATCH] x86-64: fix sibling map again

Recent x86-64 sibling map fix for clustered mode by James
(http://linux.bkbits.net:8080/linux-2.6/cset@414b34a6jkiHQ5AnhA269av76y3ZAw?nav=index.html)
is not the recommended way of fixing it.

That patch assumes BIOS for non-clustered systems accept the HW assigned
value.  Why make this assumption when we can fix it in a better
fashion(which is also used by x86 kernel's today)

Basically use HW assigned apic_id's(returned by cpuid) for non clustered
systems and for clustered use BIOS provided apic_id's.  Appended patch does
this.

Note: Similar issue was earlier disussed in context of x86 approx an year
back and James then backed out his changes.
http://www.ussg.iu.edu/hypermail/linux/kernel/0312.2/0167.htmlSigned-off-by: default avatarSuresh Siddha <suresh.b.siddha@intel.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent d3ad6fb9
......@@ -103,6 +103,16 @@ static unsigned int cluster_cpu_mask_to_apicid(cpumask_t cpumask)
return BAD_APICID;
}
/* cpuid returns the value latched in the HW at reset, not the APIC ID
* register's value. For any box whose BIOS changes APIC IDs, like
* clustered APIC systems, we must use hard_smp_processor_id.
*
* See Intel's IA-32 SW Dev's Manual Vol2 under CPUID.
*/
static unsigned int phys_pkg_id(int index_msb)
{
return hard_smp_processor_id() >> index_msb;
}
struct genapic apic_cluster = {
.name = "clustered",
......@@ -116,4 +126,5 @@ struct genapic apic_cluster = {
.send_IPI_allbutself = cluster_send_IPI_allbutself,
.send_IPI_mask = cluster_send_IPI_mask,
.cpu_mask_to_apicid = cluster_cpu_mask_to_apicid,
.phys_pkg_id = phys_pkg_id,
};
......@@ -103,6 +103,13 @@ static unsigned int flat_cpu_mask_to_apicid(cpumask_t cpumask)
return cpus_addr(cpumask)[0] & APIC_ALL_CPUS;
}
static unsigned int phys_pkg_id(int index_msb)
{
u32 ebx;
ebx = cpuid_ebx(1);
return ((ebx >> 24) & 0xFF) >> index_msb;
}
struct genapic apic_flat = {
.name = "flat",
......@@ -116,4 +123,5 @@ struct genapic apic_flat = {
.send_IPI_allbutself = flat_send_IPI_allbutself,
.send_IPI_mask = flat_send_IPI_mask,
.cpu_mask_to_apicid = flat_cpu_mask_to_apicid,
.phys_pkg_id = phys_pkg_id,
};
......@@ -56,6 +56,7 @@
#include <asm/smp.h>
#include <asm/proto.h>
#include <asm/setup.h>
#include <asm/mach_apic.h>
/*
* Machine setup..
......@@ -710,7 +711,6 @@ static void __init detect_ht(struct cpuinfo_x86 *c)
#ifdef CONFIG_SMP
u32 eax, ebx, ecx, edx;
int index_lsb, index_msb, tmp;
int initial_apic_id;
int cpu = smp_processor_id();
if (!cpu_has(c, X86_FEATURE_HT))
......@@ -745,8 +745,7 @@ static void __init detect_ht(struct cpuinfo_x86 *c)
}
if (index_lsb != index_msb )
index_msb++;
initial_apic_id = hard_smp_processor_id();
phys_proc_id[cpu] = initial_apic_id >> index_msb;
phys_proc_id[cpu] = phys_pkg_id(index_msb);
printk(KERN_INFO "CPU: Physical Processor ID: %d\n",
phys_proc_id[cpu]);
......
......@@ -26,6 +26,7 @@ struct genapic {
void (*send_IPI_all)(int vector);
/* */
unsigned int (*cpu_mask_to_apicid)(cpumask_t cpumask);
unsigned int (*phys_pkg_id)(int index_msb);
};
......
......@@ -24,5 +24,6 @@
#define send_IPI_allbutself (genapic->send_IPI_allbutself)
#define send_IPI_all (genapic->send_IPI_all)
#define cpu_mask_to_apicid (genapic->cpu_mask_to_apicid)
#define phys_pkg_id (genapic->phys_pkg_id)
#endif /* __ASM_MACH_APIC_H */
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