* [PATCH v6 01/10] x86/resctrl: Stop setting event_group::force_off on RMID shortage
2026-04-29 18:48 [PATCH v6 00/10] Allow AET to use PMT as loadable module Tony Luck
@ 2026-04-29 18:48 ` Tony Luck
2026-04-29 18:48 ` [PATCH v6 02/10] fs/resctrl: Add interface to disable a monitor event Tony Luck
` (8 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Tony Luck @ 2026-04-29 18:48 UTC (permalink / raw)
To: Fenghua Yu, Reinette Chatre, Maciej Wieczor-Retman, Peter Newman,
James Morse, Babu Moger, Drew Fustini, Dave Martin, Chen Yu,
David E Box, x86
Cc: Christoph Hellwig, linux-kernel, patches, Tony Luck
Drop the force_off assignment from all_regions_have_sufficient_rmid().
This preserves current single-enumeration behaviour while preparing for
the upcoming per-mount enumeration, where latching force_off would
incorrectly suppress re-enumeration on subsequent mounts - even when the
user explicitly requested the feature via "rdt={feature}".
Signed-off-by: Tony Luck <tony.luck@intel.com>
---
arch/x86/kernel/cpu/resctrl/intel_aet.c | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
diff --git a/arch/x86/kernel/cpu/resctrl/intel_aet.c b/arch/x86/kernel/cpu/resctrl/intel_aet.c
index 89b8b619d5d5..e2af700bca04 100644
--- a/arch/x86/kernel/cpu/resctrl/intel_aet.c
+++ b/arch/x86/kernel/cpu/resctrl/intel_aet.c
@@ -60,8 +60,8 @@ struct pmt_event {
* data for all telemetry regions of type @pfname.
* Valid if the system supports the event group,
* NULL otherwise.
- * @force_off: True when "rdt" command line or architecture code disables
- * this event group due to insufficient RMIDs.
+ * @force_off: True when "rdt" command line disables this event group
+ * to avoid system limitations due to insufficient RMIDs.
* @force_on: True when "rdt" command line overrides disable of this
* event group.
* @guid: Unique number per XML description file.
@@ -214,10 +214,8 @@ static bool all_regions_have_sufficient_rmid(struct event_group *e, struct pmt_f
if (!p->regions[i].addr)
continue;
tr = &p->regions[i];
- if (tr->num_rmids < e->num_rmid) {
- e->force_off = true;
+ if (tr->num_rmids < e->num_rmid)
return false;
- }
}
return true;
--
2.53.0
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH v6 02/10] fs/resctrl: Add interface to disable a monitor event
2026-04-29 18:48 [PATCH v6 00/10] Allow AET to use PMT as loadable module Tony Luck
2026-04-29 18:48 ` [PATCH v6 01/10] x86/resctrl: Stop setting event_group::force_off on RMID shortage Tony Luck
@ 2026-04-29 18:48 ` Tony Luck
2026-04-29 18:48 ` [PATCH v6 03/10] x86/resctrl: Maintain a count of enabled monitor features Tony Luck
` (7 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Tony Luck @ 2026-04-29 18:48 UTC (permalink / raw)
To: Fenghua Yu, Reinette Chatre, Maciej Wieczor-Retman, Peter Newman,
James Morse, Babu Moger, Drew Fustini, Dave Martin, Chen Yu,
David E Box, x86
Cc: Christoph Hellwig, linux-kernel, patches, Tony Luck
In preparation for re-running AET enumeration on every mount, AET code must be
able to disable events on unmount so the next mount starts from a clean slate.
Add a file system interface for architecture to clear the enabled flag for
a given event.
Add kerneldoc comments to describe limitations on when events may be enabled
or disabled.
Signed-off-by: Tony Luck <tony.luck@intel.com>
---
include/linux/resctrl.h | 34 ++++++++++++++++++++++++++++++++++
fs/resctrl/monitor.c | 12 ++++++++++++
2 files changed, 46 insertions(+)
diff --git a/include/linux/resctrl.h b/include/linux/resctrl.h
index 006e57fd7ca5..a8338656f836 100644
--- a/include/linux/resctrl.h
+++ b/include/linux/resctrl.h
@@ -414,9 +414,43 @@ u32 resctrl_arch_get_num_closid(struct rdt_resource *r);
u32 resctrl_arch_system_num_rmid_idx(void);
int resctrl_arch_update_domains(struct rdt_resource *r, u32 closid);
+/**
+ * resctrl_enable_mon_event() - Enable monitoring event
+ * @eventid: ID of the event
+ * @any_cpu: True if event data can be read from any CPU.
+ * @binary_bits:Number of binary places of the fixed-point value expected to
+ * back a floating point event. Can only be set for floating point
+ * events.
+ * @arch_priv: Architecture private data associated with event. Passed back to
+ * architecture when reading the event via resctrl_arch_rmid_read().
+ *
+ * The file system must not be mounted when enabling an event.
+ *
+ * Events that require per-domain (architectural and/or filesystem) state must
+ * be enabled before the domain structures are allocated. For example before
+ * CPU hotplug callbacks that allocate domain structures are registered. If the
+ * architecture discovers a resource after initialization it should enable
+ * events needing per-domain state before any domain structure allocation which
+ * should be coordinated with the CPU hotplug callbacks.
+ *
+ * Return:
+ * true if event was successfully enabled, false otherwise.
+ */
bool resctrl_enable_mon_event(enum resctrl_event_id eventid, bool any_cpu,
unsigned int binary_bits, void *arch_priv);
+/**
+ * resctrl_disable_mon_event() - Disable monitoring event
+ * @eventid: ID of the event
+ *
+ * The file system must not be mounted when disabling an event.
+ *
+ * Events that require per-domain (architectural and/or filesystem) state
+ * will require additional cleanup which should be coordinated with the CPU
+ * hotplug callbacks.
+ */
+void resctrl_disable_mon_event(enum resctrl_event_id eventid);
+
bool resctrl_is_mon_event_enabled(enum resctrl_event_id eventid);
bool resctrl_arch_is_evt_configurable(enum resctrl_event_id evt);
diff --git a/fs/resctrl/monitor.c b/fs/resctrl/monitor.c
index 9fd901c78dc6..327e7a863614 100644
--- a/fs/resctrl/monitor.c
+++ b/fs/resctrl/monitor.c
@@ -1012,6 +1012,18 @@ bool resctrl_enable_mon_event(enum resctrl_event_id eventid, bool any_cpu,
return true;
}
+void resctrl_disable_mon_event(enum resctrl_event_id eventid)
+{
+ if (WARN_ON_ONCE(eventid < QOS_FIRST_EVENT || eventid >= QOS_NUM_EVENTS))
+ return;
+ if (!mon_event_all[eventid].enabled) {
+ pr_warn("Repeat disable for event %d\n", eventid);
+ return;
+ }
+
+ mon_event_all[eventid].enabled = false;
+}
+
bool resctrl_is_mon_event_enabled(enum resctrl_event_id eventid)
{
return eventid >= QOS_FIRST_EVENT && eventid < QOS_NUM_EVENTS &&
--
2.53.0
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH v6 03/10] x86/resctrl: Maintain a count of enabled monitor features
2026-04-29 18:48 [PATCH v6 00/10] Allow AET to use PMT as loadable module Tony Luck
2026-04-29 18:48 ` [PATCH v6 01/10] x86/resctrl: Stop setting event_group::force_off on RMID shortage Tony Luck
2026-04-29 18:48 ` [PATCH v6 02/10] fs/resctrl: Add interface to disable a monitor event Tony Luck
@ 2026-04-29 18:48 ` Tony Luck
2026-04-29 18:48 ` [PATCH v6 04/10] fs,x86,mpam/resctrl: Handle change in number of RMIDs on each mount Tony Luck
` (6 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Tony Luck @ 2026-04-29 18:48 UTC (permalink / raw)
To: Fenghua Yu, Reinette Chatre, Maciej Wieczor-Retman, Peter Newman,
James Morse, Babu Moger, Drew Fustini, Dave Martin, Chen Yu,
David E Box, x86
Cc: Christoph Hellwig, linux-kernel, patches, Tony Luck
AET (Application Energy Telemetry) may be enabled/disabled from one mount
to the next depending on whether the pmt_telemetry module is loaded. If
AET is the only monitoring feature supported on a system and it is enabled
in one mount, but disabled in a subsequent mount this will result in empty
mon_data directories.
Change from a boolean to a count of enabled monitor features inside
architecture code. File system code only needs to know if any monitor
features are enabled so resctrl_arch_mon_capable() can still return
boolean.
Signed-off-by: Tony Luck <tony.luck@intel.com>
---
arch/x86/include/asm/resctrl.h | 4 ++--
arch/x86/kernel/cpu/resctrl/internal.h | 2 +-
arch/x86/kernel/cpu/resctrl/core.c | 24 +++++++++++++-----------
arch/x86/kernel/cpu/resctrl/monitor.c | 11 +++--------
4 files changed, 19 insertions(+), 22 deletions(-)
diff --git a/arch/x86/include/asm/resctrl.h b/arch/x86/include/asm/resctrl.h
index 575f8408a9e7..1e50c7dc3fe3 100644
--- a/arch/x86/include/asm/resctrl.h
+++ b/arch/x86/include/asm/resctrl.h
@@ -43,7 +43,7 @@ struct resctrl_pqr_state {
DECLARE_PER_CPU(struct resctrl_pqr_state, pqr_state);
extern bool rdt_alloc_capable;
-extern bool rdt_mon_capable;
+extern int rdt_mon_feature_count;
DECLARE_STATIC_KEY_FALSE(rdt_enable_key);
DECLARE_STATIC_KEY_FALSE(rdt_alloc_enable_key);
@@ -68,7 +68,7 @@ static inline void resctrl_arch_disable_alloc(void)
static inline bool resctrl_arch_mon_capable(void)
{
- return rdt_mon_capable;
+ return !!rdt_mon_feature_count;
}
static inline void resctrl_arch_enable_mon(void)
diff --git a/arch/x86/kernel/cpu/resctrl/internal.h b/arch/x86/kernel/cpu/resctrl/internal.h
index e3cfa0c10e92..3b09cfe9a046 100644
--- a/arch/x86/kernel/cpu/resctrl/internal.h
+++ b/arch/x86/kernel/cpu/resctrl/internal.h
@@ -224,7 +224,7 @@ union l3_qos_abmc_cfg {
void rdt_ctrl_update(void *arg);
-int rdt_get_l3_mon_config(struct rdt_resource *r);
+void rdt_get_l3_mon_config(struct rdt_resource *r);
bool rdt_cpu_has(int flag);
diff --git a/arch/x86/kernel/cpu/resctrl/core.c b/arch/x86/kernel/cpu/resctrl/core.c
index 7667cf7c4e94..1af8f965fdd0 100644
--- a/arch/x86/kernel/cpu/resctrl/core.c
+++ b/arch/x86/kernel/cpu/resctrl/core.c
@@ -779,7 +779,7 @@ void resctrl_arch_pre_mount(void)
cpus_read_lock();
mutex_lock(&domain_list_lock);
r->mon_capable = true;
- rdt_mon_capable = true;
+ rdt_mon_feature_count++;
for_each_online_cpu(cpu)
domain_add_cpu_mon(cpu, r);
mutex_unlock(&domain_list_lock);
@@ -959,30 +959,32 @@ static __init bool get_rdt_alloc_resources(void)
return ret;
}
-static __init bool get_rdt_mon_resources(void)
+static __init int get_rdt_mon_resources(void)
{
struct rdt_resource *r = &rdt_resources_all[RDT_RESOURCE_L3].r_resctrl;
- bool ret = false;
+ int ret = 0;
if (rdt_cpu_has(X86_FEATURE_CQM_OCCUP_LLC)) {
resctrl_enable_mon_event(QOS_L3_OCCUP_EVENT_ID, false, 0, NULL);
- ret = true;
+ ret++;
}
if (rdt_cpu_has(X86_FEATURE_CQM_MBM_TOTAL)) {
resctrl_enable_mon_event(QOS_L3_MBM_TOTAL_EVENT_ID, false, 0, NULL);
- ret = true;
+ ret++;
}
if (rdt_cpu_has(X86_FEATURE_CQM_MBM_LOCAL)) {
resctrl_enable_mon_event(QOS_L3_MBM_LOCAL_EVENT_ID, false, 0, NULL);
- ret = true;
+ ret++;
}
if (rdt_cpu_has(X86_FEATURE_ABMC))
- ret = true;
+ ret++;
if (!ret)
- return false;
+ return 0;
- return !rdt_get_l3_mon_config(r);
+ rdt_get_l3_mon_config(r);
+
+ return ret;
}
static __init void __check_quirks_intel(void)
@@ -1013,9 +1015,9 @@ static __init void check_quirks(void)
static __init bool get_rdt_resources(void)
{
rdt_alloc_capable = get_rdt_alloc_resources();
- rdt_mon_capable = get_rdt_mon_resources();
+ rdt_mon_feature_count = get_rdt_mon_resources();
- return (rdt_mon_capable || rdt_alloc_capable);
+ return (rdt_mon_feature_count || rdt_alloc_capable);
}
static __init void rdt_init_res_defs_intel(void)
diff --git a/arch/x86/kernel/cpu/resctrl/monitor.c b/arch/x86/kernel/cpu/resctrl/monitor.c
index 9bd87bae4983..497cc57ac135 100644
--- a/arch/x86/kernel/cpu/resctrl/monitor.c
+++ b/arch/x86/kernel/cpu/resctrl/monitor.c
@@ -25,11 +25,8 @@
#include "internal.h"
-/*
- * Global boolean for rdt_monitor which is true if any
- * resource monitoring is enabled.
- */
-bool rdt_mon_capable;
+/* Global count of number of resource monitor functions that are enabled. */
+int rdt_mon_feature_count;
#define CF(cf) ((unsigned long)(1048576 * (cf) + 0.5))
@@ -402,7 +399,7 @@ static __init int snc_get_config(void)
return ret;
}
-int __init rdt_get_l3_mon_config(struct rdt_resource *r)
+void __init rdt_get_l3_mon_config(struct rdt_resource *r)
{
unsigned int mbm_offset = boot_cpu_data.x86_cache_mbm_width_offset;
struct rdt_hw_resource *hw_res = resctrl_to_arch_res(r);
@@ -460,8 +457,6 @@ int __init rdt_get_l3_mon_config(struct rdt_resource *r)
}
r->mon_capable = true;
-
- return 0;
}
void __init intel_rdt_mbm_apply_quirk(void)
--
2.53.0
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH v6 04/10] fs,x86,mpam/resctrl: Handle change in number of RMIDs on each mount
2026-04-29 18:48 [PATCH v6 00/10] Allow AET to use PMT as loadable module Tony Luck
` (2 preceding siblings ...)
2026-04-29 18:48 ` [PATCH v6 03/10] x86/resctrl: Maintain a count of enabled monitor features Tony Luck
@ 2026-04-29 18:48 ` Tony Luck
2026-04-29 18:48 ` [PATCH v6 05/10] x86/resctrl: x86/resctrl: Add PMT registration API for AET enumeration callbacks Tony Luck
` (5 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Tony Luck @ 2026-04-29 18:48 UTC (permalink / raw)
To: Fenghua Yu, Reinette Chatre, Maciej Wieczor-Retman, Peter Newman,
James Morse, Babu Moger, Drew Fustini, Dave Martin, Chen Yu,
David E Box, x86
Cc: Christoph Hellwig, linux-kernel, patches, Tony Luck
Application Energy Telemetry (AET) event enumeration takes place
asynchronously. Linux builds the pmt_telemetry module into the kernel to
kick of enumeration early enough that it completes before first mount of
the resctrl file system.
Allowing pmt_telemetry to be a loadable module means that it is possible
for different numbers of RMIDs to be supported on each mount, depending
on whether pmt_telemetry module is loaded.
Add resctrl_arch_system_max_rmid_idx() interface to provide the maximum
supported number of RMIDs on a system. For x86 this is RDT_RESOURCE_L3
rdt_resource::mon.num_rmid (if L3 monitoring is enabled).
Allocate the rmid_ptrs, rdt_l3_mon_domain::rmid_busy_llc, and
rdt_l3_mon_domain::mbm_states based on the maximum possible.
Initialize rmid_free_lru based on the number of RMIDs available for
this mount.
Note that some RMIDs may still be marked busy from a previous mount.
Don't add these to the free list. Check current RMID limit in
limbo_release_entry() and do not add out of range RMIDs to the
free list.
Signed-off-by: Tony Luck <tony.luck@intel.com>
---
include/linux/resctrl.h | 1 +
arch/x86/kernel/cpu/resctrl/core.c | 12 ++++++++
drivers/resctrl/mpam_resctrl.c | 5 ++++
fs/resctrl/monitor.c | 47 ++++++++++++++++++++----------
fs/resctrl/rdtgroup.c | 2 +-
5 files changed, 50 insertions(+), 17 deletions(-)
diff --git a/include/linux/resctrl.h b/include/linux/resctrl.h
index a8338656f836..3705f0214fa6 100644
--- a/include/linux/resctrl.h
+++ b/include/linux/resctrl.h
@@ -412,6 +412,7 @@ static inline u32 resctrl_get_default_ctrl(struct rdt_resource *r)
/* The number of closid supported by this resource regardless of CDP */
u32 resctrl_arch_get_num_closid(struct rdt_resource *r);
u32 resctrl_arch_system_num_rmid_idx(void);
+u32 resctrl_arch_system_max_rmid_idx(void);
int resctrl_arch_update_domains(struct rdt_resource *r, u32 closid);
/**
diff --git a/arch/x86/kernel/cpu/resctrl/core.c b/arch/x86/kernel/cpu/resctrl/core.c
index 1af8f965fdd0..934492c7e643 100644
--- a/arch/x86/kernel/cpu/resctrl/core.c
+++ b/arch/x86/kernel/cpu/resctrl/core.c
@@ -129,6 +129,18 @@ u32 resctrl_arch_system_num_rmid_idx(void)
return num_rmids == U32_MAX ? 0 : num_rmids;
}
+/**
+ * resctrl_arch_system_max_rmid_idx - Largest possible number of RMIDs
+ *
+ * Return: If L3 monitoring is supported, largest possible comes from L3.
+ */
+u32 resctrl_arch_system_max_rmid_idx(void)
+{
+ struct rdt_resource *r = &rdt_resources_all[RDT_RESOURCE_L3].r_resctrl;
+
+ return r->mon_capable ? r->mon.num_rmid : resctrl_arch_system_num_rmid_idx();
+}
+
struct rdt_resource *resctrl_arch_get_resource(enum resctrl_res_level l)
{
if (l >= RDT_NUM_RESOURCES)
diff --git a/drivers/resctrl/mpam_resctrl.c b/drivers/resctrl/mpam_resctrl.c
index 226ff6f532fa..7079870ca894 100644
--- a/drivers/resctrl/mpam_resctrl.c
+++ b/drivers/resctrl/mpam_resctrl.c
@@ -272,6 +272,11 @@ u32 resctrl_arch_system_num_rmid_idx(void)
return (mpam_pmg_max + 1) * (mpam_partid_max + 1);
}
+u32 resctrl_arch_system_max_rmid_idx(void)
+{
+ return resctrl_arch_system_num_rmid_idx();
+}
+
u32 resctrl_arch_rmid_idx_encode(u32 closid, u32 rmid)
{
return closid * (mpam_pmg_max + 1) + rmid;
diff --git a/fs/resctrl/monitor.c b/fs/resctrl/monitor.c
index 327e7a863614..cabf59afd39e 100644
--- a/fs/resctrl/monitor.c
+++ b/fs/resctrl/monitor.c
@@ -115,10 +115,17 @@ static inline struct rmid_entry *__rmid_entry(u32 idx)
static void limbo_release_entry(struct rmid_entry *entry)
{
+ u32 idx_limit = resctrl_arch_system_num_rmid_idx();
lockdep_assert_held(&rdtgroup_mutex);
rmid_limbo_count--;
- list_add_tail(&entry->list, &rmid_free_lru);
+
+ /*
+ * Limbo may be freeing an RMID from a previous mount where there
+ * were more RMIDs available.
+ */
+ if (resctrl_arch_rmid_idx_encode(entry->closid, entry->rmid) < idx_limit)
+ list_add_tail(&entry->list, &rmid_free_lru);
if (IS_ENABLED(CONFIG_RESCTRL_RMID_DEPENDS_ON_CLOSID))
closid_num_dirty_rmid[entry->closid]--;
@@ -133,7 +140,7 @@ static void limbo_release_entry(struct rmid_entry *entry)
void __check_limbo(struct rdt_l3_mon_domain *d, bool force_free)
{
struct rdt_resource *r = resctrl_arch_get_resource(RDT_RESOURCE_L3);
- u32 idx_limit = resctrl_arch_system_num_rmid_idx();
+ u32 idx_limit = resctrl_arch_system_max_rmid_idx();
struct rmid_entry *entry;
u32 idx, cur_idx = 1;
void *arch_mon_ctx;
@@ -192,7 +199,7 @@ void __check_limbo(struct rdt_l3_mon_domain *d, bool force_free)
bool has_busy_rmid(struct rdt_l3_mon_domain *d)
{
- u32 idx_limit = resctrl_arch_system_num_rmid_idx();
+ u32 idx_limit = resctrl_arch_system_max_rmid_idx();
return find_first_bit(d->rmid_busy_llc, idx_limit) != idx_limit;
}
@@ -916,24 +923,32 @@ int setup_rmid_lru_list(void)
return 0;
/*
- * Called on every mount, but the number of RMIDs cannot change
- * after the first mount, so keep using the same set of rmid_ptrs[]
- * until resctrl_exit(). Note that the limbo handler continues to
- * access rmid_ptrs[] after resctrl is unmounted.
+ * Allocate the largest number of RMIDs that this system will ever
+ * need. These cannot be freed until resctrl_exit() because the limbo
+ * handler continues to access rmid_ptrs[] after resctrl is unmounted.
*/
- if (rmid_ptrs)
- return 0;
+ if (!rmid_ptrs) {
+ idx_limit = resctrl_arch_system_max_rmid_idx();
+ rmid_ptrs = kzalloc_objs(struct rmid_entry, idx_limit);
+ if (!rmid_ptrs)
+ return -ENOMEM;
+
+ for (i = 0; i < idx_limit; i++) {
+ entry = &rmid_ptrs[i];
+ INIT_LIST_HEAD(&entry->list);
+
+ resctrl_arch_rmid_idx_decode(i, &entry->closid, &entry->rmid);
+ }
+ }
+ /* Find how many RMIDs are needed for this mount */
idx_limit = resctrl_arch_system_num_rmid_idx();
- rmid_ptrs = kzalloc_objs(struct rmid_entry, idx_limit);
- if (!rmid_ptrs)
- return -ENOMEM;
+ INIT_LIST_HEAD(&rmid_free_lru);
for (i = 0; i < idx_limit; i++) {
entry = &rmid_ptrs[i];
- INIT_LIST_HEAD(&entry->list);
-
- resctrl_arch_rmid_idx_decode(i, &entry->closid, &entry->rmid);
+ if (i && entry->busy)
+ continue;
list_add_tail(&entry->list, &rmid_free_lru);
}
@@ -1156,7 +1171,7 @@ static void mbm_cntr_free_all(struct rdt_resource *r, struct rdt_l3_mon_domain *
*/
static void resctrl_reset_rmid_all(struct rdt_resource *r, struct rdt_l3_mon_domain *d)
{
- u32 idx_limit = resctrl_arch_system_num_rmid_idx();
+ u32 idx_limit = resctrl_arch_system_max_rmid_idx();
enum resctrl_event_id evt;
int idx;
diff --git a/fs/resctrl/rdtgroup.c b/fs/resctrl/rdtgroup.c
index 5dfdaa6f9d8f..2e31ff753114 100644
--- a/fs/resctrl/rdtgroup.c
+++ b/fs/resctrl/rdtgroup.c
@@ -4373,7 +4373,7 @@ void resctrl_offline_mon_domain(struct rdt_resource *r, struct rdt_domain_hdr *h
*/
static int domain_setup_l3_mon_state(struct rdt_resource *r, struct rdt_l3_mon_domain *d)
{
- u32 idx_limit = resctrl_arch_system_num_rmid_idx();
+ u32 idx_limit = resctrl_arch_system_max_rmid_idx();
size_t tsize = sizeof(*d->mbm_states[0]);
enum resctrl_event_id eventid;
int idx;
--
2.53.0
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH v6 05/10] x86/resctrl: x86/resctrl: Add PMT registration API for AET enumeration callbacks
2026-04-29 18:48 [PATCH v6 00/10] Allow AET to use PMT as loadable module Tony Luck
` (3 preceding siblings ...)
2026-04-29 18:48 ` [PATCH v6 04/10] fs,x86,mpam/resctrl: Handle change in number of RMIDs on each mount Tony Luck
@ 2026-04-29 18:48 ` Tony Luck
2026-04-29 18:48 ` [PATCH v6 06/10] platform/x86/intel/pmt: Register enumeration functions with resctrl Tony Luck
` (4 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Tony Luck @ 2026-04-29 18:48 UTC (permalink / raw)
To: Fenghua Yu, Reinette Chatre, Maciej Wieczor-Retman, Peter Newman,
James Morse, Babu Moger, Drew Fustini, Dave Martin, Chen Yu,
David E Box, x86
Cc: Christoph Hellwig, linux-kernel, patches, Tony Luck
resctrl is always built-in; INTEL_PMT_TELEMETRY may be a module. Add, and
export, register/unregister functions so the PMT module can supply/clear
enumeration callback functions when loaded/unloaded.
Suggested-by: Christoph Hellwig <hch@infradead.org>
Signed-off-by: Tony Luck <tony.luck@intel.com>
---
arch/x86/include/asm/resctrl.h | 19 ++++++++++++++
arch/x86/kernel/cpu/resctrl/intel_aet.c | 35 +++++++++++++++++++++++++
2 files changed, 54 insertions(+)
diff --git a/arch/x86/include/asm/resctrl.h b/arch/x86/include/asm/resctrl.h
index 1e50c7dc3fe3..7c929b72098c 100644
--- a/arch/x86/include/asm/resctrl.h
+++ b/arch/x86/include/asm/resctrl.h
@@ -4,6 +4,8 @@
#ifdef CONFIG_X86_CPU_RESCTRL
+#include <linux/intel_pmt_features.h>
+#include <linux/intel_vsec.h>
#include <linux/jump_label.h>
#include <linux/percpu.h>
#include <linux/resctrl_types.h>
@@ -193,11 +195,28 @@ static inline void resctrl_arch_mon_ctx_free(struct rdt_resource *r,
void resctrl_cpu_detect(struct cpuinfo_x86 *c);
+#ifdef CONFIG_X86_CPU_RESCTRL_INTEL_AET
+void intel_aet_register_enumeration(struct pmt_feature_group *(*get)(enum pmt_feature_id id),
+ void (*put)(struct pmt_feature_group *p));
+void intel_aet_unregister_enumeration(void);
#else
+static inline void intel_aet_register_enumeration(struct pmt_feature_group *(*get)(enum pmt_feature_id id),
+ void (*put)(struct pmt_feature_group *p)) { }
+static inline void intel_aet_unregister_enumeration(void) { }
+#endif /* CONFIG_X86_CPU_RESCTRL_INTEL_AET */
+
+#else
+
+#include <linux/intel_pmt_features.h>
+#include <linux/intel_vsec.h>
static inline void resctrl_arch_sched_in(struct task_struct *tsk) {}
static inline void resctrl_cpu_detect(struct cpuinfo_x86 *c) {}
+static inline void intel_aet_register_enumeration(struct pmt_feature_group *(*get)(enum pmt_feature_id id),
+ void (*put)(struct pmt_feature_group *p)) { }
+static inline void intel_aet_unregister_enumeration(void) { }
+
#endif /* CONFIG_X86_CPU_RESCTRL */
#endif /* _ASM_X86_RESCTRL_H */
diff --git a/arch/x86/kernel/cpu/resctrl/intel_aet.c b/arch/x86/kernel/cpu/resctrl/intel_aet.c
index e2af700bca04..2b3677783427 100644
--- a/arch/x86/kernel/cpu/resctrl/intel_aet.c
+++ b/arch/x86/kernel/cpu/resctrl/intel_aet.c
@@ -12,17 +12,21 @@
#define pr_fmt(fmt) "resctrl: " fmt
#include <linux/bits.h>
+#include <linux/cleanup.h>
#include <linux/compiler_types.h>
#include <linux/container_of.h>
#include <linux/cpumask.h>
#include <linux/err.h>
#include <linux/errno.h>
+#include <linux/export.h>
#include <linux/gfp_types.h>
#include <linux/init.h>
#include <linux/intel_pmt_features.h>
#include <linux/intel_vsec.h>
#include <linux/io.h>
#include <linux/minmax.h>
+#include <linux/mutex.h>
+#include <linux/module.h>
#include <linux/printk.h>
#include <linux/rculist.h>
#include <linux/rcupdate.h>
@@ -289,6 +293,9 @@ static enum pmt_feature_id lookup_pfid(const char *pfname)
return FEATURE_INVALID;
}
+static struct pmt_feature_group *(*get_feature)(enum pmt_feature_id id);
+static void (*put_feature)(struct pmt_feature_group *p);
+
/*
* Request a copy of struct pmt_feature_group for each event group. If there is
* one, the returned structure has an array of telemetry_region structures,
@@ -323,6 +330,25 @@ bool intel_aet_get_events(void)
return ret;
}
+static DEFINE_MUTEX(aet_register_lock);
+
+void intel_aet_register_enumeration(struct pmt_feature_group *(*get)(enum pmt_feature_id id),
+ void (*put)(struct pmt_feature_group *p))
+{
+ guard(mutex)(&aet_register_lock);
+ get_feature = get;
+ put_feature = put;
+}
+EXPORT_SYMBOL_GPL(intel_aet_register_enumeration);
+
+void intel_aet_unregister_enumeration(void)
+{
+ guard(mutex)(&aet_register_lock);
+ get_feature = NULL;
+ put_feature = NULL;
+}
+EXPORT_SYMBOL_GPL(intel_aet_unregister_enumeration);
+
void __exit intel_aet_exit(void)
{
struct event_group **peg;
@@ -405,3 +431,12 @@ void intel_aet_mon_domain_setup(int cpu, int id, struct rdt_resource *r,
kfree(d);
}
}
+
+static int __init intel_aet_init(void)
+{
+ request_module("pmt_telemetry");
+
+ return 0;
+}
+
+late_initcall(intel_aet_init);
--
2.53.0
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH v6 06/10] platform/x86/intel/pmt: Register enumeration functions with resctrl
2026-04-29 18:48 [PATCH v6 00/10] Allow AET to use PMT as loadable module Tony Luck
` (4 preceding siblings ...)
2026-04-29 18:48 ` [PATCH v6 05/10] x86/resctrl: x86/resctrl: Add PMT registration API for AET enumeration callbacks Tony Luck
@ 2026-04-29 18:48 ` Tony Luck
2026-04-29 18:48 ` [PATCH v6 07/10] x86/resctrl: Resolve INTEL_PMT_TELEMETRY symbols at runtime Tony Luck
` (3 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Tony Luck @ 2026-04-29 18:48 UTC (permalink / raw)
To: Fenghua Yu, Reinette Chatre, Maciej Wieczor-Retman, Peter Newman,
James Morse, Babu Moger, Drew Fustini, Dave Martin, Chen Yu,
David E Box, x86
Cc: Christoph Hellwig, linux-kernel, patches, Tony Luck
INTEL_PMT_TELEMETRY is a loadable module, but resctrl is built-in and cannot
call PMT functions directly. Register the telemetry enumeration function
pointers at pmt_telemetry module init, and unregister them at module exit.
Add module_{get,put} calls to the PMT get/put functions to ensure that
INTEL_PMT_TELEMETRY cannot be unloaded while resctrl is mounted and
referencing the MMIO register space mapped by INTEL_PMT_TELEMETRY.
Note that checkpatch complains about the #include of <asm/resctrl.h>.
This is needed rather than <linux/resctrl.h> to get the function stub
definitions when CONFIG_X86_CPU_RESCTRL=n.
Suggested-by: Christoph Hellwig <hch@infradead.org>
Signed-off-by: Tony Luck <tony.luck@intel.com>
---
drivers/platform/x86/intel/pmt/telemetry.c | 17 ++++++++++++++++-
1 file changed, 16 insertions(+), 1 deletion(-)
diff --git a/drivers/platform/x86/intel/pmt/telemetry.c b/drivers/platform/x86/intel/pmt/telemetry.c
index bdc7c24a3678..0088027c1b15 100644
--- a/drivers/platform/x86/intel/pmt/telemetry.c
+++ b/drivers/platform/x86/intel/pmt/telemetry.c
@@ -25,6 +25,8 @@
#include <linux/uaccess.h>
#include <linux/xarray.h>
+#include <asm/resctrl.h>
+
#include "class.h"
#define TELEM_SIZE_OFFSET 0x0
@@ -284,6 +286,9 @@ struct pmt_feature_group *intel_pmt_get_regions_by_feature(enum pmt_feature_id i
region++;
}
+ if (!try_module_get(THIS_MODULE))
+ return ERR_PTR(-EINVAL);
+
kref_init(&feature_group->kref);
return no_free_ptr(feature_group);
@@ -293,6 +298,7 @@ EXPORT_SYMBOL(intel_pmt_get_regions_by_feature);
void intel_pmt_put_feature_group(struct pmt_feature_group *feature_group)
{
kref_put(&feature_group->kref, pmt_feature_group_release);
+ module_put(THIS_MODULE);
}
EXPORT_SYMBOL(intel_pmt_put_feature_group);
@@ -425,7 +431,15 @@ static struct auxiliary_driver pmt_telem_aux_driver = {
static int __init pmt_telem_init(void)
{
- return auxiliary_driver_register(&pmt_telem_aux_driver);
+ int ret;
+
+ ret = auxiliary_driver_register(&pmt_telem_aux_driver);
+ if (ret)
+ return ret;
+
+ intel_aet_register_enumeration(intel_pmt_get_regions_by_feature,
+ intel_pmt_put_feature_group);
+ return 0;
}
module_init(pmt_telem_init);
@@ -433,6 +447,7 @@ static void __exit pmt_telem_exit(void)
{
auxiliary_driver_unregister(&pmt_telem_aux_driver);
xa_destroy(&telem_array);
+ intel_aet_unregister_enumeration();
}
module_exit(pmt_telem_exit);
--
2.53.0
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH v6 07/10] x86/resctrl: Resolve INTEL_PMT_TELEMETRY symbols at runtime
2026-04-29 18:48 [PATCH v6 00/10] Allow AET to use PMT as loadable module Tony Luck
` (5 preceding siblings ...)
2026-04-29 18:48 ` [PATCH v6 06/10] platform/x86/intel/pmt: Register enumeration functions with resctrl Tony Luck
@ 2026-04-29 18:48 ` Tony Luck
2026-04-29 18:48 ` [PATCH v6 08/10] fs/resctrl: Call architecture hooks for every mount/unmount Tony Luck
` (2 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Tony Luck @ 2026-04-29 18:48 UTC (permalink / raw)
To: Fenghua Yu, Reinette Chatre, Maciej Wieczor-Retman, Peter Newman,
James Morse, Babu Moger, Drew Fustini, Dave Martin, Chen Yu,
David E Box, x86
Cc: Christoph Hellwig, linux-kernel, patches, Tony Luck
resctrl is always built-in, but INTEL_PMT_TELEMETRY and INTEL_TPMI are
logically independent and should be loadable modules. Switch AET to use
the function-pointer registration API (introduced in the preceding patch)
instead of direct link-time references to PMT symbols.
Move AET enumeration into resctrl_arch_pre_mount() and cleanup into
resctrl_arch_unmount() so the PMT module can be unloaded whenever the
filesystem is not mounted. Because all cleanup now happens in the unmount
path, intel_aet_exit() is no longer needed and is removed.
Note that the Linux file system code does not serialize calls to
fs_context_operations::get_tree(), so there may be arbitrarily many
parallel calls if users invoke mount(2) multiple times.
Add locking and state (resctrl_arch_mount_entries) to only perform enumeration
of first mount, and cleanup on last unmount.
event_group::num_rmid may be reset (reduced) during enumeration. This is
not worth resetting on unmount because the same reduction would occur on
each subsequent mount.
Signed-off-by: Tony Luck <tony.luck@intel.com>
---
include/linux/resctrl.h | 3 ++
arch/x86/kernel/cpu/resctrl/internal.h | 8 ++---
arch/x86/kernel/cpu/resctrl/core.c | 41 +++++++++++++++++++++++--
arch/x86/kernel/cpu/resctrl/intel_aet.c | 26 ++++++++++++----
4 files changed, 65 insertions(+), 13 deletions(-)
diff --git a/include/linux/resctrl.h b/include/linux/resctrl.h
index 3705f0214fa6..9534d42e0c57 100644
--- a/include/linux/resctrl.h
+++ b/include/linux/resctrl.h
@@ -557,6 +557,9 @@ void resctrl_offline_cpu(unsigned int cpu);
*/
void resctrl_arch_pre_mount(void);
+/* Called to report unmount. */
+void resctrl_arch_unmount(void);
+
/**
* resctrl_arch_rmid_read() - Read the eventid counter corresponding to rmid
* for this resource and domain.
diff --git a/arch/x86/kernel/cpu/resctrl/internal.h b/arch/x86/kernel/cpu/resctrl/internal.h
index 3b09cfe9a046..017a19143ec9 100644
--- a/arch/x86/kernel/cpu/resctrl/internal.h
+++ b/arch/x86/kernel/cpu/resctrl/internal.h
@@ -234,15 +234,15 @@ void rdt_domain_reconfigure_cdp(struct rdt_resource *r);
void resctrl_arch_mbm_cntr_assign_set_one(struct rdt_resource *r);
#ifdef CONFIG_X86_CPU_RESCTRL_INTEL_AET
-bool intel_aet_get_events(void);
-void __exit intel_aet_exit(void);
+bool intel_aet_pre_mount(void);
+void intel_aet_unmount(void);
int intel_aet_read_event(int domid, u32 rmid, void *arch_priv, u64 *val);
void intel_aet_mon_domain_setup(int cpu, int id, struct rdt_resource *r,
struct list_head *add_pos);
bool intel_handle_aet_option(bool force_off, char *tok);
#else
-static inline bool intel_aet_get_events(void) { return false; }
-static inline void __exit intel_aet_exit(void) { }
+static inline bool intel_aet_pre_mount(void) { return false; }
+static inline void intel_aet_unmount(void) { }
static inline int intel_aet_read_event(int domid, u32 rmid, void *arch_priv, u64 *val)
{
return -EINVAL;
diff --git a/arch/x86/kernel/cpu/resctrl/core.c b/arch/x86/kernel/cpu/resctrl/core.c
index 934492c7e643..9336299b9647 100644
--- a/arch/x86/kernel/cpu/resctrl/core.c
+++ b/arch/x86/kernel/cpu/resctrl/core.c
@@ -16,10 +16,12 @@
#define pr_fmt(fmt) "resctrl: " fmt
+#include <linux/cleanup.h>
#include <linux/cpu.h>
#include <linux/slab.h>
#include <linux/err.h>
#include <linux/cpuhotplug.h>
+#include <linux/mutex.h>
#include <asm/cpu_device_id.h>
#include <asm/msr.h>
@@ -776,12 +778,20 @@ static int resctrl_arch_offline_cpu(unsigned int cpu)
return 0;
}
+static DEFINE_MUTEX(resctrl_arch_mount_lock);
+static int resctrl_arch_mount_entries;
+
void resctrl_arch_pre_mount(void)
{
struct rdt_resource *r = &rdt_resources_all[RDT_RESOURCE_PERF_PKG].r_resctrl;
int cpu;
- if (!intel_aet_get_events())
+ guard(mutex)(&resctrl_arch_mount_lock);
+
+ if (++resctrl_arch_mount_entries > 1)
+ return;
+
+ if (!intel_aet_pre_mount())
return;
/*
@@ -798,6 +808,33 @@ void resctrl_arch_pre_mount(void)
cpus_read_unlock();
}
+void resctrl_arch_unmount(void)
+{
+ struct rdt_resource *r = &rdt_resources_all[RDT_RESOURCE_PERF_PKG].r_resctrl;
+ int cpu;
+
+ guard(mutex)(&resctrl_arch_mount_lock);
+
+ if (--resctrl_arch_mount_entries > 0)
+ return;
+
+ WARN_ON(resctrl_arch_mount_entries < 0);
+
+ intel_aet_unmount();
+
+ if (!r->mon_capable)
+ return;
+
+ cpus_read_lock();
+ mutex_lock(&domain_list_lock);
+ for_each_online_cpu(cpu)
+ domain_remove_cpu_mon(cpu, r);
+ r->mon_capable = false;
+ rdt_mon_feature_count--;
+ mutex_unlock(&domain_list_lock);
+ cpus_read_unlock();
+}
+
enum {
RDT_FLAG_CMT,
RDT_FLAG_MBM_TOTAL,
@@ -1174,8 +1211,6 @@ late_initcall(resctrl_arch_late_init);
static void __exit resctrl_arch_exit(void)
{
- intel_aet_exit();
-
cpuhp_remove_state(rdt_online);
resctrl_exit();
diff --git a/arch/x86/kernel/cpu/resctrl/intel_aet.c b/arch/x86/kernel/cpu/resctrl/intel_aet.c
index 2b3677783427..6e7458a722f9 100644
--- a/arch/x86/kernel/cpu/resctrl/intel_aet.c
+++ b/arch/x86/kernel/cpu/resctrl/intel_aet.c
@@ -25,8 +25,8 @@
#include <linux/intel_vsec.h>
#include <linux/io.h>
#include <linux/minmax.h>
-#include <linux/mutex.h>
#include <linux/module.h>
+#include <linux/mutex.h>
#include <linux/printk.h>
#include <linux/rculist.h>
#include <linux/rcupdate.h>
@@ -307,7 +307,7 @@ static void (*put_feature)(struct pmt_feature_group *p);
* struct pmt_feature_group to indicate that its events are successfully
* enabled.
*/
-bool intel_aet_get_events(void)
+static bool aet_get_events(void)
{
struct pmt_feature_group *p;
enum pmt_feature_id pfid;
@@ -316,14 +316,14 @@ bool intel_aet_get_events(void)
for_each_event_group(peg) {
pfid = lookup_pfid((*peg)->pfname);
- p = intel_pmt_get_regions_by_feature(pfid);
+ p = get_feature(pfid);
if (IS_ERR_OR_NULL(p))
continue;
if (enable_events(*peg, p)) {
(*peg)->pfg = p;
ret = true;
} else {
- intel_pmt_put_feature_group(p);
+ put_feature(p);
}
}
@@ -349,13 +349,27 @@ void intel_aet_unregister_enumeration(void)
}
EXPORT_SYMBOL_GPL(intel_aet_unregister_enumeration);
-void __exit intel_aet_exit(void)
+bool intel_aet_pre_mount(void)
+{
+ guard(mutex)(&aet_register_lock);
+ if (!get_feature || !put_feature)
+ return false;
+
+ return aet_get_events();
+}
+
+void intel_aet_unmount(void)
{
struct event_group **peg;
+ guard(mutex)(&aet_register_lock);
for_each_event_group(peg) {
if ((*peg)->pfg) {
- intel_pmt_put_feature_group((*peg)->pfg);
+ struct event_group *e = *peg;
+
+ for (int j = 0; j < e->num_events; j++)
+ resctrl_disable_mon_event(e->evts[j].id);
+ put_feature((*peg)->pfg);
(*peg)->pfg = NULL;
}
}
--
2.53.0
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH v6 08/10] fs/resctrl: Call architecture hooks for every mount/unmount
2026-04-29 18:48 [PATCH v6 00/10] Allow AET to use PMT as loadable module Tony Luck
` (6 preceding siblings ...)
2026-04-29 18:48 ` [PATCH v6 07/10] x86/resctrl: Resolve INTEL_PMT_TELEMETRY symbols at runtime Tony Luck
@ 2026-04-29 18:48 ` Tony Luck
2026-04-29 18:48 ` [PATCH v6 09/10] x86/resctrl: Simplify Kconfig options for resctrl Tony Luck
2026-04-29 18:48 ` [PATCH v6 10/10] Documentation/filesystems/resctrl: Add footnote for telemetry fstab mount caveat Tony Luck
9 siblings, 0 replies; 11+ messages in thread
From: Tony Luck @ 2026-04-29 18:48 UTC (permalink / raw)
To: Fenghua Yu, Reinette Chatre, Maciej Wieczor-Retman, Peter Newman,
James Morse, Babu Moger, Drew Fustini, Dave Martin, Chen Yu,
David E Box, x86
Cc: Christoph Hellwig, linux-kernel, patches, Tony Luck
Architecture code for AET needs to acquire INTEL_PMT_TELEMETRY module
references on mount and release them on unmount.
Add hooks for every mount/unmount of the resctrl file system so that
architecture code can allocate on mount and free on unmount.
Signed-off-by: Tony Luck <tony.luck@intel.com>
---
include/linux/resctrl.h | 7 +++++--
fs/resctrl/rdtgroup.c | 9 +++++++--
2 files changed, 12 insertions(+), 4 deletions(-)
diff --git a/include/linux/resctrl.h b/include/linux/resctrl.h
index 9534d42e0c57..e8a87c3664db 100644
--- a/include/linux/resctrl.h
+++ b/include/linux/resctrl.h
@@ -552,12 +552,15 @@ void resctrl_online_cpu(unsigned int cpu);
void resctrl_offline_cpu(unsigned int cpu);
/*
- * Architecture hook called at beginning of first file system mount attempt.
+ * Architecture hook called before attempting to mount the file system.
* No locks are held.
*/
void resctrl_arch_pre_mount(void);
-/* Called to report unmount. */
+/*
+ * Architecture hook called when mount fails, or on unmount.
+ * No locks are held.
+ */
void resctrl_arch_unmount(void);
/**
diff --git a/fs/resctrl/rdtgroup.c b/fs/resctrl/rdtgroup.c
index 2e31ff753114..134ad69de194 100644
--- a/fs/resctrl/rdtgroup.c
+++ b/fs/resctrl/rdtgroup.c
@@ -18,7 +18,6 @@
#include <linux/fs_parser.h>
#include <linux/sysfs.h>
#include <linux/kernfs.h>
-#include <linux/once.h>
#include <linux/resctrl.h>
#include <linux/seq_buf.h>
#include <linux/seq_file.h>
@@ -2790,7 +2789,7 @@ static int rdt_get_tree(struct fs_context *fc)
struct rdt_resource *r;
int ret;
- DO_ONCE_SLEEPABLE(resctrl_arch_pre_mount);
+ resctrl_arch_pre_mount();
cpus_read_lock();
mutex_lock(&rdtgroup_mutex);
@@ -2899,6 +2898,10 @@ static int rdt_get_tree(struct fs_context *fc)
rdt_last_cmd_clear();
mutex_unlock(&rdtgroup_mutex);
cpus_read_unlock();
+
+ if (ret)
+ resctrl_arch_unmount();
+
return ret;
}
@@ -3191,6 +3194,8 @@ static void rdt_kill_sb(struct super_block *sb)
kernfs_kill_sb(sb);
mutex_unlock(&rdtgroup_mutex);
cpus_read_unlock();
+
+ resctrl_arch_unmount();
}
static struct file_system_type rdt_fs_type = {
--
2.53.0
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH v6 09/10] x86/resctrl: Simplify Kconfig options for resctrl
2026-04-29 18:48 [PATCH v6 00/10] Allow AET to use PMT as loadable module Tony Luck
` (7 preceding siblings ...)
2026-04-29 18:48 ` [PATCH v6 08/10] fs/resctrl: Call architecture hooks for every mount/unmount Tony Luck
@ 2026-04-29 18:48 ` Tony Luck
2026-04-29 18:48 ` [PATCH v6 10/10] Documentation/filesystems/resctrl: Add footnote for telemetry fstab mount caveat Tony Luck
9 siblings, 0 replies; 11+ messages in thread
From: Tony Luck @ 2026-04-29 18:48 UTC (permalink / raw)
To: Fenghua Yu, Reinette Chatre, Maciej Wieczor-Retman, Peter Newman,
James Morse, Babu Moger, Drew Fustini, Dave Martin, Chen Yu,
David E Box, x86
Cc: Christoph Hellwig, linux-kernel, patches, Tony Luck
Linus Torvalds complained[1] about Kconfig complexity making it too
hard for "random people to build their own kernels".
CONFIG_X86_CPU_RESCTRL_INTEL_AET has been causing problems since
it was first added as it unnaturally required other config options
to be set to "built-in".
AET now resolves PMT symbols at runtime via the registration API,
so INTEL_PMT_TELEMETRY no longer needs to be built-in. This means
that AET can be included unconditionally as part of X86_CPU_RESCTRL.
Signed-off-by: Tony Luck <tony.luck@intel.com>
Link: https://lore.kernel.org/all/CAHk-=whigg3hvOy7c1j1MXFy6o6CHp0g4Tc3Y-MAk+XDssHU0A@mail.gmail.com # 1
---
arch/x86/include/asm/resctrl.h | 6 ------
arch/x86/kernel/cpu/resctrl/internal.h | 13 -------------
arch/x86/Kconfig | 16 ++--------------
arch/x86/kernel/cpu/resctrl/Makefile | 2 +-
4 files changed, 3 insertions(+), 34 deletions(-)
diff --git a/arch/x86/include/asm/resctrl.h b/arch/x86/include/asm/resctrl.h
index 7c929b72098c..775b8edd891b 100644
--- a/arch/x86/include/asm/resctrl.h
+++ b/arch/x86/include/asm/resctrl.h
@@ -195,15 +195,9 @@ static inline void resctrl_arch_mon_ctx_free(struct rdt_resource *r,
void resctrl_cpu_detect(struct cpuinfo_x86 *c);
-#ifdef CONFIG_X86_CPU_RESCTRL_INTEL_AET
void intel_aet_register_enumeration(struct pmt_feature_group *(*get)(enum pmt_feature_id id),
void (*put)(struct pmt_feature_group *p));
void intel_aet_unregister_enumeration(void);
-#else
-static inline void intel_aet_register_enumeration(struct pmt_feature_group *(*get)(enum pmt_feature_id id),
- void (*put)(struct pmt_feature_group *p)) { }
-static inline void intel_aet_unregister_enumeration(void) { }
-#endif /* CONFIG_X86_CPU_RESCTRL_INTEL_AET */
#else
diff --git a/arch/x86/kernel/cpu/resctrl/internal.h b/arch/x86/kernel/cpu/resctrl/internal.h
index 017a19143ec9..4a89f00aaa01 100644
--- a/arch/x86/kernel/cpu/resctrl/internal.h
+++ b/arch/x86/kernel/cpu/resctrl/internal.h
@@ -233,24 +233,11 @@ void __init intel_rdt_mbm_apply_quirk(void);
void rdt_domain_reconfigure_cdp(struct rdt_resource *r);
void resctrl_arch_mbm_cntr_assign_set_one(struct rdt_resource *r);
-#ifdef CONFIG_X86_CPU_RESCTRL_INTEL_AET
bool intel_aet_pre_mount(void);
void intel_aet_unmount(void);
int intel_aet_read_event(int domid, u32 rmid, void *arch_priv, u64 *val);
void intel_aet_mon_domain_setup(int cpu, int id, struct rdt_resource *r,
struct list_head *add_pos);
bool intel_handle_aet_option(bool force_off, char *tok);
-#else
-static inline bool intel_aet_pre_mount(void) { return false; }
-static inline void intel_aet_unmount(void) { }
-static inline int intel_aet_read_event(int domid, u32 rmid, void *arch_priv, u64 *val)
-{
- return -EINVAL;
-}
-
-static inline void intel_aet_mon_domain_setup(int cpu, int id, struct rdt_resource *r,
- struct list_head *add_pos) { }
-static inline bool intel_handle_aet_option(bool force_off, char *tok) { return false; }
-#endif
#endif /* _ASM_X86_RESCTRL_INTERNAL_H */
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index f3f7cb01d69d..861985294547 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -515,8 +515,9 @@ config X86_MPPARSE
config X86_CPU_RESCTRL
bool "x86 CPU resource control support"
- depends on X86 && (CPU_SUP_INTEL || CPU_SUP_AMD)
+ depends on X86_64 && (CPU_SUP_INTEL || CPU_SUP_AMD)
depends on MISC_FILESYSTEMS
+ depends on (INTEL_PMT_TELEMETRY != n) || !CPU_SUP_INTEL
select ARCH_HAS_CPU_RESCTRL
select RESCTRL_FS
select RESCTRL_FS_PSEUDO_LOCK
@@ -536,19 +537,6 @@ config X86_CPU_RESCTRL
Say N if unsure.
-config X86_CPU_RESCTRL_INTEL_AET
- bool "Intel Application Energy Telemetry"
- depends on X86_64 && X86_CPU_RESCTRL && CPU_SUP_INTEL && INTEL_PMT_TELEMETRY=y && INTEL_TPMI=y
- help
- Enable per-RMID telemetry events in resctrl.
-
- Intel feature that collects per-RMID execution data
- about energy consumption, measure of frequency independent
- activity and other performance metrics. Data is aggregated
- per package.
-
- Say N if unsure.
-
config X86_FRED
bool "Flexible Return and Event Delivery"
depends on X86_64
diff --git a/arch/x86/kernel/cpu/resctrl/Makefile b/arch/x86/kernel/cpu/resctrl/Makefile
index 273ddfa30836..97ceb4e44dfa 100644
--- a/arch/x86/kernel/cpu/resctrl/Makefile
+++ b/arch/x86/kernel/cpu/resctrl/Makefile
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_X86_CPU_RESCTRL) += core.o rdtgroup.o monitor.o
obj-$(CONFIG_X86_CPU_RESCTRL) += ctrlmondata.o
-obj-$(CONFIG_X86_CPU_RESCTRL_INTEL_AET) += intel_aet.o
+obj-$(CONFIG_X86_CPU_RESCTRL) += intel_aet.o
obj-$(CONFIG_RESCTRL_FS_PSEUDO_LOCK) += pseudo_lock.o
# To allow define_trace.h's recursive include:
--
2.53.0
^ permalink raw reply related [flat|nested] 11+ messages in thread* [PATCH v6 10/10] Documentation/filesystems/resctrl: Add footnote for telemetry fstab mount caveat
2026-04-29 18:48 [PATCH v6 00/10] Allow AET to use PMT as loadable module Tony Luck
` (8 preceding siblings ...)
2026-04-29 18:48 ` [PATCH v6 09/10] x86/resctrl: Simplify Kconfig options for resctrl Tony Luck
@ 2026-04-29 18:48 ` Tony Luck
9 siblings, 0 replies; 11+ messages in thread
From: Tony Luck @ 2026-04-29 18:48 UTC (permalink / raw)
To: Fenghua Yu, Reinette Chatre, Maciej Wieczor-Retman, Peter Newman,
James Morse, Babu Moger, Drew Fustini, Dave Martin, Chen Yu,
David E Box, x86
Cc: Christoph Hellwig, linux-kernel, patches, Tony Luck
Add a footnote to the 'If telemetry monitoring is enabled' sentence noting
that because PMT driver enumerates telemetry features asynchronously, an
automatic mount of resctrl from /etc/fstab at boot may occur before those
features are available, resulting in them not being enabled.
Assisted-by: Claude:Sonnet_4.6
Signed-off-by: Tony Luck <tony.luck@intel.com>
---
Documentation/filesystems/resctrl.rst | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/Documentation/filesystems/resctrl.rst b/Documentation/filesystems/resctrl.rst
index b003bed339fd..4e62b8c5e0d6 100644
--- a/Documentation/filesystems/resctrl.rst
+++ b/Documentation/filesystems/resctrl.rst
@@ -620,7 +620,7 @@ When monitoring is enabled all MON groups will also contain:
each instance of an L3 cache. Each directory contains files for the enabled
L3 events (e.g. "llc_occupancy", "mbm_total_bytes", and "mbm_local_bytes").
- If telemetry monitoring is enabled, there will be a "mon_PERF_PKG_YY"
+ If telemetry monitoring is enabled [#]_, there will be a "mon_PERF_PKG_YY"
directory for each physical processor package. Each directory contains
files for the enabled telemetry events (e.g. "core_energy". "activity",
"uops_retired", etc.)
@@ -659,6 +659,11 @@ When monitoring is enabled all MON groups will also contain:
returned if the MBM event does not have an assigned counter in the
CTRL_MON group nor in any of its associated MON groups.
+.. [#] Telemetry features are enumerated asynchronously by the PMT driver. If
+ resctrl is automatically mounted from ``/etc/fstab`` at boot, the telemetry
+ features may not yet be available at mount time and will therefore not be
+ enabled.
+
"mon_hw_id":
Available only with debug option. The identifier used by hardware
for the monitor group. On x86 this is the RMID.
--
2.53.0
^ permalink raw reply related [flat|nested] 11+ messages in thread