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