tree 7d92e2b57c66f076908a5739056d823a4bde0121
parent 3dd9d514846cdca1dcef2e4fce666d85e199e844
author Andi Kleen <[EMAIL PROTECTED]> Sun, 17 Apr 2005 05:25:16 -0700
committer Linus Torvalds <[EMAIL PROTECTED]> Sun, 17 Apr 2005 05:25:16 -0700
[PATCH] x86_64: Final support for AMD dual core
Clean up the code greatly. Now uses the infrastructure from the Intel dual
core patch Should fix a final bug noticed by Tyan of not detecting the nodes
correctly in some corner cases.
Patch for x86-64 and i386
Signed-off-by: Andi Kleen <[EMAIL PROTECTED]>
Signed-off-by: Rafael J. Wysocki <[EMAIL PROTECTED]>
Signed-off-by: Andrew Morton <[EMAIL PROTECTED]>
Signed-off-by: Linus Torvalds <[EMAIL PROTECTED]>
i386/kernel/cpu/amd.c | 24 +++++++++------
i386/kernel/cpu/common.c | 2 -
x86_64/kernel/setup.c | 71 +++++++++++++++++++++++++----------------------
3 files changed, 53 insertions(+), 44 deletions(-)
Index: arch/i386/kernel/cpu/amd.c
===================================================================
--- 28e60a8b733db213e88b0aee8ef3861a93a6fa48/arch/i386/kernel/cpu/amd.c
(mode:100644 sha1:fa10d0a509c7ad5f6712a3beba595e35aef0b642)
+++ 7d92e2b57c66f076908a5739056d823a4bde0121/arch/i386/kernel/cpu/amd.c
(mode:100644 sha1:8d182e875cd72e64b49869386bf090ba23df6793)
@@ -24,6 +24,9 @@
static void __init init_amd(struct cpuinfo_x86 *c)
{
+#ifdef CONFIG_SMP
+ int cpu = c == &boot_cpu_data ? 0 : c - cpu_data;
+#endif
u32 l, h;
int mbytes = num_physpages >> (20-PAGE_SHIFT);
int r;
@@ -195,16 +198,17 @@
c->x86_num_cores = 1;
}
- detect_ht(c);
-
-#ifdef CONFIG_X86_HT
- /* AMD dual core looks like HT but isn't really. Hide it from the
- scheduler. This works around problems with the domain scheduler.
- Also probably gives slightly better scheduling and disables
- SMT nice which is harmful on dual core.
- TBD tune the domain scheduler for dual core. */
- if (cpu_has(c, X86_FEATURE_CMP_LEGACY))
- smp_num_siblings = 1;
+#ifdef CONFIG_SMP
+ /*
+ * On a AMD dual core setup the lower bits of the APIC id
+ * distingush the cores. Assumes number of cores is a power
+ * of two.
+ */
+ if (c->x86_num_cores > 1) {
+ cpu_core_id[cpu] = cpu >> hweight32(c->x86_num_cores - 1);
+ printk(KERN_INFO "CPU %d(%d) -> Core %d\n",
+ cpu, c->x86_num_cores, cpu_core_id[cpu]);
+ }
#endif
}
Index: arch/i386/kernel/cpu/common.c
===================================================================
--- 28e60a8b733db213e88b0aee8ef3861a93a6fa48/arch/i386/kernel/cpu/common.c
(mode:100644 sha1:ed4c9c3fe667b6f8922f7a05c7fc13488d397120)
+++ 7d92e2b57c66f076908a5739056d823a4bde0121/arch/i386/kernel/cpu/common.c
(mode:100644 sha1:6be0310e3cd3a15fc70bcf4782228cf73d7e161a)
@@ -437,7 +437,7 @@
int index_msb, tmp;
int cpu = smp_processor_id();
- if (!cpu_has(c, X86_FEATURE_HT))
+ if (!cpu_has(c, X86_FEATURE_HT) || cpu_has(c, X86_FEATURE_CMP_LEGACY))
return;
cpuid(1, &eax, &ebx, &ecx, &edx);
Index: arch/x86_64/kernel/setup.c
===================================================================
--- 28e60a8b733db213e88b0aee8ef3861a93a6fa48/arch/x86_64/kernel/setup.c
(mode:100644 sha1:ef74564eedebc170c86c823a15715c746bccbe0f)
+++ 7d92e2b57c66f076908a5739056d823a4bde0121/arch/x86_64/kernel/setup.c
(mode:100644 sha1:666fe8bcca0e7a7051699ceff20da2877c37ed37)
@@ -715,14 +715,46 @@
}
}
+#ifdef CONFIG_SMP
+/*
+ * On a AMD dual core setup the lower bits of the APIC id distingush the cores.
+ * Assumes number of cores is a power of two.
+ */
+static void __init amd_detect_cmp(struct cpuinfo_x86 *c)
+{
+#ifdef CONFIG_SMP
+ int cpu = c->x86_apicid;
+ int node = 0;
+ if (c->x86_num_cores == 1)
+ return;
+ cpu_core_id[cpu] = cpu >> hweight32(c->x86_num_cores - 1);
+
+#ifdef CONFIG_NUMA
+ /* When an ACPI SRAT table is available use the mappings from SRAT
+ instead. */
+ if (acpi_numa <= 0) {
+ node = cpu_core_id[cpu];
+ if (!node_online(node))
+ node = first_node(node_online_map);
+ cpu_to_node[cpu] = node;
+ } else {
+ node = cpu_to_node[cpu];
+ }
+#endif
+ printk(KERN_INFO "CPU %d(%d) -> Node %d -> Core %d\n",
+ cpu, c->x86_num_cores, node, cpu_core_id[cpu]);
+#endif
+}
+#else
+static void __init amd_detect_cmp(struct cpuinfo_x86 *c)
+{
+}
+#endif
static int __init init_amd(struct cpuinfo_x86 *c)
{
int r;
int level;
-#ifdef CONFIG_NUMA
- int cpu;
-#endif
/* Bit 31 in normal CPUID used for nonstandard 3DNow ID;
3DNow is IDd by bit 31 in extended CPUID (1*32+31) anyway */
@@ -750,21 +782,7 @@
if (c->x86_num_cores & (c->x86_num_cores - 1))
c->x86_num_cores = 1;
-#ifdef CONFIG_NUMA
- /* On a dual core setup the lower bits of apic id
- distingush the cores. Fix up the CPU<->node mappings
- here based on that.
- Assumes number of cores is a power of two.
- When using SRAT use mapping from SRAT. */
- cpu = c->x86_apicid;
- if (acpi_numa <= 0 && c->x86_num_cores > 1) {
- cpu_to_node[cpu] = cpu >> hweight32(c->x86_num_cores -
1);
- if (!node_online(cpu_to_node[cpu]))
- cpu_to_node[cpu] = first_node(node_online_map);
- }
- printk(KERN_INFO "CPU %d(%d) -> Node %d\n",
- cpu, c->x86_num_cores, cpu_to_node[cpu]);
-#endif
+ amd_detect_cmp(c);
}
return r;
@@ -777,7 +795,7 @@
int index_msb, tmp;
int cpu = smp_processor_id();
- if (!cpu_has(c, X86_FEATURE_HT))
+ if (!cpu_has(c, X86_FEATURE_HT) || cpu_has(c, X86_FEATURE_CMP_LEGACY))
return;
cpuid(1, &eax, &ebx, &ecx, &edx);
@@ -819,6 +837,7 @@
if (smp_num_siblings & (smp_num_siblings - 1))
index_msb++;
+ /* RED-PEN surely this must run in the non HT case too! -AK */
cpu_core_id[cpu] = phys_pkg_id(index_msb);
if (c->x86_num_cores > 1)
@@ -828,19 +847,6 @@
#endif
}
-static void __init sched_cmp_hack(struct cpuinfo_x86 *c)
-{
-#ifdef CONFIG_SMP
- /* AMD dual core looks like HT but isn't really. Hide it from the
- scheduler. This works around problems with the domain scheduler.
- Also probably gives slightly better scheduling and disables
- SMT nice which is harmful on dual core.
- TBD tune the domain scheduler for dual core. */
- if (c->x86_vendor == X86_VENDOR_AMD && cpu_has(c,
X86_FEATURE_CMP_LEGACY))
- smp_num_siblings = 1;
-#endif
-}
-
/*
* find out the number of processor cores on the die
*/
@@ -1009,7 +1015,6 @@
select_idle_routine(c);
detect_ht(c);
- sched_cmp_hack(c);
/*
* On SMP, boot_cpu_data holds the common feature set between
-
To unsubscribe from this list: send the line "unsubscribe bk-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at http://vger.kernel.org/majordomo-info.html