[RFC PATCH 2/7] fs/resctrl: Add the L2 monitor events
From: Jinjie Ruan
Date: Thu Oct 22 2026 - 04:49:32 EST
Add the L2 cache occupancy (l2c_occupancy) and L2 bandwidth
(mbm_core_bytes) monitor events, and route RDT_RESOURCE_L2 through the
same per-domain read path as the L3.
As ARM MPAM Specification said, MPAM resource monitors are associated
with a shared partitionable resource in an MSC, not with a particular
cache level: the level comes from firmware's description of the MSC.
L2 monitors were only missing a resctrl scope. The events are
exposed once an architecture reports the L2 resource
mon_capable; x86 never does.
Update Documentation/arch/arm64/mpam.rst to mention L2.
Signed-off-by: Jinjie Ruan <ruanjinjie@xxxxxxxxxx>
---
Documentation/arch/arm64/mpam.rst | 23 ++++++++++++++---------
fs/resctrl/monitor.c | 9 +++++++++
include/linux/resctrl_types.h | 13 ++++++++++++-
3 files changed, 35 insertions(+), 10 deletions(-)
diff --git a/Documentation/arch/arm64/mpam.rst b/Documentation/arch/arm64/mpam.rst
index 67fe515ed501..f0697dedde03 100644
--- a/Documentation/arch/arm64/mpam.rst
+++ b/Documentation/arch/arm64/mpam.rst
@@ -32,8 +32,9 @@ Because the user interface to MPAM is via resctrl, only MPAM features that are
compatible with resctrl can be exposed to user-space.
MSC are considered as a group based on the topology. MSC that correspond with
-the L3 cache are considered together, it is not possible to mix MSC between L2
-and L3 to 'cover' a resctrl schema.
+the L3 cache are considered together, as are MSC that correspond with the L2
+cache; it is not possible to mix MSC between L2 and L3 to 'cover' a resctrl
+schema.
The supported features are:
@@ -61,9 +62,11 @@ The supported features are:
When the MPAM driver finds multiple groups of MSC it can use for the 'MB'
schema, it prefers the group closest to the L3 cache.
-* Cache Storage Usage (CSU) counters can expose the 'llc_occupancy' provided
- there is at least one CSU monitor on each MSC that makes up the L3 group.
- Exposing CSU counters from other caches or devices is not supported.
+* Cache Storage Usage (CSU) counters expose the occupancy of the cache they
+ monitor: 'llc_occupancy' for the L3 group and 'l2c_occupancy' for the L2
+ group, provided there is at least one CSU monitor on each MSC that makes up
+ the group. Exposing CSU counters from other caches or devices is not
+ supported.
* Memory Bandwidth Usage (MBWU) on or after the L3 cache. resctrl uses the
L3 cache-id to identify where the memory bandwidth is measured. For this
@@ -82,10 +85,12 @@ The supported features are:
have a corresponding L3 cache. 'mbm_local_bytes' is not exposed as MPAM
cannot distinguish local traffic from global traffic.
- All these restrictions based on L3 cache are due to resctrl, currently, only
- supporting monitoring at the L3 scope. It is expected that going forward more
- MBWU monitors can be exposed to the user after support for more monitoring
- scopes is added to resctrl.
+ MBWU monitors on an L2 MSC expose the bandwidth the cache sees as the
+ 'mbm_core_bytes' event on the L2 resource.
+
+ These restrictions are due to resctrl only supporting monitoring at the L2
+ and L3 cache scopes. MBWU monitors on caches at other levels, or on devices,
+ are not exposed.
Reporting Bugs
==============
diff --git a/fs/resctrl/monitor.c b/fs/resctrl/monitor.c
index f9f4d4486c1b..ee296c27c6e8 100644
--- a/fs/resctrl/monitor.c
+++ b/fs/resctrl/monitor.c
@@ -543,6 +543,13 @@ static int __mon_event_count(struct rdtgroup *rdtgrp, struct rmid_read *rr)
return __mon_event_count_one_domain(rdtgrp, rr);
else
return __l3_mon_event_count_sum(rdtgrp, rr);
+ case RDT_RESOURCE_L2:
+ WARN_ON_ONCE(rr->evt->any_cpu);
+ if (WARN_ON_ONCE(!rr->hdr)) {
+ rr->err = -EINVAL;
+ return -EINVAL;
+ }
+ return __mon_event_count_one_domain(rdtgrp, rr);
case RDT_RESOURCE_PERF_PKG: {
u64 tval = 0;
@@ -1032,6 +1039,8 @@ struct mon_evt mon_event_all[QOS_NUM_EVENTS] = {
MON_EVENT(QOS_L3_OCCUP_EVENT_ID, "llc_occupancy", RDT_RESOURCE_L3, false),
MON_EVENT(QOS_L3_MBM_TOTAL_EVENT_ID, "mbm_total_bytes", RDT_RESOURCE_L3, false),
MON_EVENT(QOS_L3_MBM_LOCAL_EVENT_ID, "mbm_local_bytes", RDT_RESOURCE_L3, false),
+ MON_EVENT(QOS_L2_OCCUP_EVENT_ID, "l2c_occupancy", RDT_RESOURCE_L2, false),
+ MON_EVENT(QOS_L2_MBM_CORE_EVENT_ID, "mbm_core_bytes", RDT_RESOURCE_L2, false),
MON_EVENT(PMT_EVENT_ENERGY, "core_energy", RDT_RESOURCE_PERF_PKG, true),
MON_EVENT(PMT_EVENT_ACTIVITY, "activity", RDT_RESOURCE_PERF_PKG, true),
MON_EVENT(PMT_EVENT_STALLS_LLC_HIT, "stalls_llc_hit", RDT_RESOURCE_PERF_PKG, false),
diff --git a/include/linux/resctrl_types.h b/include/linux/resctrl_types.h
index a5f56faa18d2..f31b8f2ccb8b 100644
--- a/include/linux/resctrl_types.h
+++ b/include/linux/resctrl_types.h
@@ -37,7 +37,14 @@
/* Number of memory transactions that an MBM event can be configured with */
#define NUM_MBM_TRANSACTIONS 7
-/* Event IDs */
+/*
+ * Monitor Event IDs, representative a variety of monitoring events:
+ * QOS_L3_OCCUP_EVENT_ID: L3 Cache Occupancy statistics event
+ * QOS_L3_MBM_TOTAL_EVENT_ID: Global Memory Bandwidth statistics event
+ * QOS_L3_MBM_LOCAL_EVENT_ID: L3 Cache Bandwidth statistics event
+ * QOS_L2_OCCUP_EVENT_ID: L2 Cache Occupancy statistics event
+ * QOS_L2_MBM_CORE_EVENT_ID: L2 Cache Bandwidth statistics event
+ */
enum resctrl_event_id {
/* Must match value of first event below */
QOS_FIRST_EVENT = 0x01,
@@ -50,6 +57,10 @@ enum resctrl_event_id {
QOS_L3_MBM_TOTAL_EVENT_ID = 0x02,
QOS_L3_MBM_LOCAL_EVENT_ID = 0x03,
+ /* ARM MPAM L2 Events */
+ QOS_L2_OCCUP_EVENT_ID,
+ QOS_L2_MBM_CORE_EVENT_ID,
+
/* Intel Telemetry Events */
PMT_EVENT_ENERGY,
PMT_EVENT_ACTIVITY,
--
2.43.0