[PATCH RFC v6 14/18] riscv_cbqri: resctrl: Add MB_WGHT bandwidth allocation via Mweight
Drew Fustini <[email protected]> Mon, 01 Jun 2026 13:36:08 -0700
| Newsgroups | dev.linux.lists.acpica-devel,dev.linux.lists.linux-rt-devel,org.infradead.lists.linux-riscv,org.kernel.vger.linux-acpi,org.kernel.vger.linux-devicetree,org.kernel.vger.linux-doc,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
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 <[email protected]> Signed-off-by: Adrien Ricciardi <[email protected]> Signed-off-by: Drew Fustini <[email protected]> --- drivers/resctrl/cbqri_resctrl.c | 90 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 86 insertions(+), 4 deletions(-) diff --git a/drivers/resctrl/cbqri_resctrl.c b/drivers/resctrl/cbqri_resctrl.c index 1d312004b07d..14b955eb7949 100644 --- a/drivers/resctrl/cbqri_resctrl.c +++ b/drivers/resctrl/cbqri_resctrl.c @@ -366,6 +366,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; } @@ -426,6 +428,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; } @@ -485,6 +495,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++) { @@ -549,6 +571,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 @@ -690,6 +717,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; } @@ -698,13 +744,12 @@ 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. */ 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) { @@ -723,6 +768,7 @@ static int cbqri_resctrl_pick_bw_alloc(void) } mb_min->ctrl = ctrl; + mb_wght->ctrl = ctrl; } return 0; @@ -961,10 +1007,46 @@ static int cbqri_attach_cpu_to_one_bw_res(struct cbqri_controller *ctrl, return 0; } +static void cbqri_detach_cpu_from_one_bw_res(struct cbqri_controller *ctrl, + enum resctrl_res_level rid, + unsigned int cpu) +{ + struct cbqri_resctrl_res *hw_res = &cbqri_resctrl_resources[rid]; + struct rdt_resource *res = &hw_res->resctrl_res; + struct rdt_ctrl_domain *domain; + int dom_id = ctrl->mem.prox_dom; + + lockdep_assert_held(&cbqri_domain_list_lock); + + if (!hw_res->ctrl) + return; + + domain = cbqri_find_ctrl_domain(&res->ctrl_domains, dom_id); + if (!domain || !cpumask_test_cpu(cpu, &domain->hdr.cpu_mask)) + return; + + cpumask_clear_cpu(cpu, &domain->hdr.cpu_mask); + if (cpumask_empty(&domain->hdr.cpu_mask)) { + resctrl_offline_ctrl_domain(res, domain); + list_del(&domain->hdr.list); + kfree(container_of(domain, struct cbqri_resctrl_dom, + resctrl_ctrl_dom)); + } +} + 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; + + err = cbqri_attach_cpu_to_one_bw_res(ctrl, RDT_RESOURCE_MB_WGHT, cpu); + if (err) + cbqri_detach_cpu_from_one_bw_res(ctrl, RDT_RESOURCE_MB_MIN, cpu); + return err; } static void cbqri_detach_cpu_from_l3_mon(struct rdt_resource *res, -- 2.43.0