diff options
author | Siddha, Suresh B <suresh.b.siddha@intel.com> | 2005-11-05 11:25:54 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-11-14 22:55:16 -0500 |
commit | 94605eff572b727aaad9b4b29bc358b919096503 (patch) | |
tree | 657a848d8ef34d2f94bbad3aa4e5458d2d3f2d2b /arch/x86_64/kernel/setup.c | |
parent | e90f22edf432512219cc2952f5811961abbd164f (diff) |
[PATCH] x86-64/i386: Intel HT, Multi core detection fixes
Fields obtained through cpuid vector 0x1(ebx[16:23]) and
vector 0x4(eax[14:25], eax[26:31]) indicate the maximum values and might not
always be the same as what is available and what OS sees. So make sure
"siblings" and "cpu cores" values in /proc/cpuinfo reflect the values as seen
by OS instead of what cpuid instruction says. This will also fix the buggy BIOS
cases (for example where cpuid on a single core cpu says there are "2" siblings,
even when HT is disabled in the BIOS.
http://bugzilla.kernel.org/show_bug.cgi?id=4359)
Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com>
Signed-off-by: Andi Kleen <ak@suse.de>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/x86_64/kernel/setup.c')
-rw-r--r-- | arch/x86_64/kernel/setup.c | 69 |
1 files changed, 29 insertions, 40 deletions
diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c index 476ee034fca2..40c77f6fe4b0 100644 --- a/arch/x86_64/kernel/setup.c +++ b/arch/x86_64/kernel/setup.c | |||
@@ -795,7 +795,7 @@ static void __init amd_detect_cmp(struct cpuinfo_x86 *c) | |||
795 | #endif | 795 | #endif |
796 | 796 | ||
797 | bits = 0; | 797 | bits = 0; |
798 | while ((1 << bits) < c->x86_num_cores) | 798 | while ((1 << bits) < c->x86_max_cores) |
799 | bits++; | 799 | bits++; |
800 | 800 | ||
801 | /* Low order bits define the core id (index of core in socket) */ | 801 | /* Low order bits define the core id (index of core in socket) */ |
@@ -828,7 +828,7 @@ static void __init amd_detect_cmp(struct cpuinfo_x86 *c) | |||
828 | numa_set_node(cpu, node); | 828 | numa_set_node(cpu, node); |
829 | 829 | ||
830 | printk(KERN_INFO "CPU %d(%d) -> Node %d -> Core %d\n", | 830 | printk(KERN_INFO "CPU %d(%d) -> Node %d -> Core %d\n", |
831 | cpu, c->x86_num_cores, node, cpu_core_id[cpu]); | 831 | cpu, c->x86_max_cores, node, cpu_core_id[cpu]); |
832 | #endif | 832 | #endif |
833 | #endif | 833 | #endif |
834 | } | 834 | } |
@@ -877,9 +877,9 @@ static int __init init_amd(struct cpuinfo_x86 *c) | |||
877 | display_cacheinfo(c); | 877 | display_cacheinfo(c); |
878 | 878 | ||
879 | if (c->extended_cpuid_level >= 0x80000008) { | 879 | if (c->extended_cpuid_level >= 0x80000008) { |
880 | c->x86_num_cores = (cpuid_ecx(0x80000008) & 0xff) + 1; | 880 | c->x86_max_cores = (cpuid_ecx(0x80000008) & 0xff) + 1; |
881 | if (c->x86_num_cores & (c->x86_num_cores - 1)) | 881 | if (c->x86_max_cores & (c->x86_max_cores - 1)) |
882 | c->x86_num_cores = 1; | 882 | c->x86_max_cores = 1; |
883 | 883 | ||
884 | amd_detect_cmp(c); | 884 | amd_detect_cmp(c); |
885 | } | 885 | } |
@@ -891,54 +891,44 @@ static void __cpuinit detect_ht(struct cpuinfo_x86 *c) | |||
891 | { | 891 | { |
892 | #ifdef CONFIG_SMP | 892 | #ifdef CONFIG_SMP |
893 | u32 eax, ebx, ecx, edx; | 893 | u32 eax, ebx, ecx, edx; |
894 | int index_msb, tmp; | 894 | int index_msb, core_bits; |
895 | int cpu = smp_processor_id(); | 895 | int cpu = smp_processor_id(); |
896 | 896 | ||
897 | cpuid(1, &eax, &ebx, &ecx, &edx); | ||
898 | |||
899 | c->apicid = phys_pkg_id(0); | ||
900 | |||
897 | if (!cpu_has(c, X86_FEATURE_HT) || cpu_has(c, X86_FEATURE_CMP_LEGACY)) | 901 | if (!cpu_has(c, X86_FEATURE_HT) || cpu_has(c, X86_FEATURE_CMP_LEGACY)) |
898 | return; | 902 | return; |
899 | 903 | ||
900 | cpuid(1, &eax, &ebx, &ecx, &edx); | ||
901 | smp_num_siblings = (ebx & 0xff0000) >> 16; | 904 | smp_num_siblings = (ebx & 0xff0000) >> 16; |
902 | 905 | ||
903 | if (smp_num_siblings == 1) { | 906 | if (smp_num_siblings == 1) { |
904 | printk(KERN_INFO "CPU: Hyper-Threading is disabled\n"); | 907 | printk(KERN_INFO "CPU: Hyper-Threading is disabled\n"); |
905 | } else if (smp_num_siblings > 1) { | 908 | } else if (smp_num_siblings > 1 ) { |
906 | index_msb = 31; | 909 | |
907 | /* | ||
908 | * At this point we only support two siblings per | ||
909 | * processor package. | ||
910 | */ | ||
911 | if (smp_num_siblings > NR_CPUS) { | 910 | if (smp_num_siblings > NR_CPUS) { |
912 | printk(KERN_WARNING "CPU: Unsupported number of the siblings %d", smp_num_siblings); | 911 | printk(KERN_WARNING "CPU: Unsupported number of the siblings %d", smp_num_siblings); |
913 | smp_num_siblings = 1; | 912 | smp_num_siblings = 1; |
914 | return; | 913 | return; |
915 | } | 914 | } |
916 | tmp = smp_num_siblings; | 915 | |
917 | while ((tmp & 0x80000000 ) == 0) { | 916 | index_msb = get_count_order(smp_num_siblings); |
918 | tmp <<=1 ; | ||
919 | index_msb--; | ||
920 | } | ||
921 | if (smp_num_siblings & (smp_num_siblings - 1)) | ||
922 | index_msb++; | ||
923 | phys_proc_id[cpu] = phys_pkg_id(index_msb); | 917 | phys_proc_id[cpu] = phys_pkg_id(index_msb); |
924 | 918 | ||
925 | printk(KERN_INFO "CPU: Physical Processor ID: %d\n", | 919 | printk(KERN_INFO "CPU: Physical Processor ID: %d\n", |
926 | phys_proc_id[cpu]); | 920 | phys_proc_id[cpu]); |
927 | 921 | ||
928 | smp_num_siblings = smp_num_siblings / c->x86_num_cores; | 922 | smp_num_siblings = smp_num_siblings / c->x86_max_cores; |
929 | 923 | ||
930 | tmp = smp_num_siblings; | 924 | index_msb = get_count_order(smp_num_siblings) ; |
931 | index_msb = 31; | 925 | |
932 | while ((tmp & 0x80000000) == 0) { | 926 | core_bits = get_count_order(c->x86_max_cores); |
933 | tmp <<=1 ; | ||
934 | index_msb--; | ||
935 | } | ||
936 | if (smp_num_siblings & (smp_num_siblings - 1)) | ||
937 | index_msb++; | ||
938 | 927 | ||
939 | cpu_core_id[cpu] = phys_pkg_id(index_msb); | 928 | cpu_core_id[cpu] = phys_pkg_id(index_msb) & |
929 | ((1 << core_bits) - 1); | ||
940 | 930 | ||
941 | if (c->x86_num_cores > 1) | 931 | if (c->x86_max_cores > 1) |
942 | printk(KERN_INFO "CPU: Processor Core ID: %d\n", | 932 | printk(KERN_INFO "CPU: Processor Core ID: %d\n", |
943 | cpu_core_id[cpu]); | 933 | cpu_core_id[cpu]); |
944 | } | 934 | } |
@@ -1006,7 +996,7 @@ static void __cpuinit init_intel(struct cpuinfo_x86 *c) | |||
1006 | c->x86_cache_alignment = c->x86_clflush_size * 2; | 996 | c->x86_cache_alignment = c->x86_clflush_size * 2; |
1007 | if (c->x86 >= 15) | 997 | if (c->x86 >= 15) |
1008 | set_bit(X86_FEATURE_CONSTANT_TSC, &c->x86_capability); | 998 | set_bit(X86_FEATURE_CONSTANT_TSC, &c->x86_capability); |
1009 | c->x86_num_cores = intel_num_cpu_cores(c); | 999 | c->x86_max_cores = intel_num_cpu_cores(c); |
1010 | 1000 | ||
1011 | srat_detect_node(); | 1001 | srat_detect_node(); |
1012 | } | 1002 | } |
@@ -1044,7 +1034,7 @@ void __cpuinit early_identify_cpu(struct cpuinfo_x86 *c) | |||
1044 | c->x86_model_id[0] = '\0'; /* Unset */ | 1034 | c->x86_model_id[0] = '\0'; /* Unset */ |
1045 | c->x86_clflush_size = 64; | 1035 | c->x86_clflush_size = 64; |
1046 | c->x86_cache_alignment = c->x86_clflush_size; | 1036 | c->x86_cache_alignment = c->x86_clflush_size; |
1047 | c->x86_num_cores = 1; | 1037 | c->x86_max_cores = 1; |
1048 | c->extended_cpuid_level = 0; | 1038 | c->extended_cpuid_level = 0; |
1049 | memset(&c->x86_capability, 0, sizeof c->x86_capability); | 1039 | memset(&c->x86_capability, 0, sizeof c->x86_capability); |
1050 | 1040 | ||
@@ -1278,13 +1268,12 @@ static int show_cpuinfo(struct seq_file *m, void *v) | |||
1278 | seq_printf(m, "cache size\t: %d KB\n", c->x86_cache_size); | 1268 | seq_printf(m, "cache size\t: %d KB\n", c->x86_cache_size); |
1279 | 1269 | ||
1280 | #ifdef CONFIG_SMP | 1270 | #ifdef CONFIG_SMP |
1281 | if (smp_num_siblings * c->x86_num_cores > 1) { | 1271 | if (smp_num_siblings * c->x86_max_cores > 1) { |
1282 | int cpu = c - cpu_data; | 1272 | int cpu = c - cpu_data; |
1283 | seq_printf(m, "physical id\t: %d\n", phys_proc_id[cpu]); | 1273 | seq_printf(m, "physical id\t: %d\n", phys_proc_id[cpu]); |
1284 | seq_printf(m, "siblings\t: %d\n", | 1274 | seq_printf(m, "siblings\t: %d\n", cpus_weight(cpu_core_map[cpu])); |
1285 | c->x86_num_cores * smp_num_siblings); | ||
1286 | seq_printf(m, "core id\t\t: %d\n", cpu_core_id[cpu]); | 1275 | seq_printf(m, "core id\t\t: %d\n", cpu_core_id[cpu]); |
1287 | seq_printf(m, "cpu cores\t: %d\n", c->x86_num_cores); | 1276 | seq_printf(m, "cpu cores\t: %d\n", c->booted_cores); |
1288 | } | 1277 | } |
1289 | #endif | 1278 | #endif |
1290 | 1279 | ||