x86/amd: Fix L1i and L2 cache sharing information for AMD family 15h processors
PATCH 1/1 x86/amd: Fix L1i and L2 cache sharing information for AMD family 15h processors
For L1 instruction cache and L2 cache the shared CPU information is wrong. On current AMD family 15h CPUs those caches are shared between both cores of a compute unit.
This fixes https://bugzilla.kernel.org/show_bug.cgi?id=42607
--- arch/x86/kernel/cpu/intel_cacheinfo.c | 45 +++++++++++++++++++++++++++----- 1 files changed, 38 insertions(+), 7 deletions(-)
arch/x86/kernel/cpu/intel_cacheinfo.c +38 -7
@@ -725,14 +725,16 @@ static DEFINE_PER_CPU(struct _cpuid4_info *, ici_cpuid4_info);#define CPUID4_INFO_IDX (x, y) (&((per_cpu(ici_cpuid4_info, x))[y]))#ifdef CONFIG_SMP -static void __cpuinit cache_shared_cpu_map_setup (unsigned int cpu,int index) + +static int __cpuinit cache_shared_amd_cpu_map_setup (unsigned int cpu,int index) { -struct _cpuid4_info *this_leaf, *sibling_leaf; -unsigned long num_threads_sharing; -int index_msb, i, sibling; +struct _cpuid4_info *this_leaf; +int ret, i, sibling;struct cpuinfo_x86 *c = &cpu_data (cpu); -if ((index ==3 ) && (c->x86_vendor ==X86_VENDOR_AMD )) { + ret =0 ; +if (index ==3 ) { + ret =1 ;for_each_cpu (i,cpu_llc_shared_mask (cpu)) {if (!per_cpu (ici_cpuid4_info, i))continue ;
@@ -740,11 +742,40 @@ static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index)for_each_cpu (sibling,cpu_llc_shared_mask (cpu)) {if (!cpu_online (sibling))continue ; -set_bit (sibling, this_leaf->shared_cpu_map); +set_bit (sibling, + this_leaf->shared_cpu_map); + } + } + }else if ((c->x86 ==0x15 ) && ((index ==1 ) || (index ==2 ))) { + ret =1 ; +for_each_cpu (i,cpu_sibling_mask (cpu)) { +if (!per_cpu (ici_cpuid4_info, i)) +continue ; + this_leaf =CPUID4_INFO_IDX (i, index); +for_each_cpu (sibling,cpu_sibling_mask (cpu)) { +if (!cpu_online (sibling)) +continue ; +set_bit (sibling, + this_leaf->shared_cpu_map); } } -return ; } + +return ret; +} + +static void __cpuinit cache_shared_cpu_map_setup (unsigned int cpu,int index) +{ +struct _cpuid4_info *this_leaf, *sibling_leaf; +unsigned long num_threads_sharing; +int index_msb, i; +struct cpuinfo_x86 *c = &cpu_data (cpu); + +if (c->x86_vendor ==X86_VENDOR_AMD ) { +if (cache_shared_amd_cpu_map_setup (cpu, index)) +return ; + } + this_leaf =CPUID4_INFO_IDX (cpu, index); num_threads_sharing =1 + this_leaf->base.eax.split.num_threads_sharing;
Signature · 1 line
1.7.8.3
Commit-ID: 32c3233885eb10ac9cb9410f2f8cd64b8df2b2a1 Gitweb: http://git.kernel.org/tip/32c3233885eb10ac9cb9410f2f8cd64b8df2b2a1 Author: Andreas Herrmann <[email protected]> AuthorDate: Wed, 8 Feb 2012 20:52:29 +0100 Committer: Ingo Molnar <[email protected]> CommitDate: Thu, 9 Feb 2012 09:38:15 +0100
x86/amd: Fix L1i and L2 cache sharing information for AMD family 15h processors
For L1 instruction cache and L2 cache the shared CPU information is wrong. On current AMD family 15h CPUs those caches are shared between both cores of a compute unit.
This fixes https://bugzilla.kernel.org/show_bug.cgi?id=42607
--- arch/x86/kernel/cpu/intel_cacheinfo.c | 44 +++++++++++++++++++++++++++------ 1 files changed, 36 insertions(+), 8 deletions(-)
arch/x86/kernel/cpu/intel_cacheinfo.c +36 -8
@@ -326,8 +326,7 @@ static void __cpuinit amd_calc_l3_indices(struct amd_northbridge *nb) l3->indices = (max (max3 (sc0, sc1, sc2), sc3) <<10 ) -1 ; } -static void __cpuinit amd_init_l3_cache (struct _cpuid4_info_regs *this_leaf, -int index) +static void __cpuinit amd_init_l3_cache (struct _cpuid4_info_regs *this_leaf,int index) {int node;
@@ -725,14 +724,16 @@ static DEFINE_PER_CPU(struct _cpuid4_info *, ici_cpuid4_info);#define CPUID4_INFO_IDX (x, y) (&((per_cpu(ici_cpuid4_info, x))[y]))#ifdef CONFIG_SMP -static void __cpuinit cache_shared_cpu_map_setup (unsigned int cpu,int index) + +static int __cpuinit cache_shared_amd_cpu_map_setup (unsigned int cpu,int index) { -struct _cpuid4_info *this_leaf, *sibling_leaf; -unsigned long num_threads_sharing; -int index_msb, i, sibling; +struct _cpuid4_info *this_leaf; +int ret, i, sibling;struct cpuinfo_x86 *c = &cpu_data (cpu); -if ((index ==3 ) && (c->x86_vendor ==X86_VENDOR_AMD )) { + ret =0 ; +if (index ==3 ) { + ret =1 ;for_each_cpu (i,cpu_llc_shared_mask (cpu)) {if (!per_cpu (ici_cpuid4_info, i))continue ;
@@ -743,8 +744,35 @@ static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index)set_bit (sibling, this_leaf->shared_cpu_map); } } -return ; + }else if ((c->x86 ==0x15 ) && ((index ==1 ) || (index ==2 ))) { + ret =1 ; +for_each_cpu (i,cpu_sibling_mask (cpu)) { +if (!per_cpu (ici_cpuid4_info, i)) +continue ; + this_leaf =CPUID4_INFO_IDX (i, index); +for_each_cpu (sibling,cpu_sibling_mask (cpu)) { +if (!cpu_online (sibling)) +continue ; +set_bit (sibling, this_leaf->shared_cpu_map); + } + } } + +return ret; +} + +static void __cpuinit cache_shared_cpu_map_setup (unsigned int cpu,int index) +{ +struct _cpuid4_info *this_leaf, *sibling_leaf; +unsigned long num_threads_sharing; +int index_msb, i; +struct cpuinfo_x86 *c = &cpu_data (cpu); + +if (c->x86_vendor ==X86_VENDOR_AMD ) { +if (cache_shared_amd_cpu_map_setup (cpu, index)) +return ; + } + this_leaf =CPUID4_INFO_IDX (cpu, index); num_threads_sharing =1 + this_leaf->base.eax.split.num_threads_sharing;
This commit seems to cause a boot hang on an old Athlon64 CPU:
CPU: Physical Processor ID: 0
CPU: Processor Core ID: 0numa_add_cpu cpu 0 node 0: mask now 0
ExtINT not setup in hardware but reported by MP table ..TIMER: vector=0x30 apic1=0 pin1=2 apic2=0 pin2=0 ..MP-BIOS bug: 8254 timer not connected to IO-APIC ...trying to set up timer (IRQ0) through the 8259A ... ..... (found apic 0 pin 0) ...
....... works.
CPU0: AMD Athlon(tm) 64 X2 Dual Core Processor 3800+ stepping 02
Thanks,
Ingo
Quoted 2 lines · Ingo Molnar
This commit seems to cause a boot hang on an old Athlon64 CPU:
Are you sure that it's this commit, or is it possible that some other patch in tip might trigger the trouble? (Systems boots fine with this patch reverted?)
Quoted 10 lines
CPU: Physical Processor ID: 0
CPU: Processor Core ID: 0numa_add_cpucpu 0 node 0: mask now 0
ExtINT not setup in hardware but reported by MP table ..TIMER: vector=0x30 apic1=0 pin1=2 apic2=0 pin2=0 ..MP-BIOS bug: 8254 timer not connected to IO-APIC ...trying to set up timer (IRQ0) through the 8259A ... ..... (found apic 0 pin 0) ...
....... works.
CPU0: AMD Athlon(tm) 64 X2 Dual Core Processor 3800+ stepping 02
Can't reproduce this here (tried it on a couple of further systems). Can you please provide dmesg or at least /proc/cpuinfo output? (Also at the moment, it's not obvious to me how this timer interrupt trouble is related to this patch.)
Thanks,
Andreas
Quoted 7 lines · Andreas Herrmann
Quoted 2 lines · Ingo Molnar
This commit seems to cause a boot hang on an old Athlon64 CPU:
Are you sure that it's this commit, or is it possible that some other patch in tip might trigger the trouble? (Systems boots fine with this patch reverted?)
You are right, it's not this commit after all, but probably some other recent commit. I'll bisect it.
Thanks,
Ingo