aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYazen Ghannam <Yazen.Ghannam@amd.com>2016-11-08 10:30:54 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-01-19 14:18:01 -0500
commite2d9ad2c540bf15958812189700a812110b452bf (patch)
treef955c5133de6be62c8676f16deae04582065614c
parent259495a0440f6b8025277171d7becb8b92cece82 (diff)
x86/cpu/AMD: Clean up cpu_llc_id assignment per topology feature
commit b6a50cddbcbda7105355898ead18f1a647c22520 upstream. These changes do not affect current hw - just a cleanup: Currently, we assume that a system has a single Last Level Cache (LLC) per node, and that the cpu_llc_id is thus equal to the node_id. This no longer applies since Fam17h can have multiple last level caches within a node. So group the cpu_llc_id assignment by topology feature and family in order to make the computation of cpu_llc_id on the different families more clear. Here is how the LLC ID is being computed on the different families: The NODEID_MSR feature only applies to Fam10h in which case the LLC is at the node level. The TOPOEXT feature is used on families 15h, 16h and 17h. So far we only see multiple last level caches if L3 caches are available. Otherwise, the cpu_llc_id will default to be the phys_proc_id. We have L3 caches only on families 15h and 17h: - on Fam15h, the LLC is at the node level. - on Fam17h, the LLC is at the core complex level and can be found by right shifting the APIC ID. Also, keep the family checks explicit so that new families will fall back to the default, which will be node_id for TOPOEXT systems. Single node systems in families 10h and 15h will have a Node ID of 0 which will be the same as the phys_proc_id, so we don't need to check for multiple nodes before using the node_id. Tested-by: Borislav Petkov <bp@suse.de> Signed-off-by: Yazen Ghannam <Yazen.Ghannam@amd.com> [ Rewrote the commit message. ] Signed-off-by: Borislav Petkov <bp@suse.de> Acked-by: Thomas Gleixner <tglx@linutronix.de> Cc: Aravind Gopalakrishnan <aravindksg.lkml@gmail.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Peter Zijlstra <peterz@infradead.org> Link: http://lkml.kernel.org/r/20161108153054.bs3sajbyevq6a6uu@pd.tnic Signed-off-by: Ingo Molnar <mingo@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--arch/x86/kernel/cpu/amd.c31
1 files changed, 19 insertions, 12 deletions
diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c
index 1e81a37c034e..4daad1e39352 100644
--- a/arch/x86/kernel/cpu/amd.c
+++ b/arch/x86/kernel/cpu/amd.c
@@ -314,11 +314,30 @@ static void amd_get_topology(struct cpuinfo_x86 *c)
314 smp_num_siblings = ((ebx >> 8) & 3) + 1; 314 smp_num_siblings = ((ebx >> 8) & 3) + 1;
315 c->x86_max_cores /= smp_num_siblings; 315 c->x86_max_cores /= smp_num_siblings;
316 c->cpu_core_id = ebx & 0xff; 316 c->cpu_core_id = ebx & 0xff;
317
318 /*
319 * We may have multiple LLCs if L3 caches exist, so check if we
320 * have an L3 cache by looking at the L3 cache CPUID leaf.
321 */
322 if (cpuid_edx(0x80000006)) {
323 if (c->x86 == 0x17) {
324 /*
325 * LLC is at the core complex level.
326 * Core complex id is ApicId[3].
327 */
328 per_cpu(cpu_llc_id, cpu) = c->apicid >> 3;
329 } else {
330 /* LLC is at the node level. */
331 per_cpu(cpu_llc_id, cpu) = node_id;
332 }
333 }
317 } else if (cpu_has(c, X86_FEATURE_NODEID_MSR)) { 334 } else if (cpu_has(c, X86_FEATURE_NODEID_MSR)) {
318 u64 value; 335 u64 value;
319 336
320 rdmsrl(MSR_FAM10H_NODE_ID, value); 337 rdmsrl(MSR_FAM10H_NODE_ID, value);
321 node_id = value & 7; 338 node_id = value & 7;
339
340 per_cpu(cpu_llc_id, cpu) = node_id;
322 } else 341 } else
323 return; 342 return;
324 343
@@ -329,9 +348,6 @@ static void amd_get_topology(struct cpuinfo_x86 *c)
329 set_cpu_cap(c, X86_FEATURE_AMD_DCM); 348 set_cpu_cap(c, X86_FEATURE_AMD_DCM);
330 cus_per_node = c->x86_max_cores / nodes_per_socket; 349 cus_per_node = c->x86_max_cores / nodes_per_socket;
331 350
332 /* store NodeID, use llc_shared_map to store sibling info */
333 per_cpu(cpu_llc_id, cpu) = node_id;
334
335 /* core id has to be in the [0 .. cores_per_node - 1] range */ 351 /* core id has to be in the [0 .. cores_per_node - 1] range */
336 c->cpu_core_id %= cus_per_node; 352 c->cpu_core_id %= cus_per_node;
337 } 353 }
@@ -356,15 +372,6 @@ static void amd_detect_cmp(struct cpuinfo_x86 *c)
356 /* use socket ID also for last level cache */ 372 /* use socket ID also for last level cache */
357 per_cpu(cpu_llc_id, cpu) = c->phys_proc_id; 373 per_cpu(cpu_llc_id, cpu) = c->phys_proc_id;
358 amd_get_topology(c); 374 amd_get_topology(c);
359
360 /*
361 * Fix percpu cpu_llc_id here as LLC topology is different
362 * for Fam17h systems.
363 */
364 if (c->x86 != 0x17 || !cpuid_edx(0x80000006))
365 return;
366
367 per_cpu(cpu_llc_id, cpu) = c->apicid >> 3;
368#endif 375#endif
369} 376}
370 377