[PATCH] x86_64: 386/x86-64 Further AMD dual core fixes

- Remove duplicated ifdef
- Make core_id match what Intel uses
- Initialize phys_proc_id correctly for non DC case
- Handle non power of two core numbers.

Fixes for both i386 and x86-64

Signed-off-by: Andi Kleen <ak@suse.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

authored by Andi Kleen and committed by Linus Torvalds b41e2939 b39c4fab

+19 -20
+6 -3
arch/i386/kernel/cpu/amd.c
··· 195 195 c->x86_num_cores = 1; 196 196 } 197 197 198 - #ifdef CONFIG_X86_SMP 198 + #ifdef CONFIG_X86_HT 199 199 /* 200 200 * On a AMD dual core setup the lower bits of the APIC id 201 201 * distingush the cores. Assumes number of cores is a power ··· 203 203 */ 204 204 if (c->x86_num_cores > 1) { 205 205 int cpu = smp_processor_id(); 206 - /* Fix up the APIC ID following AMD specifications. */ 207 - cpu_core_id[cpu] >>= hweight32(c->x86_num_cores - 1); 206 + unsigned bits = 0; 207 + while ((1 << bits) < c->x86_num_cores) 208 + bits++; 209 + cpu_core_id[cpu] = phys_proc_id[cpu] & ((1<<bits)-1); 210 + phys_proc_id[cpu] >>= bits; 208 211 printk(KERN_INFO "CPU %d(%d) -> Core %d\n", 209 212 cpu, c->x86_num_cores, cpu_core_id[cpu]); 210 213 }
+1 -4
arch/i386/kernel/cpu/common.c
··· 244 244 245 245 early_intel_workaround(c); 246 246 247 - #ifdef CONFIG_SMP 248 247 #ifdef CONFIG_X86_HT 249 - phys_proc_id[smp_processor_id()] = 250 - #endif 251 - cpu_core_id[smp_processor_id()] = (cpuid_ebx(1) >> 24) & 0xff; 248 + phys_proc_id[smp_processor_id()] = (cpuid_ebx(1) >> 24) & 0xff; 252 249 #endif 253 250 } 254 251
+12 -13
arch/x86_64/kernel/setup.c
··· 719 719 } 720 720 } 721 721 722 - #ifdef CONFIG_SMP 723 722 /* 724 723 * On a AMD dual core setup the lower bits of the APIC id distingush the cores. 725 724 * Assumes number of cores is a power of two. ··· 728 729 #ifdef CONFIG_SMP 729 730 int cpu = smp_processor_id(); 730 731 int node = 0; 732 + unsigned bits; 731 733 if (c->x86_num_cores == 1) 732 734 return; 733 - /* Fix up the APIC ID following the AMD specification. */ 734 - cpu_core_id[cpu] >>= hweight32(c->x86_num_cores - 1); 735 + 736 + bits = 0; 737 + while ((1 << bits) < c->x86_num_cores) 738 + bits++; 739 + 740 + /* Low order bits define the core id (index of core in socket) */ 741 + cpu_core_id[cpu] = phys_proc_id[cpu] & ((1 << bits)-1); 742 + /* Convert the APIC ID into the socket ID */ 743 + phys_proc_id[cpu] >>= bits; 735 744 736 745 #ifdef CONFIG_NUMA 737 746 /* When an ACPI SRAT table is available use the mappings from SRAT 738 747 instead. */ 739 748 if (acpi_numa <= 0) { 740 - node = cpu_core_id[cpu]; 749 + node = phys_proc_id[cpu]; 741 750 if (!node_online(node)) 742 751 node = first_node(node_online_map); 743 752 cpu_to_node[cpu] = node; ··· 753 746 node = cpu_to_node[cpu]; 754 747 } 755 748 #endif 756 - /* For now: - better than BAD_APIC_ID at least*/ 757 - phys_proc_id[cpu] = cpu_core_id[cpu]; 758 749 759 750 printk(KERN_INFO "CPU %d(%d) -> Node %d -> Core %d\n", 760 751 cpu, c->x86_num_cores, node, cpu_core_id[cpu]); 761 752 #endif 762 753 } 763 - #else 764 - static void __init amd_detect_cmp(struct cpuinfo_x86 *c) 765 - { 766 - } 767 - #endif 768 754 769 755 static int __init init_amd(struct cpuinfo_x86 *c) 770 756 { ··· 963 963 } 964 964 965 965 #ifdef CONFIG_SMP 966 - phys_proc_id[smp_processor_id()] = 967 - cpu_core_id[smp_processor_id()] = (cpuid_ebx(1) >> 24) & 0xff; 966 + phys_proc_id[smp_processor_id()] = (cpuid_ebx(1) >> 24) & 0xff; 968 967 #endif 969 968 } 970 969