Andrew, Please apply this to your tree. This is 2.6.15 material.
Thanks.
--
This patch cleans up the x86 and x86_64 Intel HT and Multi Core detection code.
These are the areas that this patch touches.
a) Cleanup and merge HT and Mutli Core detection code for x86 and x86_64
b) 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)
c) Fix the cache detection code assumption that number of threads sharing the
cache will either be equal to number of HT or core siblings.
Signed-off-by: Suresh Siddha <[email protected]>
diff -pNru linux-2.6.14-rc3/arch/i386/kernel/Makefile linux-2.6.14-rc3-core/arch/i386/kernel/Makefile
--- linux-2.6.14-rc3/arch/i386/kernel/Makefile 2005-09-30 14:17:35.000000000 -0700
+++ linux-2.6.14-rc3-core/arch/i386/kernel/Makefile 2005-10-04 17:27:28.436096192 -0700
@@ -18,7 +18,7 @@ obj-$(CONFIG_X86_MSR) += msr.o
obj-$(CONFIG_X86_CPUID) += cpuid.o
obj-$(CONFIG_MICROCODE) += microcode.o
obj-$(CONFIG_APM) += apm.o
-obj-$(CONFIG_X86_SMP) += smp.o smpboot.o
+obj-$(CONFIG_X86_SMP) += smp.o smpboot.o sibling-map.o
obj-$(CONFIG_X86_TRAMPOLINE) += trampoline.o
obj-$(CONFIG_X86_MPPARSE) += mpparse.o
obj-$(CONFIG_X86_LOCAL_APIC) += apic.o nmi.o
diff -pNru linux-2.6.14-rc3/arch/i386/kernel/cpu/Makefile linux-2.6.14-rc3-core/arch/i386/kernel/cpu/Makefile
--- linux-2.6.14-rc3/arch/i386/kernel/cpu/Makefile 2005-09-30 14:17:35.000000000 -0700
+++ linux-2.6.14-rc3-core/arch/i386/kernel/cpu/Makefile 2005-10-04 17:27:28.436096192 -0700
@@ -8,7 +8,7 @@ obj-y += amd.o
obj-y += cyrix.o
obj-y += centaur.o
obj-y += transmeta.o
-obj-y += intel.o intel_cacheinfo.o
+obj-y += intel.o intel_cacheinfo.o intel_htmc.o
obj-y += rise.o
obj-y += nexgen.o
obj-y += umc.o
diff -pNru linux-2.6.14-rc3/arch/i386/kernel/cpu/common.c linux-2.6.14-rc3-core/arch/i386/kernel/cpu/common.c
--- linux-2.6.14-rc3/arch/i386/kernel/cpu/common.c 2005-09-30 14:17:35.000000000 -0700
+++ linux-2.6.14-rc3-core/arch/i386/kernel/cpu/common.c 2005-10-04 17:27:28.437096040 -0700
@@ -442,61 +442,6 @@ void __devinit identify_cpu(struct cpuin
mtrr_ap_init();
}
-#ifdef CONFIG_X86_HT
-void __devinit detect_ht(struct cpuinfo_x86 *c)
-{
- u32 eax, ebx, ecx, edx;
- int index_msb, tmp;
- int cpu = smp_processor_id();
-
- if (!cpu_has(c, X86_FEATURE_HT) || cpu_has(c, X86_FEATURE_CMP_LEGACY))
- return;
-
- cpuid(1, &eax, &ebx, &ecx, &edx);
- smp_num_siblings = (ebx & 0xff0000) >> 16;
-
- if (smp_num_siblings == 1) {
- printk(KERN_INFO "CPU: Hyper-Threading is disabled\n");
- } else if (smp_num_siblings > 1 ) {
- index_msb = 31;
-
- if (smp_num_siblings > NR_CPUS) {
- printk(KERN_WARNING "CPU: Unsupported number of the siblings %d", smp_num_siblings);
- smp_num_siblings = 1;
- return;
- }
- tmp = smp_num_siblings;
- while ((tmp & 0x80000000 ) == 0) {
- tmp <<=1 ;
- index_msb--;
- }
- if (smp_num_siblings & (smp_num_siblings - 1))
- index_msb++;
- phys_proc_id[cpu] = phys_pkg_id((ebx >> 24) & 0xFF, index_msb);
-
- printk(KERN_INFO "CPU: Physical Processor ID: %d\n",
- phys_proc_id[cpu]);
-
- smp_num_siblings = smp_num_siblings / c->x86_num_cores;
-
- tmp = smp_num_siblings;
- index_msb = 31;
- while ((tmp & 0x80000000) == 0) {
- tmp <<=1 ;
- index_msb--;
- }
-
- if (smp_num_siblings & (smp_num_siblings - 1))
- index_msb++;
-
- cpu_core_id[cpu] = phys_pkg_id((ebx >> 24) & 0xFF, index_msb);
-
- if (c->x86_num_cores > 1)
- printk(KERN_INFO "CPU: Processor Core ID: %d\n",
- cpu_core_id[cpu]);
- }
-}
-#endif
void __devinit print_cpu_info(struct cpuinfo_x86 *c)
{
diff -pNru linux-2.6.14-rc3/arch/i386/kernel/cpu/intel.c linux-2.6.14-rc3-core/arch/i386/kernel/cpu/intel.c
--- linux-2.6.14-rc3/arch/i386/kernel/cpu/intel.c 2005-09-30 14:17:35.000000000 -0700
+++ linux-2.6.14-rc3-core/arch/i386/kernel/cpu/intel.c 2005-10-04 17:27:28.437096040 -0700
@@ -76,25 +76,6 @@ static void __devinit Intel_errata_worka
}
}
-
-/*
- * find out the number of processor cores on the die
- */
-static int __devinit num_cpu_cores(struct cpuinfo_x86 *c)
-{
- unsigned int eax, ebx, ecx, edx;
-
- if (c->cpuid_level < 4)
- return 1;
-
- /* Intel has a non-standard dependency on %ecx for this CPUID level. */
- cpuid_count(4, 0, &eax, &ebx, &ecx, &edx);
- if (eax & 0x1f)
- return ((eax >> 26) + 1);
- else
- return 1;
-}
-
static void __devinit init_intel(struct cpuinfo_x86 *c)
{
unsigned int l2 = 0;
@@ -157,7 +138,7 @@ static void __devinit init_intel(struct
if ( p )
strcpy(c->x86_model_id, p);
- c->x86_num_cores = num_cpu_cores(c);
+ c->x86_num_cores = intel_num_cpu_cores(c);
detect_ht(c);
diff -pNru linux-2.6.14-rc3/arch/i386/kernel/cpu/intel_cacheinfo.c linux-2.6.14-rc3-core/arch/i386/kernel/cpu/intel_cacheinfo.c
--- linux-2.6.14-rc3/arch/i386/kernel/cpu/intel_cacheinfo.c 2005-09-30 14:17:35.000000000 -0700
+++ linux-2.6.14-rc3-core/arch/i386/kernel/cpu/intel_cacheinfo.c 2005-10-04 17:27:28.438095888 -0700
@@ -303,29 +303,45 @@ static struct _cpuid4_info *cpuid4_info[
#ifdef CONFIG_SMP
static void __devinit cache_shared_cpu_map_setup(unsigned int cpu, int index)
{
- struct _cpuid4_info *this_leaf;
+ struct _cpuid4_info *this_leaf, *sibling_leaf;
unsigned long num_threads_sharing;
-#ifdef CONFIG_X86_HT
- struct cpuinfo_x86 *c = cpu_data + cpu;
-#endif
+ int index_msb, i;
+ struct cpuinfo_x86 *c = cpu_data;
this_leaf = CPUID4_INFO_IDX(cpu, index);
num_threads_sharing = 1 + this_leaf->eax.split.num_threads_sharing;
if (num_threads_sharing == 1)
cpu_set(cpu, this_leaf->shared_cpu_map);
-#ifdef CONFIG_X86_HT
- else if (num_threads_sharing == smp_num_siblings)
- this_leaf->shared_cpu_map = cpu_sibling_map[cpu];
- else if (num_threads_sharing == (c->x86_num_cores * smp_num_siblings))
- this_leaf->shared_cpu_map = cpu_core_map[cpu];
- else
- printk(KERN_DEBUG "Number of CPUs sharing cache didn't match "
- "any known set of CPUs\n");
-#endif
+ else {
+ index_msb = get_count_order(num_threads_sharing);
+
+ for_each_online_cpu(i) {
+ if (c[i].apicid >> index_msb ==
+ c[cpu].apicid >> index_msb) {
+ cpu_set(i, this_leaf->shared_cpu_map);
+ if (i != cpu && cpuid4_info[i]) {
+ sibling_leaf = CPUID4_INFO_IDX(i, index);
+ cpu_set(cpu, sibling_leaf->shared_cpu_map);
+ }
+ }
+ }
+ }
+}
+static void __devinit cache_remove_shared_cpu_map(unsigned int cpu, int index)
+{
+ struct _cpuid4_info *this_leaf, *sibling_leaf;
+ int sibling;
+
+ this_leaf = CPUID4_INFO_IDX(cpu, index);
+ for_each_cpu_mask(sibling, this_leaf->shared_cpu_map) {
+ sibling_leaf = CPUID4_INFO_IDX(sibling, index);
+ cpu_clear(cpu, sibling_leaf->shared_cpu_map);
+ }
}
#else
static void __init cache_shared_cpu_map_setup(unsigned int cpu, int index) {}
+static void __init cache_remove_shared_cpu_map(unsigned int cpu, int index) {}
#endif
static void free_cache_attributes(unsigned int cpu)
@@ -584,8 +600,10 @@ static int __devexit cache_remove_dev(st
unsigned int cpu = sys_dev->id;
unsigned long i;
- for (i = 0; i < num_cache_leaves; i++)
+ for (i = 0; i < num_cache_leaves; i++) {
+ cache_remove_shared_cpu_map(cpu, i);
kobject_unregister(&(INDEX_KOBJECT_PTR(cpu,i)->kobj));
+ }
kobject_unregister(cache_kobject[cpu]);
cpuid4_cache_sysfs_exit(cpu);
return 0;
diff -pNru linux-2.6.14-rc3/arch/i386/kernel/cpu/intel_htmc.c linux-2.6.14-rc3-core/arch/i386/kernel/cpu/intel_htmc.c
--- linux-2.6.14-rc3/arch/i386/kernel/cpu/intel_htmc.c 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.6.14-rc3-core/arch/i386/kernel/cpu/intel_htmc.c 2005-10-04 17:27:28.438095888 -0700
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2005 Intel Corp
+ * Intel Multi Core and Hyper-Threading detection routines
+ *
+ * Changes:
+ * Suresh Siddha : Merge x86 and x86_64 code with some fixes.
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+
+#include <linux/smp.h>
+#include <asm/processor.h>
+
+
+/*
+ * find out the number of processor cores on the die
+ */
+int __cpuinit intel_num_cpu_cores(struct cpuinfo_x86 *c)
+{
+ unsigned int eax, ebx, ecx, edx;
+
+ if (c->cpuid_level < 4)
+ return 1;
+
+ cpuid_count(4, 0, &eax, &ebx, &ecx, &edx);
+
+ if (eax & 0x1f)
+ return ((eax >> 26) + 1);
+ else
+ return 1;
+}
+
+#ifdef CONFIG_X86_HT
+#ifndef CONFIG_X86_64
+#include <mach_apic.h>
+#else
+#include <asm/mach_apic.h>
+#endif
+void __cpuinit detect_ht(struct cpuinfo_x86 *c)
+{
+ u32 eax, ebx, ecx, edx;
+ int index_msb, core_bits;
+ int cpu = smp_processor_id();
+
+ cpuid(1, &eax, &ebx, &ecx, &edx);
+#ifdef CONFIG_X86_64
+ c->apicid = phys_pkg_id(0);
+#else
+ c->apicid = phys_pkg_id((ebx >> 24) & 0xFF, 0);
+#endif
+
+ if (!cpu_has(c, X86_FEATURE_HT) || cpu_has(c, X86_FEATURE_CMP_LEGACY))
+ return;
+
+ smp_num_siblings = (ebx & 0xff0000) >> 16;
+
+ if (smp_num_siblings == 1) {
+ printk(KERN_INFO "CPU: Hyper-Threading is disabled\n");
+ } else if (smp_num_siblings > 1 ) {
+
+ if (smp_num_siblings > NR_CPUS) {
+ printk(KERN_WARNING "CPU: Unsupported number of the siblings %d", smp_num_siblings);
+ smp_num_siblings = 1;
+ return;
+ }
+
+ index_msb = get_count_order(smp_num_siblings);
+#ifdef CONFIG_X86_64
+ phys_proc_id[cpu] = phys_pkg_id(index_msb);
+#else
+ phys_proc_id[cpu] = phys_pkg_id((ebx >> 24) & 0xFF, index_msb);
+#endif
+
+ printk(KERN_INFO "CPU: Physical Processor ID: %d\n",
+ phys_proc_id[cpu]);
+
+ smp_num_siblings = smp_num_siblings / c->x86_num_cores;
+
+ index_msb = get_count_order(smp_num_siblings) ;
+
+ core_bits = get_count_order(c->x86_num_cores);
+
+#ifdef CONFIG_X86_64
+ cpu_core_id[cpu] = phys_pkg_id(index_msb) &
+ ((1 << core_bits) - 1);
+#else
+ cpu_core_id[cpu] = phys_pkg_id((ebx >> 24) & 0xFF, index_msb) &
+ ((1 << core_bits) - 1);
+#endif
+
+ if (c->x86_num_cores > 1)
+ printk(KERN_INFO "CPU: Processor Core ID: %d\n",
+ cpu_core_id[cpu]);
+ }
+}
+#endif
diff -pNru linux-2.6.14-rc3/arch/i386/kernel/cpu/proc.c linux-2.6.14-rc3-core/arch/i386/kernel/cpu/proc.c
--- linux-2.6.14-rc3/arch/i386/kernel/cpu/proc.c 2005-09-30 14:17:35.000000000 -0700
+++ linux-2.6.14-rc3-core/arch/i386/kernel/cpu/proc.c 2005-10-04 17:27:28.439095736 -0700
@@ -97,9 +97,9 @@ static int show_cpuinfo(struct seq_file
if (c->x86_num_cores * smp_num_siblings > 1) {
seq_printf(m, "physical id\t: %d\n", phys_proc_id[n]);
seq_printf(m, "siblings\t: %d\n",
- c->x86_num_cores * smp_num_siblings);
+ cpus_weight(cpu_core_map[n]));
seq_printf(m, "core id\t\t: %d\n", cpu_core_id[n]);
- seq_printf(m, "cpu cores\t: %d\n", c->x86_num_cores);
+ seq_printf(m, "cpu cores\t: %d\n", c->booted_cores);
}
#endif
diff -pNru linux-2.6.14-rc3/arch/i386/kernel/sibling-map.c linux-2.6.14-rc3-core/arch/i386/kernel/sibling-map.c
--- linux-2.6.14-rc3/arch/i386/kernel/sibling-map.c 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.6.14-rc3-core/arch/i386/kernel/sibling-map.c 2005-10-04 17:27:28.439095736 -0700
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2005 Intel Corp
+ * Setup and Removal of various sibling maps
+ *
+ * Changes:
+ * Suresh Siddha : Merge x86 and x86_64 code with some fixes
+ */
+#include <linux/config.h>
+#include <linux/init.h>
+
+#include <linux/smp.h>
+
+static cpumask_t cpu_sibling_setup_map;
+
+#ifdef CONFIG_HOTPLUG_CPU
+void
+remove_siblinginfo(int cpu)
+{
+ int sibling;
+ struct cpuinfo_x86 *c = cpu_data;
+
+ for_each_cpu_mask(sibling, cpu_core_map[cpu]) {
+ cpu_clear(cpu, cpu_core_map[sibling]);
+ /*
+ * last thread sibling in this cpu core going down
+ */
+ if (cpus_weight(cpu_sibling_map[cpu]) == 1)
+ c[sibling].booted_cores--;
+ }
+
+ for_each_cpu_mask(sibling, cpu_sibling_map[cpu])
+ cpu_clear(cpu, cpu_sibling_map[sibling]);
+ cpus_clear(cpu_sibling_map[cpu]);
+ cpus_clear(cpu_core_map[cpu]);
+ phys_proc_id[cpu] = BAD_APICID;
+ cpu_core_id[cpu] = BAD_APICID;
+ cpu_clear(cpu, cpu_sibling_setup_map);
+}
+#endif
+
+void __cpuinit
+set_cpu_sibling_map(int cpu)
+{
+ int i;
+ struct cpuinfo_x86 *c = cpu_data;
+
+ cpu_set(cpu, cpu_sibling_setup_map);
+
+ if (smp_num_siblings > 1) {
+ for_each_cpu_mask(i, cpu_sibling_setup_map) {
+ if (phys_proc_id[cpu] == phys_proc_id[i] &&
+ cpu_core_id[cpu] == cpu_core_id[i]) {
+ cpu_set(i, cpu_sibling_map[cpu]);
+ cpu_set(cpu, cpu_sibling_map[i]);
+ cpu_set(i, cpu_core_map[cpu]);
+ cpu_set(cpu, cpu_core_map[i]);
+ }
+ }
+ } else {
+ cpu_set(cpu, cpu_sibling_map[cpu]);
+ }
+
+ if (current_cpu_data.x86_num_cores == 1) {
+ cpu_core_map[cpu] = cpu_sibling_map[cpu];
+ c[cpu].booted_cores = 1;
+ return;
+ }
+
+ for_each_cpu_mask(i, cpu_sibling_setup_map) {
+ if (phys_proc_id[cpu] == phys_proc_id[i]) {
+ cpu_set(i, cpu_core_map[cpu]);
+ cpu_set(cpu, cpu_core_map[i]);
+ /*
+ * Does this new cpu bringup a new core?
+ */
+ if (cpus_weight(cpu_sibling_map[cpu]) == 1) {
+ /*
+ * for each core in package, increment
+ * the booted_cores for this new cpu
+ */
+ if (first_cpu(cpu_sibling_map[i]) == i)
+ c[cpu].booted_cores++;
+ /*
+ * increment the core count for all
+ * the other cpus in this package
+ */
+ if (i != cpu)
+ c[i].booted_cores++;
+ } else if (i != cpu && !c[cpu].booted_cores)
+ c[cpu].booted_cores = c[i].booted_cores;
+ }
+ }
+}
diff -pNru linux-2.6.14-rc3/arch/i386/kernel/smpboot.c linux-2.6.14-rc3-core/arch/i386/kernel/smpboot.c
--- linux-2.6.14-rc3/arch/i386/kernel/smpboot.c 2005-09-30 14:17:35.000000000 -0700
+++ linux-2.6.14-rc3-core/arch/i386/kernel/smpboot.c 2005-10-05 15:23:37.137028880 -0700
@@ -440,38 +440,6 @@ static void __devinit smp_callin(void)
static int cpucount;
-static inline void
-set_cpu_sibling_map(int cpu)
-{
- int i;
-
- if (smp_num_siblings > 1) {
- for (i = 0; i < NR_CPUS; i++) {
- if (!cpu_isset(i, cpu_callout_map))
- continue;
- if (cpu_core_id[cpu] == cpu_core_id[i]) {
- cpu_set(i, cpu_sibling_map[cpu]);
- cpu_set(cpu, cpu_sibling_map[i]);
- }
- }
- } else {
- cpu_set(cpu, cpu_sibling_map[cpu]);
- }
-
- if (current_cpu_data.x86_num_cores > 1) {
- for (i = 0; i < NR_CPUS; i++) {
- if (!cpu_isset(i, cpu_callout_map))
- continue;
- if (phys_proc_id[cpu] == phys_proc_id[i]) {
- cpu_set(i, cpu_core_map[cpu]);
- cpu_set(cpu, cpu_core_map[i]);
- }
- }
- } else {
- cpu_core_map[cpu] = cpu_sibling_map[cpu];
- }
-}
-
/*
* Activate a secondary processor.
*/
@@ -1092,11 +1060,7 @@ static void __init smp_boot_cpus(unsigne
current_thread_info()->cpu = 0;
smp_tune_scheduling();
- cpus_clear(cpu_sibling_map[0]);
- cpu_set(0, cpu_sibling_map[0]);
-
- cpus_clear(cpu_core_map[0]);
- cpu_set(0, cpu_core_map[0]);
+ set_cpu_sibling_map(raw_smp_processor_id());
/*
* If we couldn't find an SMP configuration at boot time,
@@ -1271,21 +1235,6 @@ void __devinit smp_prepare_boot_cpu(void
}
#ifdef CONFIG_HOTPLUG_CPU
-static void
-remove_siblinginfo(int cpu)
-{
- int sibling;
-
- for_each_cpu_mask(sibling, cpu_sibling_map[cpu])
- cpu_clear(cpu, cpu_sibling_map[sibling]);
- for_each_cpu_mask(sibling, cpu_core_map[cpu])
- cpu_clear(cpu, cpu_core_map[sibling]);
- cpus_clear(cpu_sibling_map[cpu]);
- cpus_clear(cpu_core_map[cpu]);
- phys_proc_id[cpu] = BAD_APICID;
- cpu_core_id[cpu] = BAD_APICID;
-}
-
int __cpu_disable(void)
{
cpumask_t map = cpu_online_map;
diff -pNru linux-2.6.14-rc3/arch/x86_64/kernel/Makefile linux-2.6.14-rc3-core/arch/x86_64/kernel/Makefile
--- linux-2.6.14-rc3/arch/x86_64/kernel/Makefile 2005-09-30 14:17:35.000000000 -0700
+++ linux-2.6.14-rc3-core/arch/x86_64/kernel/Makefile 2005-10-04 17:27:28.440095584 -0700
@@ -16,7 +16,7 @@ obj-$(CONFIG_ACPI) += acpi/
obj-$(CONFIG_X86_MSR) += msr.o
obj-$(CONFIG_MICROCODE) += microcode.o
obj-$(CONFIG_X86_CPUID) += cpuid.o
-obj-$(CONFIG_SMP) += smp.o smpboot.o trampoline.o
+obj-$(CONFIG_SMP) += smp.o smpboot.o trampoline.o sibling-map.o
obj-$(CONFIG_X86_LOCAL_APIC) += apic.o nmi.o
obj-$(CONFIG_X86_IO_APIC) += io_apic.o mpparse.o \
genapic.o genapic_cluster.o genapic_flat.o
@@ -34,7 +34,7 @@ obj-$(CONFIG_X86_PM_TIMER) += pmtimer.o
obj-$(CONFIG_MODULES) += module.o
obj-y += topology.o
-obj-y += intel_cacheinfo.o
+obj-y += intel_cacheinfo.o intel_htmc.o
CFLAGS_vsyscall.o := $(PROFILING) -g0
@@ -47,3 +47,5 @@ intel_cacheinfo-y += ../../i386/kernel/
quirks-y += ../../i386/kernel/quirks.o
i8237-y += ../../i386/kernel/i8237.o
msr-$(subst m,y,$(CONFIG_X86_MSR)) += ../../i386/kernel/msr.o
+sibling-map-y += ../../i386/kernel/sibling-map.o
+intel_htmc-y += ../../i386/kernel/cpu/intel_htmc.o
diff -pNru linux-2.6.14-rc3/arch/x86_64/kernel/setup.c linux-2.6.14-rc3-core/arch/x86_64/kernel/setup.c
--- linux-2.6.14-rc3/arch/x86_64/kernel/setup.c 2005-09-30 14:17:35.000000000 -0700
+++ linux-2.6.14-rc3-core/arch/x86_64/kernel/setup.c 2005-10-04 17:27:28.441095432 -0700
@@ -885,85 +885,6 @@ static int __init init_amd(struct cpuinf
return r;
}
-static void __cpuinit detect_ht(struct cpuinfo_x86 *c)
-{
-#ifdef CONFIG_SMP
- u32 eax, ebx, ecx, edx;
- int index_msb, tmp;
- int cpu = smp_processor_id();
-
- if (!cpu_has(c, X86_FEATURE_HT) || cpu_has(c, X86_FEATURE_CMP_LEGACY))
- return;
-
- cpuid(1, &eax, &ebx, &ecx, &edx);
- smp_num_siblings = (ebx & 0xff0000) >> 16;
-
- if (smp_num_siblings == 1) {
- printk(KERN_INFO "CPU: Hyper-Threading is disabled\n");
- } else if (smp_num_siblings > 1) {
- index_msb = 31;
- /*
- * At this point we only support two siblings per
- * processor package.
- */
- if (smp_num_siblings > NR_CPUS) {
- printk(KERN_WARNING "CPU: Unsupported number of the siblings %d", smp_num_siblings);
- smp_num_siblings = 1;
- return;
- }
- tmp = smp_num_siblings;
- while ((tmp & 0x80000000 ) == 0) {
- tmp <<=1 ;
- index_msb--;
- }
- if (smp_num_siblings & (smp_num_siblings - 1))
- index_msb++;
- phys_proc_id[cpu] = phys_pkg_id(index_msb);
-
- printk(KERN_INFO "CPU: Physical Processor ID: %d\n",
- phys_proc_id[cpu]);
-
- smp_num_siblings = smp_num_siblings / c->x86_num_cores;
-
- tmp = smp_num_siblings;
- index_msb = 31;
- while ((tmp & 0x80000000) == 0) {
- tmp <<=1 ;
- index_msb--;
- }
- if (smp_num_siblings & (smp_num_siblings - 1))
- index_msb++;
-
- cpu_core_id[cpu] = phys_pkg_id(index_msb);
-
- if (c->x86_num_cores > 1)
- printk(KERN_INFO "CPU: Processor Core ID: %d\n",
- cpu_core_id[cpu]);
- }
-#endif
-}
-
-/*
- * find out the number of processor cores on the die
- */
-static int __cpuinit intel_num_cpu_cores(struct cpuinfo_x86 *c)
-{
- unsigned int eax;
-
- if (c->cpuid_level < 4)
- return 1;
-
- __asm__("cpuid"
- : "=a" (eax)
- : "0" (4), "c" (0)
- : "bx", "dx");
-
- if (eax & 0x1f)
- return ((eax >> 26) + 1);
- else
- return 1;
-}
-
static void srat_detect_node(void)
{
#ifdef CONFIG_NUMA
@@ -1276,9 +1197,9 @@ static int show_cpuinfo(struct seq_file
int cpu = c - cpu_data;
seq_printf(m, "physical id\t: %d\n", phys_proc_id[cpu]);
seq_printf(m, "siblings\t: %d\n",
- c->x86_num_cores * smp_num_siblings);
+ cpus_weight(cpu_core_map[cpu]));
seq_printf(m, "core id\t\t: %d\n", cpu_core_id[cpu]);
- seq_printf(m, "cpu cores\t: %d\n", c->x86_num_cores);
+ seq_printf(m, "cpu cores\t: %d\n", c->booted_cores);
}
#endif
diff -pNru linux-2.6.14-rc3/arch/x86_64/kernel/smpboot.c linux-2.6.14-rc3-core/arch/x86_64/kernel/smpboot.c
--- linux-2.6.14-rc3/arch/x86_64/kernel/smpboot.c 2005-09-30 14:17:35.000000000 -0700
+++ linux-2.6.14-rc3-core/arch/x86_64/kernel/smpboot.c 2005-10-04 17:27:28.442095280 -0700
@@ -436,33 +436,6 @@ void __cpuinit smp_callin(void)
cpu_set(cpuid, cpu_callin_map);
}
-static inline void set_cpu_sibling_map(int cpu)
-{
- int i;
-
- if (smp_num_siblings > 1) {
- for_each_cpu(i) {
- if (cpu_core_id[cpu] == cpu_core_id[i]) {
- cpu_set(i, cpu_sibling_map[cpu]);
- cpu_set(cpu, cpu_sibling_map[i]);
- }
- }
- } else {
- cpu_set(cpu, cpu_sibling_map[cpu]);
- }
-
- if (current_cpu_data.x86_num_cores > 1) {
- for_each_cpu(i) {
- if (phys_proc_id[cpu] == phys_proc_id[i]) {
- cpu_set(i, cpu_core_map[cpu]);
- cpu_set(cpu, cpu_core_map[i]);
- }
- }
- } else {
- cpu_core_map[cpu] = cpu_sibling_map[cpu];
- }
-}
-
/*
* Setup code on secondary processor (after comming out of the trampoline)
*/
@@ -966,6 +939,7 @@ void __init smp_prepare_cpus(unsigned in
nmi_watchdog_default();
current_cpu_data = boot_cpu_data;
current_thread_info()->cpu = 0; /* needed? */
+ set_cpu_sibling_map(0);
#ifdef CONFIG_HOTPLUG_CPU
prefill_possible_map();
@@ -1013,8 +987,7 @@ void __init smp_prepare_boot_cpu(void)
int me = smp_processor_id();
cpu_set(me, cpu_online_map);
cpu_set(me, cpu_callout_map);
- cpu_set(0, cpu_sibling_map[0]);
- cpu_set(0, cpu_core_map[0]);
+
per_cpu(cpu_state, me) = CPU_ONLINE;
}
@@ -1083,20 +1056,6 @@ void __init smp_cpus_done(unsigned int m
#ifdef CONFIG_HOTPLUG_CPU
-static void remove_siblinginfo(int cpu)
-{
- int sibling;
-
- for_each_cpu_mask(sibling, cpu_sibling_map[cpu])
- cpu_clear(cpu, cpu_sibling_map[sibling]);
- for_each_cpu_mask(sibling, cpu_core_map[cpu])
- cpu_clear(cpu, cpu_core_map[sibling]);
- cpus_clear(cpu_sibling_map[cpu]);
- cpus_clear(cpu_core_map[cpu]);
- phys_proc_id[cpu] = BAD_APICID;
- cpu_core_id[cpu] = BAD_APICID;
-}
-
void remove_cpu_from_maps(void)
{
int cpu = smp_processor_id();
diff -pNru linux-2.6.14-rc3/include/asm-i386/processor.h linux-2.6.14-rc3-core/include/asm-i386/processor.h
--- linux-2.6.14-rc3/include/asm-i386/processor.h 2005-09-30 14:17:35.000000000 -0700
+++ linux-2.6.14-rc3-core/include/asm-i386/processor.h 2005-10-04 17:27:28.443095128 -0700
@@ -66,6 +66,8 @@ struct cpuinfo_x86 {
int coma_bug;
unsigned long loops_per_jiffy;
unsigned char x86_num_cores;
+ unsigned char booted_cores;
+ unsigned char apicid;
} __attribute__((__aligned__(SMP_CACHE_BYTES)));
#define X86_VENDOR_INTEL 0
@@ -104,6 +106,7 @@ extern char ignore_fpu_irq;
extern void identify_cpu(struct cpuinfo_x86 *);
extern void print_cpu_info(struct cpuinfo_x86 *);
extern unsigned int init_intel_cacheinfo(struct cpuinfo_x86 *c);
+extern int intel_num_cpu_cores(struct cpuinfo_x86 *c);
#ifdef CONFIG_X86_HT
extern void detect_ht(struct cpuinfo_x86 *c);
diff -pNru linux-2.6.14-rc3/include/asm-i386/smp.h linux-2.6.14-rc3-core/include/asm-i386/smp.h
--- linux-2.6.14-rc3/include/asm-i386/smp.h 2005-09-30 14:17:35.000000000 -0700
+++ linux-2.6.14-rc3-core/include/asm-i386/smp.h 2005-10-05 15:24:59.695478088 -0700
@@ -37,6 +37,9 @@ extern int smp_num_siblings;
extern cpumask_t cpu_sibling_map[];
extern cpumask_t cpu_core_map[];
+extern void set_cpu_sibling_map(int);
+extern void remove_siblinginfo(int);
+
extern void (*mtrr_hook) (void);
extern void zap_low_mappings (void);
extern void lock_ipi_call_lock(void);
diff -pNru linux-2.6.14-rc3/include/asm-x86_64/processor.h linux-2.6.14-rc3-core/include/asm-x86_64/processor.h
--- linux-2.6.14-rc3/include/asm-x86_64/processor.h 2005-09-30 14:17:35.000000000 -0700
+++ linux-2.6.14-rc3-core/include/asm-x86_64/processor.h 2005-10-04 17:27:28.443095128 -0700
@@ -65,6 +65,8 @@ struct cpuinfo_x86 {
__u32 x86_power;
__u32 extended_cpuid_level; /* Max extended CPUID function supported */
unsigned long loops_per_jiffy;
+ __u8 apicid;
+ __u8 booted_cores;
} ____cacheline_aligned;
#define X86_VENDOR_INTEL 0
@@ -91,6 +93,14 @@ extern char ignore_irq13;
extern void identify_cpu(struct cpuinfo_x86 *);
extern void print_cpu_info(struct cpuinfo_x86 *);
extern unsigned int init_intel_cacheinfo(struct cpuinfo_x86 *c);
+extern int intel_num_cpu_cores(struct cpuinfo_x86 *c);
+
+#ifdef CONFIG_X86_HT
+extern void detect_ht(struct cpuinfo_x86 *c);
+#else
+static inline void detect_ht(struct cpuinfo_x86 *c) {}
+#endif
+
/*
* EFLAGS bits
diff -pNru linux-2.6.14-rc3/include/asm-x86_64/smp.h linux-2.6.14-rc3-core/include/asm-x86_64/smp.h
--- linux-2.6.14-rc3/include/asm-x86_64/smp.h 2005-09-30 14:17:35.000000000 -0700
+++ linux-2.6.14-rc3-core/include/asm-x86_64/smp.h 2005-10-04 17:27:28.444094976 -0700
@@ -57,6 +57,9 @@ extern cpumask_t cpu_core_map[NR_CPUS];
extern u8 phys_proc_id[NR_CPUS];
extern u8 cpu_core_id[NR_CPUS];
+extern void set_cpu_sibling_map(int);
+extern void remove_siblinginfo(int);
+
#define SMP_TRAMPOLINE_BASE 0x6000
/*
diff -pNru linux-2.6.14-rc3/include/linux/bitops.h linux-2.6.14-rc3-core/include/linux/bitops.h
--- linux-2.6.14-rc3/include/linux/bitops.h 2005-09-30 14:17:35.000000000 -0700
+++ linux-2.6.14-rc3-core/include/linux/bitops.h 2005-10-04 17:27:28.444094976 -0700
@@ -84,6 +84,16 @@ static __inline__ int get_bitmask_order(
return order; /* We could be slightly more clever with -1 here... */
}
+static __inline__ int get_count_order(unsigned int count)
+{
+ int order;
+
+ order = fls(count) - 1;
+ if (count & (count - 1))
+ order++;
+ return order;
+}
+
/*
* hweightN: returns the hamming weight (i.e. the number
* of bits set) of a N-bit word
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[Index of Archives]
[Kernel Newbies]
[Netfilter]
[Bugtraq]
[Photo]
[Stuff]
[Gimp]
[Yosemite News]
[MIPS Linux]
[ARM Linux]
[Linux Security]
[Linux RAID]
[Video 4 Linux]
[Linux for the blind]
[Linux Resources]