[RFC PATCH v2 5/9] fs/resctrl: Allow mba_MBps with assignable MBM counters

From: Jinjie Ruan

Date: Thu Nov 12 2026 - 08:28:20 EST


The controller needs a counter for the event selected by mba_MBps_event
in every monitoring group, so mba_MBps is refused when MBM counters are
assignable. On MPAM a group's monitor is assigned from a fixed pool
when the group is created, and users can otherwise only pick a
percentage of a maximum that firmware does not report.

Allow the controller when the architecture has a fixed assignment mode
and assigns counters when a group is created. Keep mbm_assign_on_mkdir
enabled while the controller is in use, restore its previous value
when the controller is disabled, and refuse to unassign the
controller's counter meanwhile.

Only MPAM has this mode; other systems keep the previous behavior.

Suggested-by: Ben Horgan <ben.horgan@xxxxxxx>
Signed-off-by: Jinjie Ruan <ruanjinjie@xxxxxxxxxx>
---
Documentation/filesystems/resctrl.rst | 7 +++++--
fs/resctrl/monitor.c | 25 ++++++++++++++++++++++
fs/resctrl/rdtgroup.c | 30 +++++++++++++++++++++------
3 files changed, 54 insertions(+), 8 deletions(-)

diff --git a/Documentation/filesystems/resctrl.rst b/Documentation/filesystems/resctrl.rst
index b52795e03303..d70aec6f7096 100644
--- a/Documentation/filesystems/resctrl.rst
+++ b/Documentation/filesystems/resctrl.rst
@@ -471,7 +471,8 @@ with the following files:
Determines if a counter will automatically be assigned to an RMID, MBM event
pair when its associated monitor group is created via mkdir. Enabled by default
on boot, also when switched from "default" mode to "mbm_event" counter assignment
- mode. Users can disable this capability by writing to the interface.
+ mode. Users can disable this capability by writing to the interface. While the
+ MBA software controller is enabled, auto assignment cannot be disabled.

"0":
Auto assignment is disabled.
@@ -704,7 +705,9 @@ When monitoring is enabled all MON groups may also contain:
mbm_total_bytes:0=e;1=e
mbm_local_bytes:0=e;1=e

- Assignments can be modified by writing to the interface.
+ Assignments can be modified by writing to the interface. While the
+ MBA software controller is enabled, the counter of the event the
+ controller uses cannot be unassigned.

Examples:

diff --git a/fs/resctrl/monitor.c b/fs/resctrl/monitor.c
index 8f3b8c3e3010..5a67c8089615 100644
--- a/fs/resctrl/monitor.c
+++ b/fs/resctrl/monitor.c
@@ -1210,6 +1210,12 @@ ssize_t resctrl_mbm_assign_on_mkdir_write(struct kernfs_open_file *of, char *buf
goto out_unlock;
}

+ if (!value && is_mba_sc(NULL)) {
+ rdt_last_cmd_puts("mbm_assign_on_mkdir is required by the software controller\n");
+ ret = -EBUSY;
+ goto out_unlock;
+ }
+
r->mon.mbm_assign_on_mkdir = value;

out_unlock:
@@ -1776,6 +1782,19 @@ static struct mon_evt *mbm_get_mon_event_by_name(struct rdt_resource *r, char *n
return NULL;
}

