Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 99
b: refs/heads/master
c: 6351864
h: refs/heads/master
i:
  97: faedbbe
  95: 93d9527
v: v3
  • Loading branch information
Andi Kleen authored and Linus Torvalds committed Apr 16, 2005
1 parent 65063f8 commit 04430f3
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 45 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 3dd9d514846cdca1dcef2e4fce666d85e199e844
refs/heads/master: 635186447d0e6f3b35895fda993a266a1315d2a7
24 changes: 14 additions & 10 deletions trunk/arch/i386/kernel/cpu/amd.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ __asm__(".align 4\nvide: ret");

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;
Expand Down Expand Up @@ -195,16 +198,17 @@ static void __init init_amd(struct cpuinfo_x86 *c)
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
}

Expand Down
2 changes: 1 addition & 1 deletion trunk/arch/i386/kernel/cpu/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -437,7 +437,7 @@ void __init detect_ht(struct cpuinfo_x86 *c)
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);
Expand Down
71 changes: 38 additions & 33 deletions trunk/arch/x86_64/kernel/setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -715,14 +715,46 @@ static void __init display_cacheinfo(struct cpuinfo_x86 *c)
}
}

#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 */
Expand Down Expand Up @@ -750,21 +782,7 @@ static int __init init_amd(struct cpuinfo_x86 *c)
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;
Expand All @@ -777,7 +795,7 @@ static void __init detect_ht(struct cpuinfo_x86 *c)
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);
Expand Down Expand Up @@ -819,6 +837,7 @@ static void __init detect_ht(struct cpuinfo_x86 *c)
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)
Expand All @@ -828,19 +847,6 @@ static void __init detect_ht(struct cpuinfo_x86 *c)
#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
*/
Expand Down Expand Up @@ -1009,7 +1015,6 @@ void __init identify_cpu(struct cpuinfo_x86 *c)

select_idle_routine(c);
detect_ht(c);
sched_cmp_hack(c);

/*
* On SMP, boot_cpu_data holds the common feature set between
Expand Down

0 comments on commit 04430f3

Please sign in to comment.