[PATCH RFC v4 14/18] riscv_cbqri: resctrl: Add MB_WGHT bandwidth allocation via Mweight
Drew Fustini
fustini at kernel.org
Sun May 10 22:11:10 PDT 2026
Add bandwidth allocation through Mweight (shared weight for unreserved
bandwidth) exposed as the MB_WGHT resource. Mweight has no MBA
equivalent, so it lands as a new RDT_RESOURCE_*.
Mweight is an integer in [0, 255]. A value of 0 disables work-
conserving sharing for the group, capping its bandwidth at the
MB_MIN reservation. Values 1..255 compete for the leftover pool in
proportion to the weight.
The same BC backs both MB_MIN and MB_WGHT and bc_bw_alloc packs Rbwb and
Mweight in one register. cbqri_attach_cpu_to_bw_ctrl() attaches both
rids to the picked BC.
Reset gives every RCID the new-group default (max_bw = 255) for
equal opportunistic shares.
Assisted-by: Claude:claude-opus-4-7
Co-developed-by: Adrien Ricciardi <aricciardi at baylibre.com>
Signed-off-by: Adrien Ricciardi <aricciardi at baylibre.com>
Signed-off-by: Drew Fustini <fustini at kernel.org>
---
drivers/resctrl/cbqri_resctrl.c | 62 ++++++++++++++++++++++++++++++++++++++---
1 file changed, 58 insertions(+), 4 deletions(-)
diff --git a/drivers/resctrl/cbqri_resctrl.c b/drivers/resctrl/cbqri_resctrl.c
index bcd9367e3555..71ee8e610757 100644
--- a/drivers/resctrl/cbqri_resctrl.c
+++ b/drivers/resctrl/cbqri_resctrl.c
@@ -418,6 +418,8 @@ int resctrl_arch_update_one(struct rdt_resource *r, struct rdt_ctrl_domain *d,
case RDT_RESOURCE_MB_MIN:
/* sum(Rbwb) <= MRBWB validation runs inside cbqri_apply_rbwb(). */
return cbqri_apply_rbwb(dom->hw_ctrl, closid, cfg_val, true);
+ case RDT_RESOURCE_MB_WGHT:
+ return cbqri_apply_mweight_config(dom->hw_ctrl, closid, cfg_val);
default:
return -EINVAL;
}
@@ -478,6 +480,14 @@ u32 resctrl_arch_get_config(struct rdt_resource *r, struct rdt_ctrl_domain *d,
val = (u32)rbwb;
break;
}
+ case RDT_RESOURCE_MB_WGHT: {
+ u64 mweight;
+
+ err = cbqri_read_mweight(ctrl, closid, &mweight);
+ if (err == 0)
+ val = (u32)mweight;
+ break;
+ }
default:
break;
}
@@ -526,6 +536,18 @@ void resctrl_arch_reset_all_ctrls(struct rdt_resource *r)
rcid, rerr);
}
break;
+ case RDT_RESOURCE_MB_WGHT:
+ /* All RCIDs start at max weight (the new-group default). */
+ for (i = 0; i < hw_res->ctrl->rcid_count; i++) {
+ int rerr;
+
+ rerr = cbqri_apply_mweight_config(dom->hw_ctrl, i,
+ default_ctrl);
+ if (rerr)
+ pr_err_ratelimited("Mweight reset RCID %u failed (%d)\n",
+ i, rerr);
+ }
+ break;
default:
for (i = 0; i < hw_res->ctrl->rcid_count; i++) {
for (t = 0; t < CDP_NUM_TYPES; t++) {
@@ -594,6 +616,11 @@ static int cbqri_init_domain_ctrlval(struct rdt_resource *r, struct rdt_ctrl_dom
err = cbqri_apply_rbwb(dom->hw_ctrl, rcid, rbwb, false);
break;
}
+ case RDT_RESOURCE_MB_WGHT:
+ /* Match the new-group default: equal weights across RCIDs. */
+ err = cbqri_apply_mweight_config(dom->hw_ctrl, i,
+ resctrl_get_default_ctrl(r));
+ break;
default:
/*
* Seed both DATA and CODE staged slots so a later
@@ -731,6 +758,25 @@ static int cbqri_resctrl_control_init(struct cbqri_resctrl_res *cbqri_res)
INIT_LIST_HEAD(&res->mon_domains);
break;
+ case RDT_RESOURCE_MB_WGHT:
+ res->name = "MB_WGHT";
+ res->schema_fmt = RESCTRL_SCHEMA_RANGE;
+ res->ctrl_scope = RESCTRL_L3_CACHE;
+ /* Mweight is a dimensionless ratio. No delay/linear concept. */
+ res->membw.throttle_mode = THREAD_THROTTLE_UNDEFINED;
+ /*
+ * CBQRI section 4.5: Mweight is 0-255 (0 disables
+ * work-conserving). No sum constraint, so leave
+ * default_to_min false: groups default to max_bw.
+ */
+ res->membw.min_bw = 0;
+ res->membw.max_bw = 255;
+ res->membw.bw_gran = 1;
+ res->alloc_capable = ctrl->alloc_capable;
+ INIT_LIST_HEAD(&res->ctrl_domains);
+ INIT_LIST_HEAD(&res->mon_domains);
+ break;
+
default:
break;
}
@@ -739,13 +785,14 @@ static int cbqri_resctrl_control_init(struct cbqri_resctrl_res *cbqri_res)
}
/*
- * Pick one BC to back MB_MIN. Multiple BCs must agree on rcid_count
- * and mrbwb. Mismatch is fatal because resctrl exposes a single set
- * of caps per rid.
+ * Pick one BC to back both MB_MIN and MB_WGHT (they share a controller).
+ * Multiple BCs must agree on rcid_count and mrbwb. Mismatch is fatal
+ * because resctrl exposes a single set of caps per rid.
*/
static int cbqri_resctrl_pick_bw_alloc(void)
{
struct cbqri_resctrl_res *mb_min = &cbqri_resctrl_resources[RDT_RESOURCE_MB_MIN];
+ struct cbqri_resctrl_res *mb_wght = &cbqri_resctrl_resources[RDT_RESOURCE_MB_WGHT];
struct cbqri_controller *ctrl;
list_for_each_entry(ctrl, &cbqri_controllers, list) {
@@ -764,6 +811,7 @@ static int cbqri_resctrl_pick_bw_alloc(void)
}
mb_min->ctrl = ctrl;
+ mb_wght->ctrl = ctrl;
}
return 0;
@@ -982,7 +1030,13 @@ static int cbqri_attach_cpu_to_one_bw_res(struct cbqri_controller *ctrl,
static int cbqri_attach_cpu_to_bw_ctrl(struct cbqri_controller *ctrl,
unsigned int cpu)
{
- return cbqri_attach_cpu_to_one_bw_res(ctrl, RDT_RESOURCE_MB_MIN, cpu);
+ int err;
+
+ err = cbqri_attach_cpu_to_one_bw_res(ctrl, RDT_RESOURCE_MB_MIN, cpu);
+ if (err)
+ return err;
+
+ return cbqri_attach_cpu_to_one_bw_res(ctrl, RDT_RESOURCE_MB_WGHT, cpu);
}
static void cbqri_detach_cpu_from_l3_mon(struct rdt_resource *res,
--
2.43.0
More information about the linux-riscv
mailing list