[PATCH v1 1/4] x86,fs/resctrl: Make resctrl_arch_is_evt_configurable() aware of mbm_assign_mode

From: Ben Horgan

Date: Wed Feb 25 2026 - 15:19:36 EST


The features BMEC and ABMC provide separate interfaces to configuring which
bandwidth types a counter tracks. Currently
resctrl_arch_is_evt_configurable() only ever returns true if BMEC is
supported.

ABMC is useful even when BMEC is supported as it also provides counter
assignment which reduces the number of hardware monitors a system
requires. It is an architectural detail that ABMC provides counter
configurability without requiring the prior feature, BMEC. On MPAM systems
these two features are independent and the bandwidth types are limited to a
choice of only read or write.

In order to give resctrl the information to support these features
independently extend resctrl_arch_is_evt_configurable() to report whether
events are configurable when using the mbm_event counter assignment mode.

Signed-off-by: Ben Horgan <ben.horgan@xxxxxxx>
---
arch/x86/kernel/cpu/resctrl/core.c | 12 ++++++++++--
fs/resctrl/monitor.c | 4 ++--
include/linux/resctrl.h | 2 +-
3 files changed, 13 insertions(+), 5 deletions(-)

diff --git a/arch/x86/kernel/cpu/resctrl/core.c b/arch/x86/kernel/cpu/resctrl/core.c
index 7667cf7c4e94..d35f4417d55e 100644
--- a/arch/x86/kernel/cpu/resctrl/core.c
+++ b/arch/x86/kernel/cpu/resctrl/core.c
@@ -877,11 +877,19 @@ bool rdt_cpu_has(int flag)
return ret;
}

-bool resctrl_arch_is_evt_configurable(enum resctrl_event_id evt)
+bool resctrl_arch_is_evt_configurable(enum resctrl_event_id evt, bool assignable)
{
- if (!rdt_cpu_has(X86_FEATURE_BMEC))
+ if (!assignable && !rdt_cpu_has(X86_FEATURE_BMEC))
return false;

+ if (assignable && !rdt_cpu_has(X86_FEATURE_ABMC))
+ return false;
+
+ /*
+ * When ABMC is used the mbm_local and mbm_total events are enabled
+ * based on the equivalently named cpu features. (In order to allow
+ * fallback to the default counter assignment mode).
+ */
switch (evt) {
case QOS_L3_MBM_TOTAL_EVENT_ID:
return rdt_cpu_has(X86_FEATURE_CQM_MBM_TOTAL);
diff --git a/fs/resctrl/monitor.c b/fs/resctrl/monitor.c
index 49f3f6b846b2..d25622ee22c5 100644
--- a/fs/resctrl/monitor.c
+++ b/fs/resctrl/monitor.c
@@ -1854,12 +1854,12 @@ int resctrl_l3_mon_resource_init(void)
if (ret)
return ret;

- if (resctrl_arch_is_evt_configurable(QOS_L3_MBM_TOTAL_EVENT_ID)) {
+ if (resctrl_arch_is_evt_configurable(QOS_L3_MBM_TOTAL_EVENT_ID, false)) {
mon_event_all[QOS_L3_MBM_TOTAL_EVENT_ID].configurable = true;
resctrl_file_fflags_init("mbm_total_bytes_config",
RFTYPE_MON_INFO | RFTYPE_RES_CACHE);
}
- if (resctrl_arch_is_evt_configurable(QOS_L3_MBM_LOCAL_EVENT_ID)) {
+ if (resctrl_arch_is_evt_configurable(QOS_L3_MBM_LOCAL_EVENT_ID, false)) {
mon_event_all[QOS_L3_MBM_LOCAL_EVENT_ID].configurable = true;
resctrl_file_fflags_init("mbm_local_bytes_config",
RFTYPE_MON_INFO | RFTYPE_RES_CACHE);
diff --git a/include/linux/resctrl.h b/include/linux/resctrl.h
index 006e57fd7ca5..9ac1fe76bff4 100644
--- a/include/linux/resctrl.h
+++ b/include/linux/resctrl.h
@@ -419,7 +419,7 @@ bool resctrl_enable_mon_event(enum resctrl_event_id eventid, bool any_cpu,

bool resctrl_is_mon_event_enabled(enum resctrl_event_id eventid);

-bool resctrl_arch_is_evt_configurable(enum resctrl_event_id evt);
+bool resctrl_arch_is_evt_configurable(enum resctrl_event_id evt, bool assignable);

static inline bool resctrl_is_mbm_event(enum resctrl_event_id eventid)
{
--
2.43.0