From 3dd9d514846cdca1dcef2e4fce666d85e199e844 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Sat, 16 Apr 2005 15:25:15 -0700 Subject: [PATCH] x86_64: add support for Intel dual-core detection and displaying Appended patch adds the support for Intel dual-core detection and displaying the core related information in /proc/cpuinfo. It adds two new fields "core id" and "cpu cores" to x86 /proc/cpuinfo and the "core id" field for x86_64("cpu cores" field is already present in x86_64). Number of processor cores in a die is detected using cpuid(4) and this is documented in IA-32 Intel Architecture Software Developer's Manual (vol 2a) (http://developer.intel.com/design/pentium4/manuals/index_new.htm#sdm_vol2a) This patch also adds cpu_core_map similar to cpu_sibling_map. Slightly hacked by AK. Signed-off-by: Suresh Siddha Signed-off-by: Andi Kleen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/x86_64/kernel/smpboot.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) (limited to 'arch/x86_64/kernel/smpboot.c') diff --git a/arch/x86_64/kernel/smpboot.c b/arch/x86_64/kernel/smpboot.c index e5714090b00d..7e2de8925b0f 100644 --- a/arch/x86_64/kernel/smpboot.c +++ b/arch/x86_64/kernel/smpboot.c @@ -58,7 +58,10 @@ int smp_num_siblings = 1; /* Package ID of each logical CPU */ u8 phys_proc_id[NR_CPUS] = { [0 ... NR_CPUS-1] = BAD_APICID }; +/* Core ID of each logical CPU */ +u8 cpu_core_id[NR_CPUS] = { [0 ... NR_CPUS-1] = BAD_APICID }; EXPORT_SYMBOL(phys_proc_id); +EXPORT_SYMBOL(cpu_core_id); /* Bitmask of currently online CPUs */ cpumask_t cpu_online_map; @@ -71,6 +74,7 @@ static cpumask_t smp_commenced_mask; struct cpuinfo_x86 cpu_data[NR_CPUS] __cacheline_aligned; cpumask_t cpu_sibling_map[NR_CPUS] __cacheline_aligned; +cpumask_t cpu_core_map[NR_CPUS] __cacheline_aligned; /* * Trampoline 80x86 program as an array. @@ -713,6 +717,7 @@ static void __init smp_boot_cpus(unsigned int max_cpus) io_apic_irqs = 0; cpu_online_map = cpumask_of_cpu(0); cpu_set(0, cpu_sibling_map[0]); + cpu_set(0, cpu_core_map[0]); phys_cpu_present_map = physid_mask_of_physid(0); if (APIC_init_uniprocessor()) printk(KERN_NOTICE "Local APIC not detected." @@ -740,6 +745,7 @@ static void __init smp_boot_cpus(unsigned int max_cpus) io_apic_irqs = 0; cpu_online_map = cpumask_of_cpu(0); cpu_set(0, cpu_sibling_map[0]); + cpu_set(0, cpu_core_map[0]); phys_cpu_present_map = physid_mask_of_physid(0); disable_apic = 1; goto smp_done; @@ -756,6 +762,7 @@ static void __init smp_boot_cpus(unsigned int max_cpus) io_apic_irqs = 0; cpu_online_map = cpumask_of_cpu(0); cpu_set(0, cpu_sibling_map[0]); + cpu_set(0, cpu_core_map[0]); phys_cpu_present_map = physid_mask_of_physid(0); disable_apic = 1; goto smp_done; @@ -833,10 +840,13 @@ static void __init smp_boot_cpus(unsigned int max_cpus) * Construct cpu_sibling_map[], so that we can tell the * sibling CPU efficiently. */ - for (cpu = 0; cpu < NR_CPUS; cpu++) + for (cpu = 0; cpu < NR_CPUS; cpu++) { cpus_clear(cpu_sibling_map[cpu]); + cpus_clear(cpu_core_map[cpu]); + } for (cpu = 0; cpu < NR_CPUS; cpu++) { + struct cpuinfo_x86 *c = cpu_data + cpu; int siblings = 0; int i; if (!cpu_isset(cpu, cpu_callout_map)) @@ -846,7 +856,7 @@ static void __init smp_boot_cpus(unsigned int max_cpus) for (i = 0; i < NR_CPUS; i++) { if (!cpu_isset(i, cpu_callout_map)) continue; - if (phys_proc_id[cpu] == phys_proc_id[i]) { + if (phys_proc_id[cpu] == cpu_core_id[i]) { siblings++; cpu_set(i, cpu_sibling_map[cpu]); } @@ -862,6 +872,16 @@ static void __init smp_boot_cpus(unsigned int max_cpus) siblings, cpu, smp_num_siblings); smp_num_siblings = siblings; } + if (c->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]); + } + } + } else + cpu_core_map[cpu] = cpu_sibling_map[cpu]; } Dprintk("Boot done.\n"); -- cgit v1.2.2