+/*
+ * Return the event the MBA software controller uses as its input for @rdtgrp.
+ * A monitor group has no event of its own: its bandwidth is summed into the
+ * parent control group, which is the group with the mba_MBps_event setting.
+ */
+static enum resctrl_event_id rdtgrp_mba_mbps_event(struct rdtgroup *rdtgrp)
+{
+ if (rdtgrp->type == RDTMON_GROUP)
+ return rdtgrp->mon.parent->mba_mbps_event;
+
+ return rdtgrp->mba_mbps_event;
+}
+
static int rdtgroup_modify_assign_state(char *assign, struct rdt_l3_mon_domain *d,
struct rdtgroup *rdtgrp, struct mon_evt *mevt)
{
@@ -1789,6 +1808,12 @@ static int rdtgroup_modify_assign_state(char *assign, struct rdt_l3_mon_domain *
ret = rdtgroup_assign_cntr_event(d, rdtgrp, mevt);
break;
case '_':
+ if (is_mba_sc(NULL) &&
+ mevt->evtid == rdtgrp_mba_mbps_event(rdtgrp)) {
+ rdt_last_cmd_puts("Counter is in use by the software controller\n");
+ ret = -EBUSY;
+ break;
+ }
rdtgroup_unassign_cntr_event(d, rdtgrp, mevt);
break;
default:
diff --git a/fs/resctrl/rdtgroup.c b/fs/resctrl/rdtgroup.c
index b32831871f70..518d89b0c67d 100644
--- a/fs/resctrl/rdtgroup.c
+++ b/fs/resctrl/rdtgroup.c
@@ -2610,10 +2610,9 @@ static void mba_sc_domain_destroy(struct rdt_resource *r,
* The MBA software controller is supported only if MBM is supported and MBA is
* in linear scale, and the MBM monitor scope is the same as MBA control scope.
*
- * The software controller cannot be supported when the MBM counters are
- * assignable. There is no guarantee that MBM counters are assigned to the
- * event backing the software controller in all monitoring domains of all
- * monitoring groups.
+ * The controller needs a counter for its event in every monitoring group.
+ * With assignable counters that requires a fixed assignment mode, with
+ * counters assigned automatically while the controller is in use.
*/
static bool supports_mba_mbps(void)
{
@@ -2623,9 +2622,13 @@ static bool supports_mba_mbps(void)
return (resctrl_is_mbm_enabled() &&
r->alloc_capable && is_mba_linear() &&
r->ctrl_scope == rmbm->mon_scope &&
- !rmbm->mon.mbm_cntr_assignable);
+ (!rmbm->mon.mbm_cntr_assignable ||
+ rmbm->mon.mbm_cntr_assign_fixed));
}

+/* mbm_assign_on_mkdir before the software controller forced it on. */
+static bool mba_sc_saved_assign_on_mkdir;
+
/*
* Enable or disable the MBA software controller
* which helps user specify bandwidth in MBps.
@@ -2633,6 +2636,7 @@ static bool supports_mba_mbps(void)
static int set_mba_sc(bool mba_sc)
{
struct rdt_resource *r = resctrl_arch_get_resource(RDT_RESOURCE_MBA);
+ struct rdt_resource *rmbm = resctrl_arch_get_resource(RDT_RESOURCE_L3);
u32 num_closid = resctrl_arch_get_num_closid(r);
struct rdt_ctrl_domain *d;
unsigned long fflags;
@@ -2643,6 +2647,20 @@ static int set_mba_sc(bool mba_sc)

r->membw.mba_sc = mba_sc;

+ /*
+ * The controller needs its event counted in every monitoring group:
+ * force automatic assignment on, and restore the user's setting when
+ * the controller is disabled.
+ */
+ if (rmbm->mon.mbm_cntr_assignable) {
+ if (mba_sc) {
+ mba_sc_saved_assign_on_mkdir = rmbm->mon.mbm_assign_on_mkdir;
+ rmbm->mon.mbm_assign_on_mkdir = true;
+ } else {
+ rmbm->mon.mbm_assign_on_mkdir = mba_sc_saved_assign_on_mkdir;
+ }
+ }
+
rdtgroup_default.mba_mbps_event = mba_mbps_default_event;

list_for_each_entry_rcu(d, &r->ctrl_domains, hdr.list, lockdep_is_cpus_held()) {
@@ -3352,7 +3370,7 @@ static int rdt_parse_param(struct fs_context *fc, struct fs_parameter *param)
ctx->enable_cdpl2 = true;
return 0;
case Opt_mba_mbps:
- msg = "mba_MBps requires MBM (mbm_event mode not supported) and linear scale MBA at L3 scope";
+ msg = "mba_MBps requires MBM and linear scale MBA at L3 scope";
if (!supports_mba_mbps())
return invalfc(fc, msg);
ctx->enable_mba_mbps = true;
--
2.34.1