[PATCH v5 08/40] x86/resctrl: Generate default_ctrl instead of sharing it

From: James Morse
Date: Fri Oct 04 2024 - 14:06:33 EST


The struct rdt_resource default_ctrl is used by both the architecture
code for resetting the hardware controls, and by the filesystem parts
of resctrl to report to user-space.

This means the value has to be shared, but might not match the
properties of the control. e.g. a percentage greater than 100.

Instead, determine the default control value from a shared helper
resctrl_get_default_ctrl() that uses the schema properties to
determine the correct value.

Signed-off-by: James Morse <james.morse@xxxxxxx>
Tested-by: Carl Worth <carl@xxxxxxxxxxxxxxxxxxxxxx> # arm64
Tested-by: Shaopeng Tan <tan.shaopeng@xxxxxxxxxxxxxx>
Reviewed-by: Shaopeng Tan <tan.shaopeng@xxxxxxxxxxxxxx>
---
Changes since v2:
* This patch is new.
---
arch/x86/kernel/cpu/resctrl/core.c | 16 +++++++---------
arch/x86/kernel/cpu/resctrl/rdtgroup.c | 6 +++---
include/linux/resctrl.h | 19 +++++++++++++++++--
3 files changed, 27 insertions(+), 14 deletions(-)

diff --git a/arch/x86/kernel/cpu/resctrl/core.c b/arch/x86/kernel/cpu/resctrl/core.c
index e79807a8f060..d77bfa17447a 100644
--- a/arch/x86/kernel/cpu/resctrl/core.c
+++ b/arch/x86/kernel/cpu/resctrl/core.c
@@ -143,7 +143,10 @@ static inline void cache_alloc_hsw_probe(void)
{
struct rdt_hw_resource *hw_res = &rdt_resources_all[RDT_RESOURCE_L3];
struct rdt_resource *r = &hw_res->r_resctrl;
- u64 max_cbm = BIT_ULL_MASK(20) - 1, l3_cbm_0;
+ u64 max_cbm, l3_cbm_0;
+
+ r->cache.cbm_len = 20;
+ max_cbm = resctrl_get_default_ctrl(r);

if (wrmsrl_safe(MSR_IA32_L3_CBM_BASE, max_cbm))
return;
@@ -155,8 +158,6 @@ static inline void cache_alloc_hsw_probe(void)
return;

hw_res->num_closid = 4;
- r->default_ctrl = max_cbm;
- r->cache.cbm_len = 20;
r->cache.shareable_bits = 0xc0000;
r->cache.min_cbm_bits = 2;
r->cache.arch_has_sparse_bitmasks = false;
@@ -211,7 +212,6 @@ static bool __get_mem_config_intel(struct rdt_resource *r)
cpuid_count(0x00000010, 3, &eax.full, &ebx, &ecx, &edx.full);
hw_res->num_closid = edx.split.cos_max + 1;
max_delay = eax.split.max_delay + 1;
- r->default_ctrl = MAX_MBA_BW;
r->membw.max_bw = MAX_MBA_BW;
r->membw.arch_needs_linear = true;
if (ecx & MBA_IS_LINEAR) {
@@ -248,7 +248,6 @@ static bool __rdt_get_mem_config_amd(struct rdt_resource *r)

cpuid_count(0x80000020, subleaf, &eax, &ebx, &ecx, &edx);
hw_res->num_closid = edx + 1;
- r->default_ctrl = 1 << eax;
r->schema_fmt = RESCTRL_SCHEMA_RANGE;
r->membw.max_bw = 1 << eax;

@@ -280,8 +279,7 @@ static void rdt_get_cache_alloc_cfg(int idx, struct rdt_resource *r)
cpuid_count(0x00000010, idx, &eax.full, &ebx, &ecx.full, &edx.full);
hw_res->num_closid = edx.split.cos_max + 1;
r->cache.cbm_len = eax.split.cbm_len + 1;
- r->default_ctrl = BIT_MASK(eax.split.cbm_len + 1) - 1;
- r->cache.shareable_bits = ebx & r->default_ctrl;
+ r->cache.shareable_bits = ebx & resctrl_get_default_ctrl(r);
if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL)
r->cache.arch_has_sparse_bitmasks = ecx.split.noncont;
r->alloc_capable = true;
@@ -328,7 +326,7 @@ static u32 delay_bw_map(unsigned long bw, struct rdt_resource *r)
return MAX_MBA_BW - bw;

pr_warn_once("Non Linear delay-bw map not supported but queried\n");
- return r->default_ctrl;
+ return resctrl_get_default_ctrl(r);
}

