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) ...@@ -103,6 +103,16 @@ static unsigned int cluster_cpu_mask_to_apicid(cpumask_t cpumask)
return BAD_APICID; 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 = { struct genapic apic_cluster = {
.name = "clustered", .name = "clustered",
...@@ -116,4 +126,5 @@ struct genapic apic_cluster = { ...@@ -116,4 +126,5 @@ struct genapic apic_cluster = {
.send_IPI_allbutself = cluster_send_IPI_allbutself, .send_IPI_allbutself = cluster_send_IPI_allbutself,
.send_IPI_mask = cluster_send_IPI_mask, .send_IPI_mask = cluster_send_IPI_mask,
.cpu_mask_to_apicid = cluster_cpu_mask_to_apicid, .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) ...@@ -103,6 +103,13 @@ static unsigned int flat_cpu_mask_to_apicid(cpumask_t cpumask)
return cpus_addr(cpumask)[0] & APIC_ALL_CPUS; 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 = { struct genapic apic_flat = {
.name = "flat", .name = "flat",
...@@ -116,4 +123,5 @@ struct genapic apic_flat = { ...@@ -116,4 +123,5 @@ struct genapic apic_flat = {
.send_IPI_allbutself = flat_send_IPI_allbutself, .send_IPI_allbutself = flat_send_IPI_allbutself,
.send_IPI_mask = flat_send_IPI_mask, .send_IPI_mask = flat_send_IPI_mask,
.cpu_mask_to_apicid = flat_cpu_mask_to_apicid, .cpu_mask_to_apicid = flat_cpu_mask_to_apicid,
.phys_pkg_id = phys_pkg_id,
}; };
...@@ -56,6 +56,7 @@ ...@@ -56,6 +56,7 @@
#include <asm/smp.h> #include <asm/smp.h>
#include <asm/proto.h> #include <asm/proto.h>
#include <asm/setup.h> #include <asm/setup.h>
#include <asm/mach_apic.h>
/* /*
* Machine setup.. * Machine setup..
...@@ -710,7 +711,6 @@ static void __init detect_ht(struct cpuinfo_x86 *c) ...@@ -710,7 +711,6 @@ static void __init detect_ht(struct cpuinfo_x86 *c)
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
u32 eax, ebx, ecx, edx; u32 eax, ebx, ecx, edx;
int index_lsb, index_msb, tmp; int index_lsb, index_msb, tmp;
int initial_apic_id;
int cpu = smp_processor_id(); int cpu = smp_processor_id();
if (!cpu_has(c, X86_FEATURE_HT)) if (!cpu_has(c, X86_FEATURE_HT))
...@@ -745,8 +745,7 @@ static void __init detect_ht(struct cpuinfo_x86 *c) ...@@ -745,8 +745,7 @@ static void __init detect_ht(struct cpuinfo_x86 *c)
} }
if (index_lsb != index_msb ) if (index_lsb != index_msb )
index_msb++; index_msb++;
initial_apic_id = hard_smp_processor_id(); phys_proc_id[cpu] = phys_pkg_id(index_msb);
phys_proc_id[cpu] = initial_apic_id >> index_msb;
printk(KERN_INFO "CPU: Physical Processor ID: %d\n", printk(KERN_INFO "CPU: Physical Processor ID: %d\n",
phys_proc_id[cpu]); phys_proc_id[cpu]);
......
...@@ -26,6 +26,7 @@ struct genapic { ...@@ -26,6 +26,7 @@ struct genapic {
void (*send_IPI_all)(int vector); void (*send_IPI_all)(int vector);
/* */ /* */
unsigned int (*cpu_mask_to_apicid)(cpumask_t cpumask); unsigned int (*cpu_mask_to_apicid)(cpumask_t cpumask);
unsigned int (*phys_pkg_id)(int index_msb);
}; };
......
...@@ -24,5 +24,6 @@ ...@@ -24,5 +24,6 @@
#define send_IPI_allbutself (genapic->send_IPI_allbutself) #define send_IPI_allbutself (genapic->send_IPI_allbutself)
#define send_IPI_all (genapic->send_IPI_all) #define send_IPI_all (genapic->send_IPI_all)
#define cpu_mask_to_apicid (genapic->cpu_mask_to_apicid) #define cpu_mask_to_apicid (genapic->cpu_mask_to_apicid)
#define phys_pkg_id (genapic->phys_pkg_id)
#endif /* __ASM_MACH_APIC_H */ #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