x86/resctrl: Fix AMD L3 QOS CDP enable/disable

When the AMD QoS feature CDP (code and data prioritization) is enabled
or disabled, the CDP bit in MSR 0000_0C81 is written on one of the CPUs
in an L3 domain (core complex). That is not correct - the CDP bit needs
to be updated on all the logical CPUs in the domain.

This was not spelled out clearly in the spec earlier. The specification
has been updated and the updated document, "AMD64 Technology Platform
Quality of Service Extensions Publication # 56375 Revision: 1.02 Issue
Date: October 2020" is available now. Refer the section: Code and Data
Prioritization.

Fix the issue by adding a new flag arch_has_per_cpu_cfg in rdt_cache
data structure.

The documentation can be obtained at:
https://developer.amd.com/wp-content/resources/56375.pdf
Link: https://bugzilla.kernel.org/show_bug.cgi?id=206537

 [ bp: Massage commit message. ]

Fixes: 4d05bf71f1 ("x86/resctrl: Introduce AMD QOS feature")
Signed-off-by: Babu Moger <babu.moger@amd.com>
Signed-off-by: Borislav Petkov <bp@suse.de>
Reviewed-by: Reinette Chatre <reinette.chatre@intel.com>
Link: https://lkml.kernel.org/r/160675180380.15628.3309402017215002347.stgit@bmoger-ubuntu
This commit is contained in:
Babu Moger 2020-11-30 09:57:20 -06:00 committed by Borislav Petkov
parent 25bc65d8dd
commit fae3a13d2a
3 changed files with 14 additions and 2 deletions

View File

@ -570,6 +570,8 @@ static void domain_add_cpu(int cpu, struct rdt_resource *r)
if (d) { if (d) {
cpumask_set_cpu(cpu, &d->cpu_mask); cpumask_set_cpu(cpu, &d->cpu_mask);
if (r->cache.arch_has_per_cpu_cfg)
rdt_domain_reconfigure_cdp(r);
return; return;
} }
@ -923,6 +925,7 @@ static __init void rdt_init_res_defs_intel(void)
r->rid == RDT_RESOURCE_L2CODE) { r->rid == RDT_RESOURCE_L2CODE) {
r->cache.arch_has_sparse_bitmaps = false; r->cache.arch_has_sparse_bitmaps = false;
r->cache.arch_has_empty_bitmaps = false; r->cache.arch_has_empty_bitmaps = false;
r->cache.arch_has_per_cpu_cfg = false;
} else if (r->rid == RDT_RESOURCE_MBA) { } else if (r->rid == RDT_RESOURCE_MBA) {
r->msr_base = MSR_IA32_MBA_THRTL_BASE; r->msr_base = MSR_IA32_MBA_THRTL_BASE;
r->msr_update = mba_wrmsr_intel; r->msr_update = mba_wrmsr_intel;
@ -943,6 +946,7 @@ static __init void rdt_init_res_defs_amd(void)
r->rid == RDT_RESOURCE_L2CODE) { r->rid == RDT_RESOURCE_L2CODE) {
r->cache.arch_has_sparse_bitmaps = true; r->cache.arch_has_sparse_bitmaps = true;
r->cache.arch_has_empty_bitmaps = true; r->cache.arch_has_empty_bitmaps = true;
r->cache.arch_has_per_cpu_cfg = true;
} else if (r->rid == RDT_RESOURCE_MBA) { } else if (r->rid == RDT_RESOURCE_MBA) {
r->msr_base = MSR_IA32_MBA_BW_BASE; r->msr_base = MSR_IA32_MBA_BW_BASE;
r->msr_update = mba_wrmsr_amd; r->msr_update = mba_wrmsr_amd;

View File

@ -360,6 +360,8 @@ struct msr_param {
* executing entities * executing entities
* @arch_has_sparse_bitmaps: True if a bitmap like f00f is valid. * @arch_has_sparse_bitmaps: True if a bitmap like f00f is valid.
* @arch_has_empty_bitmaps: True if the '0' bitmap is valid. * @arch_has_empty_bitmaps: True if the '0' bitmap is valid.
* @arch_has_per_cpu_cfg: True if QOS_CFG register for this cache
* level has CPU scope.
*/ */
struct rdt_cache { struct rdt_cache {
unsigned int cbm_len; unsigned int cbm_len;
@ -369,6 +371,7 @@ struct rdt_cache {
unsigned int shareable_bits; unsigned int shareable_bits;
bool arch_has_sparse_bitmaps; bool arch_has_sparse_bitmaps;
bool arch_has_empty_bitmaps; bool arch_has_empty_bitmaps;
bool arch_has_per_cpu_cfg;
}; };
/** /**

View File

@ -1909,6 +1909,11 @@ static int set_cache_qos_cfg(int level, bool enable)
r_l = &rdt_resources_all[level]; r_l = &rdt_resources_all[level];
list_for_each_entry(d, &r_l->domains, list) { list_for_each_entry(d, &r_l->domains, list) {
if (r_l->cache.arch_has_per_cpu_cfg)
/* Pick all the CPUs in the domain instance */
for_each_cpu(cpu, &d->cpu_mask)
cpumask_set_cpu(cpu, cpu_mask);
else
/* Pick one CPU from each domain instance to update MSR */ /* Pick one CPU from each domain instance to update MSR */
cpumask_set_cpu(cpumask_any(&d->cpu_mask), cpu_mask); cpumask_set_cpu(cpumask_any(&d->cpu_mask), cpu_mask);
} }