static void mba_wrmsr_intel(struct msr_param *m)
@@ -437,7 +435,7 @@ static void setup_default_ctrlval(struct rdt_resource *r, u32 *dc)
* For Memory Allocation: Set b/w requested to 100%
*/
for (i = 0; i < hw_res->num_closid; i++, dc++)
- *dc = r->default_ctrl;
+ *dc = resctrl_get_default_ctrl(r);
}

static void ctrl_domain_free(struct rdt_hw_ctrl_domain *hw_dom)
diff --git a/arch/x86/kernel/cpu/resctrl/rdtgroup.c b/arch/x86/kernel/cpu/resctrl/rdtgroup.c
index 1707b04e901e..de2c169a1678 100644
--- a/arch/x86/kernel/cpu/resctrl/rdtgroup.c
+++ b/arch/x86/kernel/cpu/resctrl/rdtgroup.c
@@ -969,7 +969,7 @@ static int rdt_default_ctrl_show(struct kernfs_open_file *of,
struct resctrl_schema *s = of->kn->parent->priv;
struct rdt_resource *r = s->res;

- seq_printf(seq, "%x\n", r->default_ctrl);
+ seq_printf(seq, "%x\n", resctrl_get_default_ctrl(r));
return 0;
}

@@ -2866,7 +2866,7 @@ static int reset_all_ctrls(struct rdt_resource *r)
hw_dom = resctrl_to_arch_ctrl_dom(d);

for (i = 0; i < hw_res->num_closid; i++)
- hw_dom->ctrl_val[i] = r->default_ctrl;
+ hw_dom->ctrl_val[i] = resctrl_get_default_ctrl(r);
msr_param.dom = d;
smp_call_function_any(&d->hdr.cpu_mask, rdt_ctrl_update, &msr_param, 1);
}
@@ -3401,7 +3401,7 @@ static void rdtgroup_init_mba(struct rdt_resource *r, u32 closid)
}

cfg = &d->staged_config[CDP_NONE];
- cfg->new_ctrl = r->default_ctrl;
+ cfg->new_ctrl = resctrl_get_default_ctrl(r);
cfg->have_new_ctrl = true;
}
}
diff --git a/include/linux/resctrl.h b/include/linux/resctrl.h
index b66cd977b658..1a9cca95b5e8 100644
--- a/include/linux/resctrl.h
+++ b/include/linux/resctrl.h
@@ -217,7 +217,6 @@ enum resctrl_schema_fmt {
* @ctrl_domains: RCU list of all control domains for this resource
* @mon_domains: RCU list of all monitor domains for this resource
* @name: Name to use in "schemata" file.
- * @default_ctrl: Specifies default cache cbm or memory B/W percent.
* @schema_fmt: Which format string and parser is used for this schema.
* @evt_list: List of monitoring events
* @cdp_capable: Is the CDP feature available on this resource
@@ -234,7 +233,6 @@ struct rdt_resource {
struct list_head ctrl_domains;
struct list_head mon_domains;
char *name;
- u32 default_ctrl;
enum resctrl_schema_fmt schema_fmt;
struct list_head evt_list;
bool cdp_capable;
@@ -269,6 +267,23 @@ struct resctrl_schema {
u32 num_closid;
};

+/**
+ * resctrl_get_default_ctrl() - Return the default control value for this
+ * resource.
+ * @r: The resource whose default control type is queried.
+ */
+static inline u32 resctrl_get_default_ctrl(struct rdt_resource *r)
+{
+ switch (r->schema_fmt) {
+ case RESCTRL_SCHEMA_BITMAP:
+ return BIT_MASK(r->cache.cbm_len) - 1;
+ case RESCTRL_SCHEMA_RANGE:
+ return r->membw.max_bw;
+ }
+
+ return WARN_ON_ONCE(1);
+}
+
/* The number of closid supported by this resource regardless of CDP */
u32 resctrl_arch_get_num_closid(struct rdt_resource *r);
u32 resctrl_arch_system_num_rmid_idx(void);
--
2.39.2