mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH v13 00/25] Allow AET to use PMT as loadable module
@ 2026-09-28 22:14 Tony Luck
  2026-09-28 22:14 ` [PATCH v13 01/25] fs/resctrl: Ensure default group reports tasks on monitor-only systems Tony Luck
                   ` (25 more replies)
  0 siblings, 26 replies; 27+ messages in thread
From: Tony Luck @ 2026-09-28 22:14 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

Requiring INTEL_PMT_TELEMETRY=y to enable AET is a functional workaround
to enable enumeration of Application Energy Telemetry (AET) events, but
unacceptable to many users. It results in increased configuration complexity,
increased kernel memory footprint and inability to patch problems by unloading
a module and loading an updated version.

Add a registration function to the AET code that can be used by
INTEL_PMT_TELEMETRY to provide the enumeration functions.

INTEL_PMT_TELEMETRY can be loaded/unloaded independently of
resctrl file system mount/unmount. Perform enumeration on
every mount and cleanup on every unmount.

Patch series based on TIP tree x86/cache branch current HEAD is:
  a17d099481bd ("x86/resctrl: Update documented unit for the "activity" event")

Signed-off-by: Tony Luck <tony.luck@intel.com>

Previous version (v12) here:
Link: https://lore.kernel.org/all/20260916231320.14502-1-tony.luck@intel.com/

Changes since v12:

[PATCH v13 01/25] fs/resctrl: Ensure default group reports tasks on monitor-only systems
	New patch (split from patch 9)

[PATCH v13 02/25] x86/cpufeatures: Add missing CQM feature dependency
	Added Reinette RB tag

[PATCH v13 03/25] x86/resctrl: Check if monitoring features are supported
	Dropped (Linux: X86_FEATURE_*) from commit comment
	s/specific features/resource specific features/
	s/L3-based monitoring features/L3 monitoring features/
	Added maintainer note about not back porting.

[PATCH v13 04/25] x86/resctrl: Centralize monitoring feature enumeration
	Update commit subject and comment as suggested.

[PATCH v13 05/25] x86/resctrl: Apply Intel MBM quirk from rdt_get_l3_mon_config()
	Babu:
	s/intel_rdt_mbm_apply_quirk(r->mon.num_rmid)/intel_rdt_mbm_apply_quirk(num_rmid)/

	Reinette:
	Add comment to code describing model specific details of quirk.

[PATCH v13 06/25] x86/resctrl: Delete resctrl_cpu_detect()
	Replaced commit comment with Reinette improved version.

[PATCH v13 07/25] arm,x86,fs/resctrl: Replace architecture resctrl_arch_{alloc,mon}_capable()
	s/is alloc, or mon, capable/is capable of allocation or monitoring/

[PATCH v13 08/25] x86/resctrl: Update special case for Intel Haswell enumeration
	Replaced commit comment with Reinette's improved version.

[PATCH v13 09/25] x86/resctrl: Delete rdt_alloc_capable and rdt_mon_capable
	Expand commit message.

[PATCH v13 10/25] fs/resctrl: Remove redundant calls to resctrl_mon_capable()
	Moved change to is_closid_match() to its own patch.

[PATCH v13 11/25] x86/resctrl: Honor rdt={perf|energy} options to force enable AET events
	Update subject and commit comment to reflect that this change
	applies equally to rdt=energy.

[PATCH v13 12/25] fs/resctrl: Add interface to disable a monitor event
	Add back the comment that events must not be disabled while
	the file system is mounted.

[PATCH v13 13/25] arm,x86,fs/resctrl: Allocate maximum needed rmid_ptrs[]
	Updated commit message using Reinette suggestion.
	Merged patch 14 "Rebuild free RMID list on each mount" into
	this patch as the split into separate patches didn't work
	as well as I hoped.

[PATCH v13 14/25] arm,x86,fs/resctrl: Use right size for L3 monitor data structures
	Drop rename of local "idx_limit" to "l3_idx_limit"
	Re-wrote commit message.

[PATCH v13 15/25] x86,fs/resctrl: Handle systems where AET is the only resource
	Add a pr_info() if no L3 features are enabled on a
	"X86_FEATURE_CQM_LLC" system.

	Add a comment for the "return true" from get_rdt_mon_resources()

	Rewrite commit message with context for the change.

[PATCH v13 16/25] x86/resctrl: Add PMT registration API for AET enumeration callbacks
	Rewrote commit message using correct context at this point in the series.
	Use "pmt_telemetry" throughout.

[PATCH v13 17/25] platform/x86/intel/pmt: Register enumeration functions with resctrl
	Dropped empty line in pmt_telem_init()
	Rewrote commit message with accurate context.

[PATCH v13 18/25] x86/resctrl: Use registered function pointers for AET enumeration
	Replace intel_pmt_put_feature_group() call in intel_aet_exit()
	with call via registered function pointer.

	Explain in commit comment that pmt_telemetry is built-in so the
	try_module_get() is a no-op.

[PATCH v13 19/25] arm,x86,fs/resctrl: Enumerate AET on every resctrl mount
	Replace comment about holding resctrl_mount_lock for
	resctrl_arch_pre_mount() and resctrl_arch_unmount()
	with "Serialized against other mount and unmount attempts."

	Dropped stray blank line addition to rdt_get_tree()

	Rewrote commit message. Note that previous iterations of this
	patch series attempted to split into separate parts. But these
	were hard to explain separately.

[PATCH v13 20/25] x86/resctrl: Enforce system RMID limit on AET
	Drop sentence about SNC reducing number of RMIDs as it isn't
	relevant.

	s/lower/higher/ in commit message.

	s/IA32_PQR_ASSOC.RMID/MSR_IA32_PQR_ASSOC.RMID/

	Changed pqr_assoc_num_rmid from static to global.

	Move clamp from arch/x86/kernel/cpu/resctrl/core.c to
	arch/x86/kernel/cpu/resctrl/intel_aet.c

[PATCH v13 21/25] x86/resctrl: Export interface to report telemetry unbind/remove
	Dropped telemetry_region::addr from list of things protected
	by aet_register_lock.

	Declare and use aet_mmio_lock in this patch instead of next one.

	Explain the reason for the new lock.

[PATCH v13 22/25] platform/x86/intel/pmt: Inform resctrl when MMIO maps are being removed
	Context paragraph added describing the problem.

	New aet_mmio_lock moved to previous patch to avoid
	churn here changing lines that were just changed there.

	Add a comment in code that all entries for a removed device
	are on the same package.

[PATCH v13 23/25] x86/resctrl: Require 64-bit x86 for resctrl support
	Re-order tags
	s/This in line/This is in line/
	s/the state of/reduced/

[PATCH v13 24/25] x86/resctrl: Simplify Kconfig options for resctrl
	Re-order tags.
	Swap "intel_" prefix to "rdt_".

[PATCH v13 25/25] x86,fs/resctrl: Document telemetry mount timing caveat
	Drop the "Mounting resctrl with telemetry" section. Include the
	solution in the footnote.

Tony Luck (25):
  fs/resctrl: Ensure default group reports tasks on monitor-only systems
  x86/cpufeatures: Add missing CQM feature dependency
  x86/resctrl: Check if monitoring features are supported
  x86/resctrl: Centralize monitoring feature enumeration
  x86/resctrl: Apply Intel MBM quirk from rdt_get_l3_mon_config()
  x86/resctrl: Delete resctrl_cpu_detect()
  arm,x86,fs/resctrl: Replace architecture
    resctrl_arch_{alloc,mon}_capable()
  x86/resctrl: Update special case for Intel Haswell enumeration
  x86/resctrl: Delete rdt_alloc_capable and rdt_mon_capable
  fs/resctrl: Remove redundant calls to resctrl_mon_capable()
  x86/resctrl: Honor rdt={perf|energy} options to force enable AET
    events
  fs/resctrl: Add interface to disable a monitor event
  arm,x86,fs/resctrl: Allocate maximum needed rmid_ptrs[]
  arm,x86,fs/resctrl: Use right size for L3 monitor data structures
  x86,fs/resctrl: Handle systems where AET is the only resource
  x86/resctrl: Add PMT registration API for AET enumeration callbacks
  platform/x86/intel/pmt: Register enumeration functions with resctrl
  x86/resctrl: Use registered function pointers for AET enumeration
  arm,x86,fs/resctrl: Enumerate AET on every resctrl mount
  x86/resctrl: Enforce system RMID limit on AET
  x86/resctrl: Export interface to report telemetry unbind/remove
  platform/x86/intel/pmt: Inform resctrl when MMIO maps are being
    removed
  x86/resctrl: Require 64-bit x86 for resctrl support
  x86/resctrl: Simplify Kconfig options for resctrl
  x86,fs/resctrl: Document telemetry mount timing caveat

 Documentation/filesystems/resctrl.rst      |   7 +-
 include/linux/arm_mpam.h                   |   3 -
 include/linux/intel_vsec.h                 |  14 ++
 include/linux/resctrl.h                    |  84 +++++++++++-
 arch/x86/include/asm/processor.h           |   4 -
 arch/x86/include/asm/resctrl.h             |  24 +---
 arch/x86/kernel/cpu/resctrl/internal.h     |  31 ++---
 arch/x86/kernel/cpu/amd.c                  |   3 -
 arch/x86/kernel/cpu/cpuid-deps.c           |   1 +
 arch/x86/kernel/cpu/hygon.c                |   3 -
 arch/x86/kernel/cpu/intel.c                |   7 -
 arch/x86/kernel/cpu/resctrl/core.c         | 150 +++++++++++----------
 arch/x86/kernel/cpu/resctrl/intel_aet.c    | 132 ++++++++++++++++--
 arch/x86/kernel/cpu/resctrl/monitor.c      |  78 +++++++----
 drivers/platform/x86/intel/pmt/telemetry.c |  45 ++++++-
 drivers/resctrl/mpam_resctrl.c             |  44 +++---
 fs/resctrl/monitor.c                       | 111 ++++++++++-----
 fs/resctrl/pseudo_lock.c                   |   6 +-
 fs/resctrl/rdtgroup.c                      |  74 ++++++----
 arch/x86/Kconfig                           |  15 +--
 arch/x86/kernel/cpu/resctrl/Makefile       |   3 +-
 21 files changed, 567 insertions(+), 272 deletions(-)


base-commit: a17d099481bd11f0911993a8e69992269f92ad12
-- 
2.55.0


^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH v13 01/25] fs/resctrl: Ensure default group reports tasks on monitor-only systems
  2026-09-28 22:14 [PATCH v13 00/25] Allow AET to use PMT as loadable module Tony Luck
@ 2026-09-28 22:14 ` Tony Luck
  2026-09-28 22:14 ` [PATCH v13 02/25] x86/cpufeatures: Add missing CQM feature dependency Tony Luck
                   ` (24 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Tony Luck @ 2026-09-28 22:14 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, Sashiko

This is a pre-existing issue, but the resctrl_arch_alloc_capable() check in
is_closid_match() actively breaks the default group on systems that only
support monitoring capabilities.

When a user reads the root /sys/fs/resctrl/tasks file on a system with
monitoring capabilities but no allocation capabilities, the following call
chain occurs:
	rdtgroup_tasks_show()
	show_rdt_tasks()
	is_closid_match()

Since resctrl_arch_alloc_capable() evaluates to false on such systems,
is_closid_match() unconditionally returns false for all tasks. Furthermore,
because the default group has type RDTCTRL_GROUP, is_rmid_match() will also
return false.

This causes the root tasks file to appear completely empty, hiding all tasks
on the system that have not been explicitly moved to a monitoring group.

Removing the resctrl_arch_alloc_capable() test is safe because a struct
rdtgroup with type == RDTCTRL_GROUP (other than the always-present default
group) can only be created on systems where allocation is supported. So
whenever the remaining resctrl_arch_match_closid() check could meaningfully
succeed, resctrl_arch_alloc_capable() was already implicitly true, making
the test redundant.

Fixes: e6b2fac36fcc ("x86/resctrl: Use is_closid_match() in more places")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://sashiko.dev/#/patchset/20260831174421.13921-1-tony.luck%40intel.com?part=9
Signed-off-by: Tony Luck <tony.luck@intel.com>
---
v13:
	New patch (split from patch 9)
---
 fs/resctrl/rdtgroup.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/resctrl/rdtgroup.c b/fs/resctrl/rdtgroup.c
index 68be9b903ac6..57ab090072c2 100644
--- a/fs/resctrl/rdtgroup.c
+++ b/fs/resctrl/rdtgroup.c
@@ -685,7 +685,7 @@ static int __rdtgroup_move_task(struct task_struct *tsk,
 
 static bool is_closid_match(struct task_struct *t, struct rdtgroup *r)
 {
-	return (resctrl_arch_alloc_capable() && (r->type == RDTCTRL_GROUP) &&
+	return (r->type == RDTCTRL_GROUP &&
 		resctrl_arch_match_closid(t, r->closid));
 }
 
-- 
2.55.0


^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH v13 02/25] x86/cpufeatures: Add missing CQM feature dependency
  2026-09-28 22:14 [PATCH v13 00/25] Allow AET to use PMT as loadable module Tony Luck
  2026-09-28 22:14 ` [PATCH v13 01/25] fs/resctrl: Ensure default group reports tasks on monitor-only systems Tony Luck
@ 2026-09-28 22:14 ` Tony Luck
  2026-09-28 22:14 ` [PATCH v13 03/25] x86/resctrl: Check if monitoring features are supported Tony Luck
                   ` (23 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Tony Luck @ 2026-09-28 22:14 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

The Intel Software Developer's Manual says that software must check that
CPUID(0x7,0x0).EBX[12] (Linux X86_FEATURE_CQM) is set before checking
for monitoring features in CPUID leaf 0xF.

Add the missing dependency of X86_FEATURE_CQM_LLC on X86_FEATURE_CQM.

Signed-off-by: Tony Luck <tony.luck@intel.com>
Reviewed-by: Reinette Chatre <reinette.chatre@intel.com>
---
v13:
	Added Reinette RB tag
---
 arch/x86/kernel/cpu/cpuid-deps.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/x86/kernel/cpu/cpuid-deps.c b/arch/x86/kernel/cpu/cpuid-deps.c
index 99801e844b30..93d45b688f6c 100644
--- a/arch/x86/kernel/cpu/cpuid-deps.c
+++ b/arch/x86/kernel/cpu/cpuid-deps.c
@@ -67,6 +67,7 @@ static const struct cpuid_dep cpuid_deps[] = {
 	{ X86_FEATURE_AVX512_4FMAPS,		X86_FEATURE_AVX512F   },
 	{ X86_FEATURE_AVX512_VPOPCNTDQ,		X86_FEATURE_AVX512F   },
 	{ X86_FEATURE_AVX512_VP2INTERSECT,	X86_FEATURE_AVX512VL  },
+	{ X86_FEATURE_CQM_LLC,			X86_FEATURE_CQM       },
 	{ X86_FEATURE_CQM_OCCUP_LLC,		X86_FEATURE_CQM_LLC   },
 	{ X86_FEATURE_CQM_MBM_TOTAL,		X86_FEATURE_CQM_LLC   },
 	{ X86_FEATURE_CQM_MBM_LOCAL,		X86_FEATURE_CQM_LLC   },
-- 
2.55.0


^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH v13 03/25] x86/resctrl: Check if monitoring features are supported
  2026-09-28 22:14 [PATCH v13 00/25] Allow AET to use PMT as loadable module Tony Luck
  2026-09-28 22:14 ` [PATCH v13 01/25] fs/resctrl: Ensure default group reports tasks on monitor-only systems Tony Luck
  2026-09-28 22:14 ` [PATCH v13 02/25] x86/cpufeatures: Add missing CQM feature dependency Tony Luck
@ 2026-09-28 22:14 ` Tony Luck
  2026-09-28 22:14 ` [PATCH v13 04/25] x86/resctrl: Centralize monitoring feature enumeration Tony Luck
                   ` (22 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Tony Luck @ 2026-09-28 22:14 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

Both Intel and AMD manuals say that software must first check
CPUID(0x7,0x0).EBX[12] to see if any monitoring features are supported before
checking for resource specific features supported in subleaves.

Each of the L3 monitoring features is further gated by CPUID(0xF,0x0).EDX[1].

Add checks for these feature bits.

Maintainer note: No need to backport this fix. No issues have been seen
from this failure to follow the exact enumeration process in the manual.

Fixes: cbc82b172638 ("x86: Add support for Intel Cache QoS Monitoring (CQM) detection")
Signed-off-by: Tony Luck <tony.luck@intel.com>
---
v13:
	Dropped (Linux: X86_FEATURE_*) from commit comment
	s/specific features/resource specific features/
	s/L3-based monitoring features/L3 monitoring features/
	Added maintainer note about not back porting.
---
 arch/x86/kernel/cpu/resctrl/core.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/arch/x86/kernel/cpu/resctrl/core.c b/arch/x86/kernel/cpu/resctrl/core.c
index 55214d6fdc49..34ca3c7cc046 100644
--- a/arch/x86/kernel/cpu/resctrl/core.c
+++ b/arch/x86/kernel/cpu/resctrl/core.c
@@ -968,6 +968,14 @@ static __init bool get_rdt_mon_resources(void)
 	struct rdt_resource *r = &rdt_resources_all[RDT_RESOURCE_L3].r_resctrl;
 	bool ret = false;
 
+	/* Any monitoring at all? */
+	if (!cpu_feature_enabled(X86_FEATURE_CQM))
+		return false;
+
+	/* Any of the L3 monitoring features? */
+	if (!cpu_feature_enabled(X86_FEATURE_CQM_LLC))
+		return false;
+
 	if (rdt_cpu_has(X86_FEATURE_CQM_OCCUP_LLC)) {
 		resctrl_enable_mon_event(QOS_L3_OCCUP_EVENT_ID, false, 0, NULL);
 		ret = true;
-- 
2.55.0


^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH v13 04/25] x86/resctrl: Centralize monitoring feature enumeration
  2026-09-28 22:14 [PATCH v13 00/25] Allow AET to use PMT as loadable module Tony Luck
                   ` (2 preceding siblings ...)
  2026-09-28 22:14 ` [PATCH v13 03/25] x86/resctrl: Check if monitoring features are supported Tony Luck
@ 2026-09-28 22:14 ` Tony Luck
  2026-09-28 22:14 ` [PATCH v13 05/25] x86/resctrl: Apply Intel MBM quirk from rdt_get_l3_mon_config() Tony Luck
                   ` (21 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Tony Luck @ 2026-09-28 22:14 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

The original implementation of Intel Cache QoS Monitoring (CQM) planned
to integrate with the "perf" and "cgroup" subsystems. With that plan it
made sense for parameters from CPUID to be stored in fields of the
cpuinfo_x86 structure. But that plan was abandoned and the resctrl file
system user interface replaced it.

Centralize all L3 monitoring enumeration within resctrl in preparation for
removal of resctrl fields from struct cpuinfo_x86.

Signed-off-by: Tony Luck <tony.luck@intel.com>
---
v13:
	Update commit subject and comment as suggested.
---
 arch/x86/include/asm/resctrl.h        |  9 ++++----
 arch/x86/kernel/cpu/resctrl/monitor.c | 32 ++++++++++++++++++++++++---
 2 files changed, 33 insertions(+), 8 deletions(-)

diff --git a/arch/x86/include/asm/resctrl.h b/arch/x86/include/asm/resctrl.h
index 8f6edcdcfd87..c9f9db96f792 100644
--- a/arch/x86/include/asm/resctrl.h
+++ b/arch/x86/include/asm/resctrl.h
@@ -44,6 +44,7 @@ DECLARE_PER_CPU(struct resctrl_pqr_state, pqr_state);
 
 extern bool rdt_alloc_capable;
 extern bool rdt_mon_capable;
+extern unsigned int rdt_l3_mon_scale;
 
 DECLARE_STATIC_KEY_FALSE(rdt_enable_key);
 DECLARE_STATIC_KEY_FALSE(rdt_alloc_enable_key);
@@ -132,11 +133,9 @@ static inline void __resctrl_sched_in(struct task_struct *tsk)
 
 static inline unsigned int resctrl_arch_round_mon_val(unsigned int val)
 {
-	unsigned int scale = boot_cpu_data.x86_cache_occ_scale;
-
-	/* h/w works in units of "boot_cpu_data.x86_cache_occ_scale" */
-	val /= scale;
-	return val * scale;
+	/* Round down to nearest h/w monitoring unit */
+	val /= rdt_l3_mon_scale;
+	return val * rdt_l3_mon_scale;
 }
 
 static inline void resctrl_arch_set_cpu_default_closid_rmid(int cpu, u32 closid,
diff --git a/arch/x86/kernel/cpu/resctrl/monitor.c b/arch/x86/kernel/cpu/resctrl/monitor.c
index 3838e0a13d36..89b83cc7e800 100644
--- a/arch/x86/kernel/cpu/resctrl/monitor.c
+++ b/arch/x86/kernel/cpu/resctrl/monitor.c
@@ -32,6 +32,11 @@
  */
 bool rdt_mon_capable;
 
+/*
+ * Scale factor to convert L3 monitor events to bytes.
+ */
+unsigned int __ro_after_init rdt_l3_mon_scale;
+
 #define CF(cf)	((unsigned long)(1048576 * (cf) + 0.5))
 
 static int snc_nodes_per_l3_cache = 1;
@@ -418,16 +423,37 @@ static __init int snc_get_config(void)
 
 int __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);
+	unsigned int mbm_offset;
 	unsigned int threshold;
 	u32 eax, ebx, ecx, edx;
+	u32 num_rmid;
+
+	/* Resource monitoring leaf is 0xf. L3 monitoring details in subleaf 1 */
+	cpuid_count(0xf, 1, &eax, &ebx, &ecx, &edx);
+	mbm_offset = eax & GENMASK(7, 0);
+	rdt_l3_mon_scale = ebx;
+	num_rmid = ecx + 1;
+
+	if (!mbm_offset) {
+		switch (boot_cpu_data.x86_vendor) {
+		case X86_VENDOR_AMD:
+			mbm_offset = MBM_CNTR_WIDTH_OFFSET_AMD;
+			break;
+		case X86_VENDOR_HYGON:
+			mbm_offset = MBM_CNTR_WIDTH_OFFSET_HYGON;
+			break;
+		default:
+			/* Leave mbm_offset as 0 */
+			break;
+		}
+	}
 
 	snc_nodes_per_l3_cache = snc_get_config();
 
 	resctrl_rmid_realloc_limit = boot_cpu_data.x86_cache_size * 1024;
-	hw_res->mon_scale = boot_cpu_data.x86_cache_occ_scale / snc_nodes_per_l3_cache;
-	r->mon.num_rmid = (boot_cpu_data.x86_cache_max_rmid + 1) / snc_nodes_per_l3_cache;
+	hw_res->mon_scale = rdt_l3_mon_scale / snc_nodes_per_l3_cache;
+	r->mon.num_rmid = num_rmid / snc_nodes_per_l3_cache;
 	hw_res->mbm_width = MBM_CNTR_WIDTH_BASE;
 
 	if (mbm_offset > 0 && mbm_offset <= MBM_CNTR_WIDTH_OFFSET_MAX)
-- 
2.55.0


^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH v13 05/25] x86/resctrl: Apply Intel MBM quirk from rdt_get_l3_mon_config()
  2026-09-28 22:14 [PATCH v13 00/25] Allow AET to use PMT as loadable module Tony Luck
                   ` (3 preceding siblings ...)
  2026-09-28 22:14 ` [PATCH v13 04/25] x86/resctrl: Centralize monitoring feature enumeration Tony Luck
@ 2026-09-28 22:14 ` Tony Luck
  2026-09-28 22:14 ` [PATCH v13 06/25] x86/resctrl: Delete resctrl_cpu_detect() Tony Luck
                   ` (20 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Tony Luck @ 2026-09-28 22:14 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

The Intel quirk to adjust Memory Bandwidth Monitoring (MBM) values on
certain CPUs is applied early, before discovering if MBM is supported.

Move the call into rdt_get_l3_mon_config(), but keep the decision on
whether it is needed in __check_quirks_intel() with all the other
model specific tests.

Signed-off-by: Tony Luck <tony.luck@intel.com>
---
v13:
	Babu:
	s/intel_rdt_mbm_apply_quirk(r->mon.num_rmid)/intel_rdt_mbm_apply_quirk(num_rmid)/

	Reinette:
	Add comment to code describing model specific details of quirk.
---
 arch/x86/kernel/cpu/resctrl/internal.h |  4 +--
 arch/x86/kernel/cpu/resctrl/core.c     |  2 +-
 arch/x86/kernel/cpu/resctrl/monitor.c  | 40 ++++++++++++++++----------
 3 files changed, 28 insertions(+), 18 deletions(-)

diff --git a/arch/x86/kernel/cpu/resctrl/internal.h b/arch/x86/kernel/cpu/resctrl/internal.h
index e3cfa0c10e92..086282a82fca 100644
--- a/arch/x86/kernel/cpu/resctrl/internal.h
+++ b/arch/x86/kernel/cpu/resctrl/internal.h
@@ -151,6 +151,8 @@ static inline struct rdt_hw_resource *resctrl_to_arch_res(struct rdt_resource *r
 
 extern struct rdt_hw_resource rdt_resources_all[];
 
+extern bool intel_rdt_mbm_need_quirk;
+
 void arch_mon_domain_online(struct rdt_resource *r, struct rdt_l3_mon_domain *d);
 
 /* CPUID.(EAX=10H, ECX=ResID=1).EAX */
@@ -228,8 +230,6 @@ int rdt_get_l3_mon_config(struct rdt_resource *r);
 
 bool rdt_cpu_has(int flag);
 
-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);
 
diff --git a/arch/x86/kernel/cpu/resctrl/core.c b/arch/x86/kernel/cpu/resctrl/core.c
index 34ca3c7cc046..82b27a0157ae 100644
--- a/arch/x86/kernel/cpu/resctrl/core.c
+++ b/arch/x86/kernel/cpu/resctrl/core.c
@@ -1011,7 +1011,7 @@ static __init void __check_quirks_intel(void)
 			set_rdt_options("!l3cat");
 		fallthrough;
 	case INTEL_BROADWELL_X:
-		intel_rdt_mbm_apply_quirk();
+		intel_rdt_mbm_need_quirk = true;
 		break;
 	}
 }
diff --git a/arch/x86/kernel/cpu/resctrl/monitor.c b/arch/x86/kernel/cpu/resctrl/monitor.c
index 89b83cc7e800..468e9821f35a 100644
--- a/arch/x86/kernel/cpu/resctrl/monitor.c
+++ b/arch/x86/kernel/cpu/resctrl/monitor.c
@@ -37,6 +37,8 @@ bool rdt_mon_capable;
  */
 unsigned int __ro_after_init rdt_l3_mon_scale;
 
+bool __initdata intel_rdt_mbm_need_quirk;
+
 #define CF(cf)	((unsigned long)(1048576 * (cf) + 0.5))
 
 static int snc_nodes_per_l3_cache = 1;
@@ -51,7 +53,7 @@ static int snc_nodes_per_l3_cache = 1;
  * 1. The threshold 0 is changed to rmid count - 1 so don't do correction
  *    for the case.
  * 2. MBM total and local correction table indexed by core counter which is
- *    equal to (x86_cache_max_rmid + 1) / 8 - 1 and is from 0 up to 27.
+ *    equal to num_rmid / 8 - 1 and is from 0 up to 27.
  * 3. The correction factor is normalized to 2^20 (1048576) so it's faster
  *    to calculate corrected value by shifting:
  *    corrected_value = (original_value * correction_factor) >> 20
@@ -421,6 +423,20 @@ static __init int snc_get_config(void)
 	return ret;
 }
 
+static void __init intel_rdt_mbm_apply_quirk(u32 num_rmid)
+{
+	unsigned int cf_index;
+
+	cf_index = num_rmid / 8 - 1;
+	if (cf_index >= ARRAY_SIZE(mbm_cf_table)) {
+		pr_info("No MBM correction factor available\n");
+		return;
+	}
+
+	mbm_cf_rmidthreshold = mbm_cf_table[cf_index].rmidthreshold;
+	mbm_cf = mbm_cf_table[cf_index].cf;
+}
+
 int __init rdt_get_l3_mon_config(struct rdt_resource *r)
 {
 	struct rdt_hw_resource *hw_res = resctrl_to_arch_res(r);
@@ -500,25 +516,19 @@ int __init rdt_get_l3_mon_config(struct rdt_resource *r)
 		hw_res->mbm_cntr_assign_enabled = true;
 	}
 
+	/*
+	 * This quirk only applies to Intel Skylake and Broadwell
+	 * CPUs. These don't support Sub-NUMA Cluster. Pass the
+	 * raw number of RMIDs enumerated by CPUID(0xF,0x1).ECX.
+	 */
+	if (intel_rdt_mbm_need_quirk)
+		intel_rdt_mbm_apply_quirk(num_rmid);
+
 	r->mon_capable = true;
 
 	return 0;
 }
 
-void __init intel_rdt_mbm_apply_quirk(void)
-{
-	int cf_index;
-
-	cf_index = (boot_cpu_data.x86_cache_max_rmid + 1) / 8 - 1;
-	if (cf_index >= ARRAY_SIZE(mbm_cf_table)) {
-		pr_info("No MBM correction factor available\n");
-		return;
-	}
-
-	mbm_cf_rmidthreshold = mbm_cf_table[cf_index].rmidthreshold;
-	mbm_cf = mbm_cf_table[cf_index].cf;
-}
-
 static void resctrl_abmc_set_one_amd(void *arg)
 {
 	bool *enable = arg;
-- 
2.55.0


^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH v13 06/25] x86/resctrl: Delete resctrl_cpu_detect()
  2026-09-28 22:14 [PATCH v13 00/25] Allow AET to use PMT as loadable module Tony Luck
                   ` (4 preceding siblings ...)
  2026-09-28 22:14 ` [PATCH v13 05/25] x86/resctrl: Apply Intel MBM quirk from rdt_get_l3_mon_config() Tony Luck
@ 2026-09-28 22:14 ` Tony Luck
  2026-09-28 22:14 ` [PATCH v13 07/25] arm,x86,fs/resctrl: Replace architecture resctrl_arch_{alloc,mon}_capable() Tony Luck
                   ` (19 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Tony Luck @ 2026-09-28 22:14 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,
	Borislav Petkov (AMD)

resctrl now enumerates its monitoring properties itself, leaving
cpuinfo_x86::x86_cache_{max_rmid,occ_scale,mbm_width_offset} without any
consumers. These resctrl specific fields are populated from the vendor CPU
identification paths, unnecessarily placing resctrl details in generic x86
CPU setup.

Delete the unused fields together with the code that populates them, removing
resctrl from early CPU identification.

Signed-off-by: Tony Luck <tony.luck@intel.com>
Acked-by: Borislav Petkov (AMD) <bp@alien8.de>
---
v13:
	Replaced commit comment with Reinette improved version.
---
 arch/x86/include/asm/processor.h   |  4 ---
 arch/x86/include/asm/resctrl.h     |  3 ---
 arch/x86/kernel/cpu/amd.c          |  3 ---
 arch/x86/kernel/cpu/hygon.c        |  3 ---
 arch/x86/kernel/cpu/intel.c        |  7 -----
 arch/x86/kernel/cpu/resctrl/core.c | 42 ------------------------------
 6 files changed, 62 deletions(-)

diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index ec9db0dfa0df..4deb88c61c94 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -185,10 +185,6 @@ struct cpuinfo_x86 {
 	/* in KB - valid for CPUS which support this call: */
 	unsigned int		x86_cache_size;
 	int			x86_cache_alignment;	/* In bytes */
-	/* Cache QoS architectural values, valid only on the BSP: */
-	int			x86_cache_max_rmid;	/* max index */
-	int			x86_cache_occ_scale;	/* scale to bytes */
-	int			x86_cache_mbm_width_offset;
 	int			x86_power;
 	unsigned long		loops_per_jiffy;
 	/* protected processor identification number */
diff --git a/arch/x86/include/asm/resctrl.h b/arch/x86/include/asm/resctrl.h
index c9f9db96f792..2031b30ff25b 100644
--- a/arch/x86/include/asm/resctrl.h
+++ b/arch/x86/include/asm/resctrl.h
@@ -193,12 +193,9 @@ static inline void resctrl_arch_mon_ctx_free(struct rdt_resource *r,
 					     enum resctrl_event_id evtid,
 					     void *ctx) { }
 
-void resctrl_cpu_detect(struct cpuinfo_x86 *c);
-
 #else
 
 static inline void resctrl_arch_sched_in(struct task_struct *tsk) {}
-static inline void resctrl_cpu_detect(struct cpuinfo_x86 *c) {}
 
 #endif /* CONFIG_X86_CPU_RESCTRL */
 
diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c
index 54e14ed276b5..dd82a11084f4 100644
--- a/arch/x86/kernel/cpu/amd.c
+++ b/arch/x86/kernel/cpu/amd.c
@@ -23,7 +23,6 @@
 #include <asm/pci-direct.h>
 #include <asm/delay.h>
 #include <asm/debugreg.h>
-#include <asm/resctrl.h>
 #include <asm/msr.h>
 #include <asm/sev.h>
 
@@ -475,8 +474,6 @@ static void bsp_init_amd(struct cpuinfo_x86 *c)
 		}
 	}
 
-	resctrl_cpu_detect(c);
-
 	/* Figure out Zen generations: */
 	switch (c->x86) {
 	case 0x17:
diff --git a/arch/x86/kernel/cpu/hygon.c b/arch/x86/kernel/cpu/hygon.c
index ec51c2b9a257..0f226335dd9a 100644
--- a/arch/x86/kernel/cpu/hygon.c
+++ b/arch/x86/kernel/cpu/hygon.c
@@ -17,7 +17,6 @@
 #include <asm/spec-ctrl.h>
 #include <asm/delay.h>
 #include <asm/msr.h>
-#include <asm/resctrl.h>
 
 #include "cpu.h"
 
@@ -119,8 +118,6 @@ static void bsp_init_hygon(struct cpuinfo_x86 *c)
 			x86_amd_ls_cfg_ssbd_mask = 1ULL << 10;
 		}
 	}
-
-	resctrl_cpu_detect(c);
 }
 
 static void early_init_hygon(struct cpuinfo_x86 *c)
diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c
index 4297ceb2cb24..2f09710e863c 100644
--- a/arch/x86/kernel/cpu/intel.c
+++ b/arch/x86/kernel/cpu/intel.c
@@ -22,7 +22,6 @@
 #include <asm/microcode.h>
 #include <asm/msr.h>
 #include <asm/numa.h>
-#include <asm/resctrl.h>
 #include <asm/thermal.h>
 #include <asm/uaccess.h>
 
@@ -371,11 +370,6 @@ static void early_init_intel(struct cpuinfo_x86 *c)
 		detect_tme_early(c);
 }
 
-static void bsp_init_intel(struct cpuinfo_x86 *c)
-{
-	resctrl_cpu_detect(c);
-}
-
 #ifdef CONFIG_X86_32
 /*
  *	Early probe support logic for ppro memory erratum #50
@@ -804,7 +798,6 @@ static const struct cpu_dev intel_cpu_dev = {
 #endif
 	.c_detect_tlb	= intel_detect_tlb,
 	.c_early_init   = early_init_intel,
-	.c_bsp_init	= bsp_init_intel,
 	.c_init		= init_intel,
 	.c_x86_vendor	= X86_VENDOR_INTEL,
 };
diff --git a/arch/x86/kernel/cpu/resctrl/core.c b/arch/x86/kernel/cpu/resctrl/core.c
index 82b27a0157ae..f0cfb37482d3 100644
--- a/arch/x86/kernel/cpu/resctrl/core.c
+++ b/arch/x86/kernel/cpu/resctrl/core.c
@@ -1083,48 +1083,6 @@ static __init void rdt_init_res_defs(void)
 
 static enum cpuhp_state rdt_online;
 
-/* Runs once on the BSP during boot. */
-void resctrl_cpu_detect(struct cpuinfo_x86 *c)
-{
-	if (!cpu_has(c, X86_FEATURE_CQM_LLC) && !cpu_has(c, X86_FEATURE_ABMC)) {
-		c->x86_cache_max_rmid  = -1;
-		c->x86_cache_occ_scale = -1;
-		c->x86_cache_mbm_width_offset = -1;
-		return;
-	}
-
-	/* will be overridden if occupancy monitoring exists */
-	c->x86_cache_max_rmid = cpuid_ebx(0xf);
-
-	if (cpu_has(c, X86_FEATURE_CQM_OCCUP_LLC) ||
-	    cpu_has(c, X86_FEATURE_CQM_MBM_TOTAL) ||
-	    cpu_has(c, X86_FEATURE_CQM_MBM_LOCAL) ||
-	    cpu_has(c, X86_FEATURE_ABMC)) {
-		u32 eax, ebx, ecx, edx;
-
-		/* QoS sub-leaf, EAX=0Fh, ECX=1 */
-		cpuid_count(0xf, 1, &eax, &ebx, &ecx, &edx);
-
-		c->x86_cache_max_rmid  = ecx;
-		c->x86_cache_occ_scale = ebx;
-		c->x86_cache_mbm_width_offset = eax & 0xff;
-
-		if (!c->x86_cache_mbm_width_offset) {
-			switch (c->x86_vendor) {
-			case X86_VENDOR_AMD:
-				c->x86_cache_mbm_width_offset = MBM_CNTR_WIDTH_OFFSET_AMD;
-				break;
-			case X86_VENDOR_HYGON:
-				c->x86_cache_mbm_width_offset = MBM_CNTR_WIDTH_OFFSET_HYGON;
-				break;
-			default:
-				/* Leave c->x86_cache_mbm_width_offset as 0 */
-				break;
-			}
-		}
-	}
-}
-
 static int __init resctrl_arch_late_init(void)
 {
 	struct rdt_resource *r;
-- 
2.55.0


^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH v13 07/25] arm,x86,fs/resctrl: Replace architecture resctrl_arch_{alloc,mon}_capable()
  2026-09-28 22:14 [PATCH v13 00/25] Allow AET to use PMT as loadable module Tony Luck
                   ` (5 preceding siblings ...)
  2026-09-28 22:14 ` [PATCH v13 06/25] x86/resctrl: Delete resctrl_cpu_detect() Tony Luck
@ 2026-09-28 22:14 ` Tony Luck
  2026-09-28 22:14 ` [PATCH v13 08/25] x86/resctrl: Update special case for Intel Haswell enumeration Tony Luck
                   ` (18 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Tony Luck @ 2026-09-28 22:14 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

All the information to determine whether a system is capable of allocation or
monitoring is available to the file system. Architecture helpers are not needed.

Define generic resctrl_alloc_capable() and resctrl_mon_capable() and
replace all architecture versions.

Suggested-by: Reinette Chatre <reinette.chatre@intel.com>
Signed-off-by: Tony Luck <tony.luck@intel.com>
---
v13:
	s/is alloc, or mon, capable/is capable of allocation or monitoring/
---
 include/linux/arm_mpam.h       |  3 ---
 include/linux/resctrl.h        | 30 ++++++++++++++++++++++++++++
 arch/x86/include/asm/resctrl.h | 10 ----------
 drivers/resctrl/mpam_resctrl.c | 26 ++----------------------
 fs/resctrl/monitor.c           | 10 +++++-----
 fs/resctrl/pseudo_lock.c       |  6 +++---
 fs/resctrl/rdtgroup.c          | 36 +++++++++++++++++-----------------
 7 files changed, 58 insertions(+), 63 deletions(-)

diff --git a/include/linux/arm_mpam.h b/include/linux/arm_mpam.h
index f92a36187a52..ba4131048260 100644
--- a/include/linux/arm_mpam.h
+++ b/include/linux/arm_mpam.h
@@ -50,9 +50,6 @@ static inline int mpam_ris_create(struct mpam_msc *msc, u8 ris_idx,
 }
 #endif
 
-bool resctrl_arch_alloc_capable(void);
-bool resctrl_arch_mon_capable(void);
-
 void resctrl_arch_set_cpu_default_closid(int cpu, u32 closid);
 void resctrl_arch_set_closid_rmid(struct task_struct *tsk, u32 closid, u32 rmid);
 void resctrl_arch_set_cpu_default_closid_rmid(int cpu, u32 closid, u32 rmid);
diff --git a/include/linux/resctrl.h b/include/linux/resctrl.h
index 10dfdca7f4bf..0e7fce070fde 100644
--- a/include/linux/resctrl.h
+++ b/include/linux/resctrl.h
@@ -346,6 +346,36 @@ struct rdt_resource {
  */
 struct rdt_resource *resctrl_arch_get_resource(enum resctrl_res_level l);
 
+/*
+ * resctrl_alloc_capable - Are any allocation resources enabled?
+ */
+static inline bool resctrl_alloc_capable(void)
+{
+	struct rdt_resource *r;
+
+	for_each_rdt_resource(r) {
+		if (r->alloc_capable)
+			return true;
+	}
+
+	return false;
+}
+
+/*
+ * resctrl_mon_capable - Are any monitor resources enabled?
+ */
+static inline bool resctrl_mon_capable(void)
+{
+	struct rdt_resource *r;
+
+	for_each_rdt_resource(r) {
+		if (r->mon_capable)
+			return true;
+	}
+
+	return false;
+}
+
 /**
  * struct resctrl_schema - configuration abilities of a resource presented to
  *			   user-space
diff --git a/arch/x86/include/asm/resctrl.h b/arch/x86/include/asm/resctrl.h
index 2031b30ff25b..9c44a7766631 100644
--- a/arch/x86/include/asm/resctrl.h
+++ b/arch/x86/include/asm/resctrl.h
@@ -50,11 +50,6 @@ DECLARE_STATIC_KEY_FALSE(rdt_enable_key);
 DECLARE_STATIC_KEY_FALSE(rdt_alloc_enable_key);
 DECLARE_STATIC_KEY_FALSE(rdt_mon_enable_key);
 
-static inline bool resctrl_arch_alloc_capable(void)
-{
-	return rdt_alloc_capable;
-}
-
 static inline void resctrl_arch_enable_alloc(void)
 {
 	static_branch_enable_cpuslocked(&rdt_alloc_enable_key);
@@ -67,11 +62,6 @@ static inline void resctrl_arch_disable_alloc(void)
 	static_branch_dec_cpuslocked(&rdt_enable_key);
 }
 
-static inline bool resctrl_arch_mon_capable(void)
-{
-	return rdt_mon_capable;
-}
-
 static inline void resctrl_arch_enable_mon(void)
 {
 	static_branch_enable_cpuslocked(&rdt_mon_enable_key);
diff --git a/drivers/resctrl/mpam_resctrl.c b/drivers/resctrl/mpam_resctrl.c
index f2c651e9f6ea..7ddee8f5162f 100644
--- a/drivers/resctrl/mpam_resctrl.c
+++ b/drivers/resctrl/mpam_resctrl.c
@@ -75,28 +75,6 @@ static DECLARE_WAIT_QUEUE_HEAD(wait_cacheinfo_ready);
  */
 static bool resctrl_enabled;
 
-bool resctrl_arch_alloc_capable(void)
-{
-	struct mpam_resctrl_res *res;
-	enum resctrl_res_level rid;
-
-	for_each_mpam_resctrl_control(res, rid) {
-		if (res->resctrl_res.alloc_capable)
-			return true;
-	}
-
-	return false;
-}
-
-bool resctrl_arch_mon_capable(void)
-{
-	struct mpam_resctrl_res *res = &mpam_resctrl_controls[RDT_RESOURCE_L3];
-	struct rdt_resource *l3 = &res->resctrl_res;
-
-	/* All monitors are presented as being on the L3 cache */
-	return l3->mon_capable;
-}
-
 bool resctrl_arch_is_evt_configurable(enum resctrl_event_id evt)
 {
 	return false;
@@ -1902,9 +1880,9 @@ int mpam_resctrl_setup(void)
 
 	cpus_read_unlock();
 
-	if (!resctrl_arch_alloc_capable() && !resctrl_arch_mon_capable()) {
+	if (!resctrl_alloc_capable() && !resctrl_mon_capable()) {
 		pr_debug("No alloc(%u) or monitor(%u) found - resctrl not supported\n",
-			 resctrl_arch_alloc_capable(), resctrl_arch_mon_capable());
+			 resctrl_alloc_capable(), resctrl_mon_capable());
 		return -EOPNOTSUPP;
 	}
 
diff --git a/fs/resctrl/monitor.c b/fs/resctrl/monitor.c
index 73413cb128ea..362737e13cd3 100644
--- a/fs/resctrl/monitor.c
+++ b/fs/resctrl/monitor.c
@@ -338,7 +338,7 @@ void free_rmid(u32 closid, u32 rmid)
 	 * allows architectures that ignore the closid parameter to avoid an
 	 * unnecessary check.
 	 */
-	if (!resctrl_arch_mon_capable() ||
+	if (!resctrl_mon_capable() ||
 	    idx == resctrl_arch_rmid_idx_encode(RESCTRL_RESERVED_CLOSID,
 						RESCTRL_RESERVED_RMID))
 		return;
@@ -888,7 +888,7 @@ void mbm_handle_overflow(struct work_struct *work)
 	 * If the filesystem has been unmounted this work no longer needs to
 	 * run.
 	 */
-	if (!resctrl_mounted || !resctrl_arch_mon_capable())
+	if (!resctrl_mounted || !resctrl_mon_capable())
 		goto out_unlock;
 
 	/*
@@ -950,7 +950,7 @@ void mbm_setup_overflow_handler(struct rdt_l3_mon_domain *dom, unsigned long del
 	 * When a domain comes online there is no guarantee the filesystem is
 	 * mounted. If not, there is no need to catch counter overflow.
 	 */
-	if (!resctrl_mounted || !resctrl_arch_mon_capable())
+	if (!resctrl_mounted || !resctrl_mon_capable())
 		return;
 	cpu = cpumask_any_housekeeping(&dom->hdr.cpu_mask, exclude_cpu);
 	dom->mbm_work_cpu = cpu;
@@ -966,7 +966,7 @@ int setup_rmid_lru_list(void)
 	u32 idx;
 	int i;
 
-	if (!resctrl_arch_mon_capable())
+	if (!resctrl_mon_capable())
 		return 0;
 
 	/*
@@ -1006,7 +1006,7 @@ int setup_rmid_lru_list(void)
 
 void free_rmid_lru_list(void)
 {
-	if (!resctrl_arch_mon_capable())
+	if (!resctrl_mon_capable())
 		return;
 
 	mutex_lock(&rdtgroup_mutex);
diff --git a/fs/resctrl/pseudo_lock.c b/fs/resctrl/pseudo_lock.c
index 56ab63f19bad..3d831227a42f 100644
--- a/fs/resctrl/pseudo_lock.c
+++ b/fs/resctrl/pseudo_lock.c
@@ -383,7 +383,7 @@ static int rdtgroup_locksetup_user_restrict(struct rdtgroup *rdtgrp)
 	if (ret)
 		goto err_cpus;
 
-	if (resctrl_arch_mon_capable()) {
+	if (resctrl_mon_capable()) {
 		ret = rdtgroup_kn_mode_restrict(rdtgrp, "mon_groups");
 		if (ret)
 			goto err_cpus_list;
@@ -430,7 +430,7 @@ static int rdtgroup_locksetup_user_restore(struct rdtgroup *rdtgrp)
 	if (ret)
 		goto err_cpus;
 
-	if (resctrl_arch_mon_capable()) {
+	if (resctrl_mon_capable()) {
 		ret = rdtgroup_kn_mode_restore(rdtgrp, "mon_groups", 0777);
 		if (ret)
 			goto err_cpus_list;
@@ -577,7 +577,7 @@ int rdtgroup_locksetup_exit(struct rdtgroup *rdtgrp)
 {
 	int ret;
 
-	if (resctrl_arch_mon_capable()) {
+	if (resctrl_mon_capable()) {
 		ret = alloc_rmid(rdtgrp->closid);
 		if (ret < 0) {
 			rdt_last_cmd_puts("Out of RMIDs\n");
diff --git a/fs/resctrl/rdtgroup.c b/fs/resctrl/rdtgroup.c
index 57ab090072c2..96a4978ce6b6 100644
--- a/fs/resctrl/rdtgroup.c
+++ b/fs/resctrl/rdtgroup.c
@@ -691,7 +691,7 @@ static bool is_closid_match(struct task_struct *t, struct rdtgroup *r)
 
 static bool is_rmid_match(struct task_struct *t, struct rdtgroup *r)
 {
-	return (resctrl_arch_mon_capable() && (r->type == RDTMON_GROUP) &&
+	return (resctrl_mon_capable() && (r->type == RDTMON_GROUP) &&
 		resctrl_arch_match_rmid(t, r->mon.parent->closid,
 					r->mon.rmid));
 }
@@ -3157,9 +3157,9 @@ static void resctrl_unmount(void)
 		resctrl_arch_reset_all_ctrls(r);
 
 	resctrl_fs_teardown();
-	if (resctrl_arch_alloc_capable())
+	if (resctrl_alloc_capable())
 		resctrl_arch_disable_alloc();
-	if (resctrl_arch_mon_capable())
+	if (resctrl_mon_capable())
 		resctrl_arch_disable_mon();
 	resctrl_mounted = false;
 	mutex_unlock(&rdtgroup_mutex);
@@ -3213,7 +3213,7 @@ static int rdt_get_tree(struct fs_context *fc)
 	if (ret)
 		goto out_schemata_free;
 
-	if (resctrl_arch_mon_capable())
+	if (resctrl_mon_capable())
 		flags |= RFTYPE_MON;
 
 	ret = rdtgroup_add_files(rdtgroup_default.kn, flags);
@@ -3226,7 +3226,7 @@ static int rdt_get_tree(struct fs_context *fc)
 	if (ret < 0)
 		goto out_closid_exit;
 
-	if (resctrl_arch_mon_capable()) {
+	if (resctrl_mon_capable()) {
 		ret = mongroup_create_dir(rdtgroup_default.kn,
 					  &rdtgroup_default, "mon_groups",
 					  &kn_mongrp);
@@ -3246,12 +3246,12 @@ static int rdt_get_tree(struct fs_context *fc)
 	if (ret)
 		goto out_mondata;
 
-	if (resctrl_arch_alloc_capable())
+	if (resctrl_alloc_capable())
 		resctrl_arch_enable_alloc();
-	if (resctrl_arch_mon_capable())
+	if (resctrl_mon_capable())
 		resctrl_arch_enable_mon();
 
-	if (resctrl_arch_alloc_capable() || resctrl_arch_mon_capable())
+	if (resctrl_alloc_capable() || resctrl_mon_capable())
 		resctrl_mounted = true;
 
 	if (resctrl_is_mbm_enabled()) {
@@ -3294,10 +3294,10 @@ static int rdt_get_tree(struct fs_context *fc)
 	return ret;
 
 out_mondata:
-	if (resctrl_arch_mon_capable())
+	if (resctrl_mon_capable())
 		kernfs_remove(kn_mondata);
 out_mongrp:
-	if (resctrl_arch_mon_capable()) {
+	if (resctrl_mon_capable()) {
 		mon_put_kn_priv();
 		rdtgroup_unassign_cntrs(&rdtgroup_default);
 		kernfs_remove(kn_mongrp);
@@ -3886,7 +3886,7 @@ static int mkdir_rdt_prepare_rmid_alloc(struct rdtgroup *rdtgrp)
 {
 	int ret;
 
-	if (!resctrl_arch_mon_capable())
+	if (!resctrl_mon_capable())
 		return 0;
 
 	ret = alloc_rmid(rdtgrp->closid);
@@ -3911,7 +3911,7 @@ static int mkdir_rdt_prepare_rmid_alloc(struct rdtgroup *rdtgrp)
 
 static void mkdir_rdt_prepare_rmid_free(struct rdtgroup *rgrp)
 {
-	if (resctrl_arch_mon_capable()) {
+	if (resctrl_mon_capable()) {
 		rdtgroup_unassign_cntrs(rgrp);
 		free_rmid(rgrp->closid, rgrp->mon.rmid);
 	}
@@ -4002,7 +4002,7 @@ static int mkdir_rdt_prepare(struct kernfs_node *parent_kn,
 
 	if (rtype == RDTCTRL_GROUP) {
 		files = RFTYPE_BASE | RFTYPE_CTRL;
-		if (resctrl_arch_mon_capable())
+		if (resctrl_mon_capable())
 			files |= RFTYPE_MON;
 	} else {
 		files = RFTYPE_BASE | RFTYPE_MON;
@@ -4111,7 +4111,7 @@ static int rdtgroup_mkdir_ctrl_mon(struct kernfs_node *parent_kn,
 
 	list_add(&rdtgrp->rdtgroup_list, &rdt_all_groups);
 
-	if (resctrl_arch_mon_capable()) {
+	if (resctrl_mon_capable()) {
 		/*
 		 * Create an empty mon_groups directory to hold the subset
 		 * of tasks and cpus to monitor.
@@ -4152,11 +4152,11 @@ static int rdtgroup_mkdir(struct kernfs_node *parent_kn, const char *name,
 	 * allocation is supported, add a control and monitoring
 	 * subdirectory
 	 */
-	if (resctrl_arch_alloc_capable() && parent_kn == rdtgroup_default.kn)
+	if (resctrl_alloc_capable() && parent_kn == rdtgroup_default.kn)
 		return rdtgroup_mkdir_ctrl_mon(parent_kn, name, mode);
 
 	/* Else, attempt to add a monitoring subdirectory. */
-	if (resctrl_arch_mon_capable())
+	if (resctrl_mon_capable())
 		return rdtgroup_mkdir_mon(parent_kn, name, mode);
 
 	return -EPERM;
@@ -4571,7 +4571,7 @@ void resctrl_offline_mon_domain(struct rdt_resource *r, struct rdt_domain_hdr *h
 	 * If resctrl is mounted, remove all the
 	 * per domain monitor data directories.
 	 */
-	if (resctrl_mounted && resctrl_arch_mon_capable())
+	if (resctrl_mounted && resctrl_mon_capable())
 		rmdir_mondata_subdir_allrdtgrp(r, hdr);
 
 	if (r->rid != RDT_RESOURCE_L3)
@@ -4708,7 +4708,7 @@ int resctrl_online_mon_domain(struct rdt_resource *r, struct rdt_domain_hdr *hdr
 	 * by rdt_get_tree() calling mkdir_mondata_all().
 	 * If resctrl is mounted, add per domain monitor data directories.
 	 */
-	if (resctrl_mounted && resctrl_arch_mon_capable())
+	if (resctrl_mounted && resctrl_mon_capable())
 		mkdir_mondata_subdir_allrdtgrp(r, hdr);
 
 out_unlock:
-- 
2.55.0


^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH v13 08/25] x86/resctrl: Update special case for Intel Haswell enumeration
  2026-09-28 22:14 [PATCH v13 00/25] Allow AET to use PMT as loadable module Tony Luck
                   ` (6 preceding siblings ...)
  2026-09-28 22:14 ` [PATCH v13 07/25] arm,x86,fs/resctrl: Replace architecture resctrl_arch_{alloc,mon}_capable() Tony Luck
@ 2026-09-28 22:14 ` Tony Luck
  2026-09-28 22:14 ` [PATCH v13 09/25] x86/resctrl: Delete rdt_alloc_capable and rdt_mon_capable Tony Luck
                   ` (17 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Tony Luck @ 2026-09-28 22:14 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

Certain Intel Haswell CPUs support resctrl L3 cache allocation but do not
enumerate the feature. A quirk probes for support and provides hard-coded
parameters. The quirk sets both the global rdt_alloc_capable and the resource
specific rdt_resource::alloc_capable, only the global is used to signal that
normal enumeration can be skipped.

The global rdt_alloc_capable is redundant since rdt_resource::alloc_capable
already carries the same information.

Stop setting rdt_alloc_capable in the quirk and rely on the resource specific
flag to prepare for removal of this global variable.

No functional change intended.

Signed-off-by: Tony Luck <tony.luck@intel.com>
---
v13:
	Replaced commit comment with Reinette's improved version.
---
 arch/x86/kernel/cpu/resctrl/core.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/arch/x86/kernel/cpu/resctrl/core.c b/arch/x86/kernel/cpu/resctrl/core.c
index f0cfb37482d3..f2bf160d01c1 100644
--- a/arch/x86/kernel/cpu/resctrl/core.c
+++ b/arch/x86/kernel/cpu/resctrl/core.c
@@ -177,8 +177,6 @@ static inline void cache_alloc_hsw_probe(void)
 	r->cache.min_cbm_bits = 2;
 	r->cache.arch_has_sparse_bitmasks = false;
 	r->alloc_capable = true;
-
-	rdt_alloc_capable = true;
 }
 
 /*
@@ -930,7 +928,11 @@ static __init bool get_rdt_alloc_resources(void)
 	struct rdt_resource *r;
 	bool ret = false;
 
-	if (rdt_alloc_capable)
+	/*
+	 * On Haswell systems cache_alloc_hsw_probe() already marked
+	 * RDT_RESOURCE_L3 as alloc_capable. No further enumeration is needed.
+	 */
+	if (resctrl_alloc_capable())
 		return true;
 
 	if (!boot_cpu_has(X86_FEATURE_RDT_A))
-- 
2.55.0


^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH v13 09/25] x86/resctrl: Delete rdt_alloc_capable and rdt_mon_capable
  2026-09-28 22:14 [PATCH v13 00/25] Allow AET to use PMT as loadable module Tony Luck
                   ` (7 preceding siblings ...)
  2026-09-28 22:14 ` [PATCH v13 08/25] x86/resctrl: Update special case for Intel Haswell enumeration Tony Luck
@ 2026-09-28 22:14 ` Tony Luck
  2026-09-28 22:14 ` [PATCH v13 10/25] fs/resctrl: Remove redundant calls to resctrl_mon_capable() Tony Luck
                   ` (16 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Tony Luck @ 2026-09-28 22:14 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

These global variables have been replaced with resctrl_alloc_capable() or
resctrl_mon_capable(), delete the global declarations.

Signed-off-by: Tony Luck <tony.luck@intel.com>
---
v13:
	Expand commit message.
---
 arch/x86/include/asm/resctrl.h        |  2 --
 arch/x86/kernel/cpu/resctrl/core.c    | 13 +++----------
 arch/x86/kernel/cpu/resctrl/monitor.c |  6 ------
 3 files changed, 3 insertions(+), 18 deletions(-)

diff --git a/arch/x86/include/asm/resctrl.h b/arch/x86/include/asm/resctrl.h
index 9c44a7766631..8c3b51398ddc 100644
--- a/arch/x86/include/asm/resctrl.h
+++ b/arch/x86/include/asm/resctrl.h
@@ -42,8 +42,6 @@ struct resctrl_pqr_state {
 
 DECLARE_PER_CPU(struct resctrl_pqr_state, pqr_state);
 
-extern bool rdt_alloc_capable;
-extern bool rdt_mon_capable;
 extern unsigned int rdt_l3_mon_scale;
 
 DECLARE_STATIC_KEY_FALSE(rdt_enable_key);
diff --git a/arch/x86/kernel/cpu/resctrl/core.c b/arch/x86/kernel/cpu/resctrl/core.c
index f2bf160d01c1..2e3b9c16cbda 100644
--- a/arch/x86/kernel/cpu/resctrl/core.c
+++ b/arch/x86/kernel/cpu/resctrl/core.c
@@ -45,12 +45,6 @@ static DEFINE_MUTEX(domain_list_lock);
  */
 DEFINE_PER_CPU(struct resctrl_pqr_state, pqr_state);
 
-/*
- * Global boolean for rdt_alloc which is true if any
- * resource allocation is enabled.
- */
-bool rdt_alloc_capable;
-
 static void mba_wrmsr_intel(struct msr_param *m);
 static void cat_wrmsr(struct msr_param *m);
 static void mba_wrmsr_amd(struct msr_param *m);
@@ -781,7 +775,6 @@ void resctrl_arch_pre_mount(void)
 	cpus_read_lock();
 	mutex_lock(&domain_list_lock);
 	r->mon_capable = true;
-	rdt_mon_capable = true;
 	for_each_online_cpu(cpu)
 		domain_add_cpu_mon(cpu, r);
 	mutex_unlock(&domain_list_lock);
@@ -1026,10 +1019,10 @@ 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();
+	bool alloc = get_rdt_alloc_resources();
+	bool mon = get_rdt_mon_resources();
 
-	return (rdt_mon_capable || rdt_alloc_capable);
+	return alloc || mon;
 }
 
 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 468e9821f35a..82a555855c1b 100644
--- a/arch/x86/kernel/cpu/resctrl/monitor.c
+++ b/arch/x86/kernel/cpu/resctrl/monitor.c
@@ -26,12 +26,6 @@
 
 #include "internal.h"
 
-/*
- * Global boolean for rdt_monitor which is true if any
- * resource monitoring is enabled.
- */
-bool rdt_mon_capable;
-
 /*
  * Scale factor to convert L3 monitor events to bytes.
  */
-- 
2.55.0


^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH v13 10/25] fs/resctrl: Remove redundant calls to resctrl_mon_capable()
  2026-09-28 22:14 [PATCH v13 00/25] Allow AET to use PMT as loadable module Tony Luck
                   ` (8 preceding siblings ...)
  2026-09-28 22:14 ` [PATCH v13 09/25] x86/resctrl: Delete rdt_alloc_capable and rdt_mon_capable Tony Luck
@ 2026-09-28 22:14 ` Tony Luck
  2026-09-28 22:14 ` [PATCH v13 11/25] x86/resctrl: Honor rdt={perf|energy} options to force enable AET events Tony Luck
                   ` (15 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Tony Luck @ 2026-09-28 22:14 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_mon_capable() indicates whether any monitoring resources
are enabled on the system. It does this by scanning all resources.

Redundant calls to resctrl_mon_capable() in hot code paths should
be eliminated. There are two prime examples:

1) mbm_handle_overflow()
This function is called once per second from worker threads running on
each L3 domain. resctrl_mon_capable() is clearly redundant because worker
threads are only created if the MBM monitoring feature is enabled.

2) is_rmid_match()
This is called for every task on the system so making it less expensive is
appealing.  resctrl_mon_capable() is redundant because the function also
checks "r->type == RDTMON_GROUP" and this type of group can only be created
on systems that support monitoring.

Remove the call to resctrl_mon_capable() from each of these functions.

Signed-off-by: Tony Luck <tony.luck@intel.com>
---
v13:
	Moved change to is_closid_match() to its own patch.
---
 fs/resctrl/monitor.c  | 2 +-
 fs/resctrl/rdtgroup.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/fs/resctrl/monitor.c b/fs/resctrl/monitor.c
index 362737e13cd3..02e81fc82b14 100644
--- a/fs/resctrl/monitor.c
+++ b/fs/resctrl/monitor.c
@@ -888,7 +888,7 @@ void mbm_handle_overflow(struct work_struct *work)
 	 * If the filesystem has been unmounted this work no longer needs to
 	 * run.
 	 */
-	if (!resctrl_mounted || !resctrl_mon_capable())
+	if (!resctrl_mounted)
 		goto out_unlock;
 
 	/*
diff --git a/fs/resctrl/rdtgroup.c b/fs/resctrl/rdtgroup.c
index 96a4978ce6b6..7cf809380c53 100644
--- a/fs/resctrl/rdtgroup.c
+++ b/fs/resctrl/rdtgroup.c
@@ -691,7 +691,7 @@ static bool is_closid_match(struct task_struct *t, struct rdtgroup *r)
 
 static bool is_rmid_match(struct task_struct *t, struct rdtgroup *r)
 {
-	return (resctrl_mon_capable() && (r->type == RDTMON_GROUP) &&
+	return (r->type == RDTMON_GROUP &&
 		resctrl_arch_match_rmid(t, r->mon.parent->closid,
 					r->mon.rmid));
 }
-- 
2.55.0


^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH v13 11/25] x86/resctrl: Honor rdt={perf|energy} options to force enable AET events
  2026-09-28 22:14 [PATCH v13 00/25] Allow AET to use PMT as loadable module Tony Luck
                   ` (9 preceding siblings ...)
  2026-09-28 22:14 ` [PATCH v13 10/25] fs/resctrl: Remove redundant calls to resctrl_mon_capable() Tony Luck
@ 2026-09-28 22:14 ` Tony Luck
  2026-09-28 22:14 ` [PATCH v13 12/25] fs/resctrl: Add interface to disable a monitor event Tony Luck
                   ` (14 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Tony Luck @ 2026-09-28 22:14 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 can disable ("force_off") a feature supported by the platform if,
for example, there is an erratum related to the feature or, in the case of AET
(Application Energy Telemetry), when the event group has insufficient RMIDs. The
"rdt=" kernel command line option lets the user override ("force_on") when
a feature is disabled in such case. Users may also disable ("force_off")
individual supported resctrl features they do not need.

Linux enumerates AET once on first mount and skips this enumeration if
the associated event group is supported but disabled. Since AET is only
enumerated once, this check is guaranteed to only consider disabling via
the rdt= kernel parameter.

However, when transitioning to enumerate AET on every mount, it is no longer
correct to skip enumeration simply because an event group is marked as
disabled. It is then possible for resctrl to have force-disabled the event
group during an earlier enumeration due to insufficient RMIDs, which would
improperly cause the kernel to ignore a user's explicit rdt= override on
subsequent mounts.

Ensure the user's command line choices take precedence over system-level limits.

Reviewed-by: Reinette Chatre <reinette.chatre@intel.com>
Signed-off-by: Tony Luck <tony.luck@intel.com>
---
v13:
	Update subject and commit comment to reflect that this change
	applies equally to rdt=energy.
---
 arch/x86/kernel/cpu/resctrl/intel_aet.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/x86/kernel/cpu/resctrl/intel_aet.c b/arch/x86/kernel/cpu/resctrl/intel_aet.c
index c22c3cf5167d..4ad6ad78e93e 100644
--- a/arch/x86/kernel/cpu/resctrl/intel_aet.c
+++ b/arch/x86/kernel/cpu/resctrl/intel_aet.c
@@ -228,7 +228,7 @@ static bool enable_events(struct event_group *e, struct pmt_feature_group *p)
 	struct rdt_resource *r = &rdt_resources_all[RDT_RESOURCE_PERF_PKG].r_resctrl;
 	int skipped_events = 0;
 
-	if (e->force_off)
+	if (e->force_off && !e->force_on)
 		return false;
 
 	if (!group_has_usable_regions(e, p))
-- 
2.55.0


^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH v13 12/25] fs/resctrl: Add interface to disable a monitor event
  2026-09-28 22:14 [PATCH v13 00/25] Allow AET to use PMT as loadable module Tony Luck
                   ` (10 preceding siblings ...)
  2026-09-28 22:14 ` [PATCH v13 11/25] x86/resctrl: Honor rdt={perf|energy} options to force enable AET events Tony Luck
@ 2026-09-28 22:14 ` Tony Luck
  2026-09-28 22:14 ` [PATCH v13 13/25] arm,x86,fs/resctrl: Allocate maximum needed rmid_ptrs[] Tony Luck
                   ` (13 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Tony Luck @ 2026-09-28 22:14 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 currently assumes all monitor events are enabled before any domain
is created, because per-domain state is allocated by the architecture's CPU
hotplug callbacks. There is no way to disable an event once registered.

AET events are enumerated by the INTEL_PMT_TELEMETRY driver. To allow that
driver to be a loadable module, resctrl must tolerate AET events appearing
and disappearing, which requires the ability to disable an event when the
driver is unloaded.

Add resctrl_disable_mon_event(). The architecture owns domain lifetime
and knows mount state, so it is responsible for calling this only while
resctrl is unmounted and for cleaning up any per-domain state. Document
those requirements in the kerneldoc since they are not enforced in code.

Reviewed-by: Reinette Chatre <reinette.chatre@intel.com>
Signed-off-by: Tony Luck <tony.luck@intel.com>
---
v13:
	Add back the comment that events must not be disabled while
	the file system is mounted.
---
 include/linux/resctrl.h | 36 ++++++++++++++++++++++++++++++++++++
 fs/resctrl/monitor.c    | 15 +++++++++++++++
 2 files changed, 51 insertions(+)

diff --git a/include/linux/resctrl.h b/include/linux/resctrl.h
index 0e7fce070fde..764c45be2d59 100644
--- a/include/linux/resctrl.h
+++ b/include/linux/resctrl.h
@@ -449,9 +449,45 @@ 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
+ *
+ * Never disable an event while the file system is mounted. Never
+ * disable an event that may be accessed while the file system is
+ * unmounted.
+ *
+ * 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 02e81fc82b14..2a28fe04284b 100644
--- a/fs/resctrl/monitor.c
+++ b/fs/resctrl/monitor.c
@@ -1066,6 +1066,21 @@ 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("Event %d already disabled\n", eventid);
+		return;
+	}
+
+	mon_event_all[eventid].any_cpu = false;
+	mon_event_all[eventid].binary_bits = 0;
+	mon_event_all[eventid].arch_priv = NULL;
+	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.55.0


^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH v13 13/25] arm,x86,fs/resctrl: Allocate maximum needed rmid_ptrs[]
  2026-09-28 22:14 [PATCH v13 00/25] Allow AET to use PMT as loadable module Tony Luck
                   ` (11 preceding siblings ...)
  2026-09-28 22:14 ` [PATCH v13 12/25] fs/resctrl: Add interface to disable a monitor event Tony Luck
@ 2026-09-28 22:14 ` Tony Luck
  2026-09-28 22:14 ` [PATCH v13 14/25] arm,x86,fs/resctrl: Use right size for L3 monitor data structures Tony Luck
                   ` (12 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Tony Luck @ 2026-09-28 22:14 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 keeps per-RMID state in rmid_ptrs[]. It is allocated on first mount,
sized for the number of RMIDs available at that time, and reused by every
subsequent mount.

Application Energy Telemetry (AET) requires the pmt_telemetry driver to be
built in. Allowing it to be built as a module means the number of RMIDs can
change from one mount to the next, so a later mount may need more entries
than the first mount allocated. Reallocating per mount is not possible because
the limbo handler continues to access rmid_ptrs[] after resctrl is unmounted.

Size rmid_ptrs[] for the maximum number of RMIDs the system can ever need,
so that it is large enough for any future mount. Build the free list
based on the number of RMIDs needed for the current mount cycle.

Signed-off-by: Tony Luck <tony.luck@intel.com>
---
v13:
	Updated commit message using Reinette suggestion.
	Merged patch 14 "Rebuild free RMID list on each mount" into
	this patch as the split into separate patches didn't work
	as well as I hoped.
---
 include/linux/resctrl.h            |  1 +
 arch/x86/kernel/cpu/resctrl/core.c | 27 +++++++++++++
 drivers/resctrl/mpam_resctrl.c     |  9 +++++
 fs/resctrl/monitor.c               | 64 ++++++++++++++++++++----------
 4 files changed, 79 insertions(+), 22 deletions(-)

diff --git a/include/linux/resctrl.h b/include/linux/resctrl.h
index 764c45be2d59..7afeb3bd55d9 100644
--- a/include/linux/resctrl.h
+++ b/include/linux/resctrl.h
@@ -447,6 +447,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 2e3b9c16cbda..8702a6da2374 100644
--- a/arch/x86/kernel/cpu/resctrl/core.c
+++ b/arch/x86/kernel/cpu/resctrl/core.c
@@ -45,6 +45,9 @@ static DEFINE_MUTEX(domain_list_lock);
  */
 DEFINE_PER_CPU(struct resctrl_pqr_state, pqr_state);
 
+/* Number of unique RMID values that can be written to MSR_IA32_PQR_ASSOC.RMID */
+static u32 pqr_assoc_num_rmid;
+
 static void mba_wrmsr_intel(struct msr_param *m);
 static void cat_wrmsr(struct msr_param *m);
 static void mba_wrmsr_amd(struct msr_param *m);
@@ -124,6 +127,28 @@ u32 resctrl_arch_system_num_rmid_idx(void)
 	return num_rmids == U32_MAX ? 0 : num_rmids;
 }
 
+/**
+ * resctrl_arch_system_max_rmid_idx - Largest possible RMID index
+ *
+ * Return: Largest possible RMID index used for boot time allocations.
+ */
+u32 resctrl_arch_system_max_rmid_idx(void)
+{
+	struct rdt_resource *r = &rdt_resources_all[RDT_RESOURCE_L3].r_resctrl;
+	u32 num_rmid = pqr_assoc_num_rmid;
+
+	/*
+	 * If the system is capable of L3 monitoring the maximum RMID value may
+	 * be lower than the system maximum. Either because the L3 monitoring
+	 * feature supports fewer RMIDs, or because SNC (Sub-NUMA Cluster)
+	 * is enabled and divides RMIDs per cluster.
+	 */
+	if (r->mon_capable)
+		num_rmid = r->mon.num_rmid;
+
+	return num_rmid;
+}
+
 struct rdt_resource *resctrl_arch_get_resource(enum resctrl_res_level l)
 {
 	if (l >= RDT_NUM_RESOURCES)
@@ -967,6 +992,8 @@ static __init bool get_rdt_mon_resources(void)
 	if (!cpu_feature_enabled(X86_FEATURE_CQM))
 		return false;
 
+	pqr_assoc_num_rmid = cpuid_ebx(0xf) + 1;
+
 	/* Any of the L3 monitoring features? */
 	if (!cpu_feature_enabled(X86_FEATURE_CQM_LLC))
 		return false;
diff --git a/drivers/resctrl/mpam_resctrl.c b/drivers/resctrl/mpam_resctrl.c
index 7ddee8f5162f..52726f7fd03f 100644
--- a/drivers/resctrl/mpam_resctrl.c
+++ b/drivers/resctrl/mpam_resctrl.c
@@ -257,6 +257,15 @@ u32 resctrl_arch_system_num_rmid_idx(void)
 	return (mpam_pmg_max + 1) * (mpam_partid_max + 1);
 }
 
+/*
+ * File system calls this for one-time allocation of structures.
+ * Return the largest possible value.
+ */
+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 2a28fe04284b..ccfb1548fea1 100644
--- a/fs/resctrl/monitor.c
+++ b/fs/resctrl/monitor.c
@@ -75,6 +75,11 @@ static unsigned int rmid_limbo_count;
  */
 static struct rmid_entry	*rmid_ptrs;
 
+/*
+ * @num_rmid_ptrs - The number of elements in rmid_ptrs[].
+ */
+static u32 num_rmid_ptrs;
+
 /*
  * This is the threshold cache occupancy in bytes at which we will consider an
  * RMID available for re-allocation.
@@ -961,45 +966,60 @@ void mbm_setup_overflow_handler(struct rdt_l3_mon_domain *dom, unsigned long del
 
 int setup_rmid_lru_list(void)
 {
-	struct rmid_entry *entry = NULL;
-	u32 idx_limit;
-	u32 idx;
+	struct rmid_entry *entry;
+	u32 cur_idx_limit;
+	u32 rsvd_idx;
 	int i;
 
 	if (!resctrl_mon_capable())
 		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) {
+		num_rmid_ptrs = resctrl_arch_system_max_rmid_idx();
+		rmid_ptrs = kzalloc_objs(struct rmid_entry, num_rmid_ptrs);
+		if (!rmid_ptrs) {
+			num_rmid_ptrs = 0;
+			return -ENOMEM;
+		}
 
-	idx_limit = resctrl_arch_system_num_rmid_idx();
-	rmid_ptrs = kzalloc_objs(struct rmid_entry, idx_limit);
-	if (!rmid_ptrs)
-		return -ENOMEM;
+		for (i = 0; i < num_rmid_ptrs; i++) {
+			entry = &rmid_ptrs[i];
+			INIT_LIST_HEAD(&entry->list);
 
-	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);
+		}
+	}
 
-		resctrl_arch_rmid_idx_decode(i, &entry->closid, &entry->rmid);
-		list_add_tail(&entry->list, &rmid_free_lru);
+	/* Find how many RMIDs are available for this mount */
+	cur_idx_limit = resctrl_arch_system_num_rmid_idx();
+	if (cur_idx_limit > num_rmid_ptrs) {
+		pr_warn_once("RMID count %u exceeds allocation. Limit to %u\n",
+			     cur_idx_limit, num_rmid_ptrs);
+		cur_idx_limit = num_rmid_ptrs;
 	}
 
+	INIT_LIST_HEAD(&rmid_free_lru);
+
 	/*
 	 * RESCTRL_RESERVED_CLOSID and RESCTRL_RESERVED_RMID are special and
 	 * are always allocated. These are used for the rdtgroup_default
 	 * control group, which was setup earlier in rdtgroup_setup_default().
 	 */
-	idx = resctrl_arch_rmid_idx_encode(RESCTRL_RESERVED_CLOSID,
-					   RESCTRL_RESERVED_RMID);
-	entry = __rmid_entry(idx);
-	list_del(&entry->list);
+	rsvd_idx = resctrl_arch_rmid_idx_encode(RESCTRL_RESERVED_CLOSID,
+						RESCTRL_RESERVED_RMID);
+
+	for (i = 0; i < cur_idx_limit; i++) {
+		entry = &rmid_ptrs[i];
+		/* Don't add reserved or busy entries to free list */
+		if (i == rsvd_idx || entry->busy)
+			continue;
+		list_add_tail(&entry->list, &rmid_free_lru);
+	}
 
 	return 0;
 }
-- 
2.55.0


^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH v13 14/25] arm,x86,fs/resctrl: Use right size for L3 monitor data structures
  2026-09-28 22:14 [PATCH v13 00/25] Allow AET to use PMT as loadable module Tony Luck
                   ` (12 preceding siblings ...)
  2026-09-28 22:14 ` [PATCH v13 13/25] arm,x86,fs/resctrl: Allocate maximum needed rmid_ptrs[] Tony Luck
@ 2026-09-28 22:14 ` Tony Luck
  2026-09-28 22:14 ` [PATCH v13 15/25] x86,fs/resctrl: Handle systems where AET is the only resource Tony Luck
                   ` (11 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Tony Luck @ 2026-09-28 22:14 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

The number of RMIDs available for use is computed as the minimum value across
all enabled monitoring resources. This value does not currently change from
one mount to the next. But when changes are made to allow configuration
of the pmt_telemetry driver as a module the Application Energy Telemetry
events will only be enabled if the module is loaded at the point when the
file system is mounted. This may result in the available number of RMIDs
changing from one mount to the next.

The RDT_RESOURCE_L3 allocates some data structures sized by the
number of RMIDs:
* rdt_l3_mon_domain::rmid_busy_llc is a bitmap tracking which RMIDs
  have active L3 cache occupancy counts.
* rdt_l3_mon_domain::mbm_states[] tracks memory bandwidth for the
  "mba_MBps" software controller.
* rdt_hw_l3_mon_domain::arch_mbm_states[] keeps total count of memory
  traffic (handling overflow of hardware counters).

These structures must be allocated and manipulated based on the number
of RMIDs supported by the L3 (this will not change from mount to mount).

The limbo code must be prepared to deal with changes in the number of RMIDs
from one mount to the next because some RMIDs may still be "busy" when the
file system is unmounted, but be above resctrl_arch_system_num_rmid_idx()
for the remount. In this case RMIDs that can be released are not put onto
the rmid_free_lru list.

Use the L3 rdt_resource::mon.num_rmid to allocate and operate on these
data structures.

Signed-off-by: Tony Luck <tony.luck@intel.com>
---
v13:
	Drop rename of local "idx_limit" to "l3_idx_limit"
	Re-wrote commit message.
---
 include/linux/resctrl.h            |  7 +++++--
 arch/x86/kernel/cpu/resctrl/core.c |  5 +++++
 drivers/resctrl/mpam_resctrl.c     |  5 +++++
 fs/resctrl/monitor.c               | 22 ++++++++++++++++++----
 fs/resctrl/rdtgroup.c              |  2 +-
 5 files changed, 34 insertions(+), 7 deletions(-)

diff --git a/include/linux/resctrl.h b/include/linux/resctrl.h
index 7afeb3bd55d9..c77e24c0d8b6 100644
--- a/include/linux/resctrl.h
+++ b/include/linux/resctrl.h
@@ -183,10 +183,12 @@ struct mbm_cntr_cfg {
  * struct rdt_l3_mon_domain - group of CPUs sharing RDT_RESOURCE_L3 monitoring
  * @hdr:		common header for different domain types
  * @ci_id:		cache info id for this domain
- * @rmid_busy_llc:	bitmap of which limbo RMIDs are above threshold
+ * @rmid_busy_llc:	bitmap of which limbo RMIDs are above threshold. Sized for
+ *			maximum supported RMIDs in L3 resource.
  * @mbm_states:		Per-event pointer to the MBM event's saved state.
  *			An MBM event's state is an array of struct mbm_state
  *			indexed by RMID on x86 or combined CLOSID, RMID on Arm.
+ *			Sized same as @rmid_busy_llc.
  * @mbm_over:		worker to periodically read MBM h/w counters
  * @cqm_limbo:		worker to periodically read CQM h/w counters
  * @mbm_work_cpu:	worker CPU for MBM h/w counters
@@ -444,8 +446,9 @@ static inline u32 resctrl_get_default_ctrl(struct rdt_resource *r)
 	return WARN_ON_ONCE(1);
 }
 
-/* The number of closid supported by this resource regardless of CDP */
+/* The number of closid/rmid supported by this resource regardless of CDP */
 u32 resctrl_arch_get_num_closid(struct rdt_resource *r);
+u32 resctrl_arch_get_num_rmid_idx(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 8702a6da2374..b32fa143283e 100644
--- a/arch/x86/kernel/cpu/resctrl/core.c
+++ b/arch/x86/kernel/cpu/resctrl/core.c
@@ -380,6 +380,11 @@ u32 resctrl_arch_get_num_closid(struct rdt_resource *r)
 	return resctrl_to_arch_res(r)->num_closid;
 }
 
+u32 resctrl_arch_get_num_rmid_idx(struct rdt_resource *r)
+{
+	return r->mon.num_rmid;
+}
+
 void rdt_ctrl_update(void *arg)
 {
 	struct rdt_hw_resource *hw_res;
diff --git a/drivers/resctrl/mpam_resctrl.c b/drivers/resctrl/mpam_resctrl.c
index 52726f7fd03f..360a50eb0cd3 100644
--- a/drivers/resctrl/mpam_resctrl.c
+++ b/drivers/resctrl/mpam_resctrl.c
@@ -252,6 +252,11 @@ u32 resctrl_arch_get_num_closid(struct rdt_resource *ignored)
 	return mpam_partid_max + 1;
 }
 
+u32 resctrl_arch_get_num_rmid_idx(struct rdt_resource *ignored)
+{
+	return resctrl_arch_system_num_rmid_idx();
+}
+
 u32 resctrl_arch_system_num_rmid_idx(void)
 {
 	return (mpam_pmg_max + 1) * (mpam_partid_max + 1);
diff --git a/fs/resctrl/monitor.c b/fs/resctrl/monitor.c
index ccfb1548fea1..1d55f138e2f6 100644
--- a/fs/resctrl/monitor.c
+++ b/fs/resctrl/monitor.c
@@ -120,10 +120,18 @@ static inline struct rmid_entry *__rmid_entry(u32 idx)
 
 static void limbo_release_entry(struct rmid_entry *entry)
 {
+	u32 cur_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) < cur_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]--;
@@ -138,7 +146,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_get_num_rmid_idx(r);
 	struct rmid_entry *entry;
 	bool rmid_dirty = true;
 	u32 idx, cur_idx = 1;
@@ -159,6 +167,11 @@ void __check_limbo(struct rdt_l3_mon_domain *d, bool force_free)
 	 * are marked as busy for occupancy < threshold. If the occupancy
 	 * is less than the threshold decrement the busy counter of the
 	 * RMID and move it to the free list when the counter reaches 0.
+	 *
+	 * RMIDs will keep counts of allocated LLC entries after the resctrl
+	 * file system is unmounted. So check all possible RMIDs since a
+	 * previous mount cycle may have used more than are available in
+	 * this mount cycle.
 	 */
 	for (;;) {
 		idx = find_next_bit(d->rmid_busy_llc, idx_limit, cur_idx);
@@ -202,7 +215,8 @@ 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();
+	struct rdt_resource *r = resctrl_arch_get_resource(RDT_RESOURCE_L3);
+	u32 idx_limit = resctrl_arch_get_num_rmid_idx(r);
 
 	return find_first_bit(d->rmid_busy_llc, idx_limit) != idx_limit;
 }
@@ -1238,7 +1252,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_get_num_rmid_idx(r);
 	enum resctrl_event_id evt;
 	int idx;
 
diff --git a/fs/resctrl/rdtgroup.c b/fs/resctrl/rdtgroup.c
index 7cf809380c53..79d4ddc3d64d 100644
--- a/fs/resctrl/rdtgroup.c
+++ b/fs/resctrl/rdtgroup.c
@@ -4619,7 +4619,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_get_num_rmid_idx(r);
 	size_t tsize = sizeof(*d->mbm_states[0]);
 	enum resctrl_event_id eventid;
 	int idx;
-- 
2.55.0


^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH v13 15/25] x86,fs/resctrl: Handle systems where AET is the only resource
  2026-09-28 22:14 [PATCH v13 00/25] Allow AET to use PMT as loadable module Tony Luck
                   ` (13 preceding siblings ...)
  2026-09-28 22:14 ` [PATCH v13 14/25] arm,x86,fs/resctrl: Use right size for L3 monitor data structures Tony Luck
@ 2026-09-28 22:14 ` Tony Luck
  2026-09-28 22:15 ` [PATCH v13 16/25] x86/resctrl: Add PMT registration API for AET enumeration callbacks Tony Luck
                   ` (10 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Tony Luck @ 2026-09-28 22:14 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) is not enumerated by CPUID its
presence/absence is discovered at file system mount time by querying the
pmt_telemetry driver. This results in two issues:

1) On a platform with no L3 monitoring features rdt_get_l3_mon_config()
   will report that the system does not support any monitoring at all.

   Handle this by optimistically assuming that AET may be supported.

2) If this optimism is unfounded, rdt_get_tree() may find that neither
   allocation, nor monitoring is supported. In this case it allows the
   mount to succeed, but does not set "resctrl_mounted".

   Move the feature test earlier and fail the mount with a diagnostic
   message to the console.

Signed-off-by: Tony Luck <tony.luck@intel.com>
---
v13:
	Add a pr_info() if no L3 features are enabled on a
	"X86_FEATURE_CQM_LLC" system.

	Add a comment for the "return true" from get_rdt_mon_resources()

	Rewrite commit message with context for the change.
---
 arch/x86/kernel/cpu/resctrl/internal.h |  2 +-
 arch/x86/kernel/cpu/resctrl/core.c     | 22 +++++++++++++---------
 arch/x86/kernel/cpu/resctrl/monitor.c  |  4 +---
 fs/resctrl/rdtgroup.c                  |  8 ++++++--
 4 files changed, 21 insertions(+), 15 deletions(-)

diff --git a/arch/x86/kernel/cpu/resctrl/internal.h b/arch/x86/kernel/cpu/resctrl/internal.h
index 086282a82fca..c038b7d80ce3 100644
--- a/arch/x86/kernel/cpu/resctrl/internal.h
+++ b/arch/x86/kernel/cpu/resctrl/internal.h
@@ -226,7 +226,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 b32fa143283e..0262174df7ad 100644
--- a/arch/x86/kernel/cpu/resctrl/core.c
+++ b/arch/x86/kernel/cpu/resctrl/core.c
@@ -991,7 +991,7 @@ static __init bool get_rdt_alloc_resources(void)
 static __init bool get_rdt_mon_resources(void)
 {
 	struct rdt_resource *r = &rdt_resources_all[RDT_RESOURCE_L3].r_resctrl;
-	bool ret = false;
+	bool l3_mon_found = false;
 
 	/* Any monitoring at all? */
 	if (!cpu_feature_enabled(X86_FEATURE_CQM))
@@ -1001,27 +1001,31 @@ static __init bool get_rdt_mon_resources(void)
 
 	/* Any of the L3 monitoring features? */
 	if (!cpu_feature_enabled(X86_FEATURE_CQM_LLC))
-		return false;
+		goto out;
 
 	if (rdt_cpu_has(X86_FEATURE_CQM_OCCUP_LLC)) {
 		resctrl_enable_mon_event(QOS_L3_OCCUP_EVENT_ID, false, 0, NULL);
-		ret = true;
+		l3_mon_found = true;
 	}
 	if (rdt_cpu_has(X86_FEATURE_CQM_MBM_TOTAL)) {
 		resctrl_enable_mon_event(QOS_L3_MBM_TOTAL_EVENT_ID, false, 0, NULL);
-		ret = true;
+		l3_mon_found = true;
 	}
 	if (rdt_cpu_has(X86_FEATURE_CQM_MBM_LOCAL)) {
 		resctrl_enable_mon_event(QOS_L3_MBM_LOCAL_EVENT_ID, false, 0, NULL);
-		ret = true;
+		l3_mon_found = true;
 	}
 	if (rdt_cpu_has(X86_FEATURE_ABMC))
-		ret = true;
+		l3_mon_found = true;
 
-	if (!ret)
-		return false;
+	if (l3_mon_found)
+		rdt_get_l3_mon_config(r);
+	else
+		pr_info("CPUID reports L3 monitoring support, but no L3 monitoring features found\n");
 
-	return !rdt_get_l3_mon_config(r);
+out:
+	/* Non-L3 features, e.g. AET, may be supported */
+	return true;
 }
 
 static __init void __check_quirks_intel(void)
diff --git a/arch/x86/kernel/cpu/resctrl/monitor.c b/arch/x86/kernel/cpu/resctrl/monitor.c
index 82a555855c1b..bd45d72d1d05 100644
--- a/arch/x86/kernel/cpu/resctrl/monitor.c
+++ b/arch/x86/kernel/cpu/resctrl/monitor.c
@@ -431,7 +431,7 @@ static void __init intel_rdt_mbm_apply_quirk(u32 num_rmid)
 	mbm_cf = mbm_cf_table[cf_index].cf;
 }
 
-int __init rdt_get_l3_mon_config(struct rdt_resource *r)
+void __init rdt_get_l3_mon_config(struct rdt_resource *r)
 {
 	struct rdt_hw_resource *hw_res = resctrl_to_arch_res(r);
 	unsigned int mbm_offset;
@@ -519,8 +519,6 @@ int __init rdt_get_l3_mon_config(struct rdt_resource *r)
 		intel_rdt_mbm_apply_quirk(num_rmid);
 
 	r->mon_capable = true;
-
-	return 0;
 }
 
 static void resctrl_abmc_set_one_amd(void *arg)
diff --git a/fs/resctrl/rdtgroup.c b/fs/resctrl/rdtgroup.c
index 79d4ddc3d64d..ecdb5da50179 100644
--- a/fs/resctrl/rdtgroup.c
+++ b/fs/resctrl/rdtgroup.c
@@ -3193,6 +3193,11 @@ static int rdt_get_tree(struct fs_context *fc)
 		goto out;
 	}
 
+	if (!resctrl_alloc_capable() && !resctrl_mon_capable()) {
+		ret = invalfc(fc, "No allocation or monitoring features are available or enabled");
+		goto out;
+	}
+
 	ret = setup_rmid_lru_list();
 	if (ret)
 		goto out;
@@ -3251,8 +3256,7 @@ static int rdt_get_tree(struct fs_context *fc)
 	if (resctrl_mon_capable())
 		resctrl_arch_enable_mon();
 
-	if (resctrl_alloc_capable() || resctrl_mon_capable())
-		resctrl_mounted = true;
+	resctrl_mounted = true;
 
 	if (resctrl_is_mbm_enabled()) {
 		r = resctrl_arch_get_resource(RDT_RESOURCE_L3);
-- 
2.55.0


^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH v13 16/25] x86/resctrl: Add PMT registration API for AET enumeration callbacks
  2026-09-28 22:14 [PATCH v13 00/25] Allow AET to use PMT as loadable module Tony Luck
                   ` (14 preceding siblings ...)
  2026-09-28 22:14 ` [PATCH v13 15/25] x86,fs/resctrl: Handle systems where AET is the only resource Tony Luck
@ 2026-09-28 22:15 ` Tony Luck
  2026-09-28 22:15 ` [PATCH v13 17/25] platform/x86/intel/pmt: Register enumeration functions with resctrl Tony Luck
                   ` (9 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Tony Luck @ 2026-09-28 22:15 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 needs to call into the pmt_telemetry
code to enumerate Application Energy Telemetry (AET) features. Requiring
CONFIG_INTEL_PMT_TELEMETRY=y allows these calls to work.

In preparation for allowing pmt_telemetry to be built as a module, add
and export register/unregister functions. pmt_telemetry can then supply
and clear the enumeration callbacks as it is loaded and unloaded.

Suggested-by: Christoph Hellwig <hch@infradead.org>
Signed-off-by: Tony Luck <tony.luck@intel.com>
---
v13:
	Rewrote commit message using correct context at this point in the series.
	Use "pmt_telemetry" throughout.
---
 include/linux/intel_vsec.h              | 12 ++++++++++++
 arch/x86/kernel/cpu/resctrl/intel_aet.c | 24 ++++++++++++++++++++++++
 2 files changed, 36 insertions(+)

diff --git a/include/linux/intel_vsec.h b/include/linux/intel_vsec.h
index 843cda8f8644..c04b1d0f3143 100644
--- a/include/linux/intel_vsec.h
+++ b/include/linux/intel_vsec.h
@@ -257,4 +257,16 @@ static inline void
 intel_pmt_put_feature_group(struct pmt_feature_group *feature_group) {}
 #endif
 
+#ifdef CONFIG_X86_CPU_RESCTRL_INTEL_AET
+void intel_aet_register_enumeration(struct module *module,
+				    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 module *module,
+						  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 */
+
 #endif
diff --git a/arch/x86/kernel/cpu/resctrl/intel_aet.c b/arch/x86/kernel/cpu/resctrl/intel_aet.c
index 4ad6ad78e93e..6c4f0bf3b876 100644
--- a/arch/x86/kernel/cpu/resctrl/intel_aet.c
+++ b/arch/x86/kernel/cpu/resctrl/intel_aet.c
@@ -17,12 +17,14 @@
 #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/module.h>
 #include <linux/printk.h>
 #include <linux/rculist.h>
 #include <linux/rcupdate.h>
@@ -291,6 +293,10 @@ static enum pmt_feature_id lookup_pfid(const char *pfname)
 	return FEATURE_INVALID;
 }
 
+static struct module *pmt_module;
+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,
@@ -325,6 +331,24 @@ bool intel_aet_get_events(void)
 	return ret;
 }
 
+void intel_aet_register_enumeration(struct module *module,
+				    struct pmt_feature_group *(*get)(enum pmt_feature_id id),
+				    void (*put)(struct pmt_feature_group *p))
+{
+	get_feature = get;
+	put_feature = put;
+	pmt_module = module;
+}
+EXPORT_SYMBOL_NS_GPL(intel_aet_register_enumeration, "INTEL_PMT");
+
+void intel_aet_unregister_enumeration(void)
+{
+	pmt_module = NULL;
+	get_feature = NULL;
+	put_feature = NULL;
+}
+EXPORT_SYMBOL_NS_GPL(intel_aet_unregister_enumeration, "INTEL_PMT");
+
 void __exit intel_aet_exit(void)
 {
 	struct event_group **peg;
-- 
2.55.0


^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH v13 17/25] platform/x86/intel/pmt: Register enumeration functions with resctrl
  2026-09-28 22:14 [PATCH v13 00/25] Allow AET to use PMT as loadable module Tony Luck
                   ` (15 preceding siblings ...)
  2026-09-28 22:15 ` [PATCH v13 16/25] x86/resctrl: Add PMT registration API for AET enumeration callbacks Tony Luck
@ 2026-09-28 22:15 ` Tony Luck
  2026-09-28 22:15 ` [PATCH v13 18/25] x86/resctrl: Use registered function pointers for AET enumeration Tony Luck
                   ` (8 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Tony Luck @ 2026-09-28 22:15 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 exports register/unregister functions that the pmt_telemetry
driver should use to allow resctrl to call the Application Energy
Telemetry (AET) enumeration functions when this driver is configured
as a module.

By default module probe functions are called asynchronously. Change the
probe type to request synchronous execution to ensure that all probes
are complete before supplying the enumeration function to resctrl.

Unregister enumeration before beginning tear down of auxiliary devices
so that resctrl cannot attempt enumeration in parallel with unload of
the pmt_telemetry module.

Suggested-by: Christoph Hellwig <hch@infradead.org>
Signed-off-by: Tony Luck <tony.luck@intel.com>
---
v13:
	Dropped empty line in pmt_telem_init()
	Rewrote commit message with accurate context.
---
 drivers/platform/x86/intel/pmt/telemetry.c | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/drivers/platform/x86/intel/pmt/telemetry.c b/drivers/platform/x86/intel/pmt/telemetry.c
index 953f35b6daec..57eb2967a4d0 100644
--- a/drivers/platform/x86/intel/pmt/telemetry.c
+++ b/drivers/platform/x86/intel/pmt/telemetry.c
@@ -427,16 +427,29 @@ static struct auxiliary_driver pmt_telem_aux_driver = {
 	.id_table	= pmt_telem_id_table,
 	.remove		= pmt_telem_remove,
 	.probe		= pmt_telem_probe,
+	.driver		= {
+		.probe_type = PROBE_FORCE_SYNCHRONOUS,
+	},
 };
 
 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(THIS_MODULE, intel_pmt_get_regions_by_feature,
+				       intel_pmt_put_feature_group);
+
+	return 0;
 }
 module_init(pmt_telem_init);
 
 static void __exit pmt_telem_exit(void)
 {
+	intel_aet_unregister_enumeration();
 	auxiliary_driver_unregister(&pmt_telem_aux_driver);
 	xa_destroy(&telem_array);
 }
-- 
2.55.0


^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH v13 18/25] x86/resctrl: Use registered function pointers for AET enumeration
  2026-09-28 22:14 [PATCH v13 00/25] Allow AET to use PMT as loadable module Tony Luck
                   ` (16 preceding siblings ...)
  2026-09-28 22:15 ` [PATCH v13 17/25] platform/x86/intel/pmt: Register enumeration functions with resctrl Tony Luck
@ 2026-09-28 22:15 ` Tony Luck
  2026-09-28 22:15 ` [PATCH v13 19/25] arm,x86,fs/resctrl: Enumerate AET on every resctrl mount Tony Luck
                   ` (7 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Tony Luck @ 2026-09-28 22:15 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

The pmt_telemetry driver registers enumeration functions with resctrl
Application Energy Telemetry (AET) code.

Use the function pointers instead of direct function calls in preparation
for the telemetry driver to be a loadable module.

The pmt_telemetry is forced to be built-in to the kernel, so it does not matter
at this point that there is no matching module_put() for the try_module_get()
in intel_aet_pre_mount(). This must be resolved with additions in the file
system unmount path before pmt_telemetry can be configured as a module.

Signed-off-by: Tony Luck <tony.luck@intel.com>
---
v13:
	Replace intel_pmt_put_feature_group() call in intel_aet_exit()
	with call via registered function pointer.

	Explain in commit comment that pmt_telemetry is built-in so the
	try_module_get() is a no-op.
---
 arch/x86/kernel/cpu/resctrl/internal.h  |  4 +--
 arch/x86/kernel/cpu/resctrl/core.c      |  2 +-
 arch/x86/kernel/cpu/resctrl/intel_aet.c | 37 ++++++++++++++++++++++---
 3 files changed, 36 insertions(+), 7 deletions(-)

diff --git a/arch/x86/kernel/cpu/resctrl/internal.h b/arch/x86/kernel/cpu/resctrl/internal.h
index c038b7d80ce3..8406addc05f5 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);
 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 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 0262174df7ad..ac67b4523b2d 100644
--- a/arch/x86/kernel/cpu/resctrl/core.c
+++ b/arch/x86/kernel/cpu/resctrl/core.c
@@ -795,7 +795,7 @@ 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())
+	if (!intel_aet_pre_mount())
 		return;
 
 	/*
diff --git a/arch/x86/kernel/cpu/resctrl/intel_aet.c b/arch/x86/kernel/cpu/resctrl/intel_aet.c
index 6c4f0bf3b876..fbe0a8761bb9 100644
--- a/arch/x86/kernel/cpu/resctrl/intel_aet.c
+++ b/arch/x86/kernel/cpu/resctrl/intel_aet.c
@@ -12,6 +12,7 @@
 #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>
@@ -25,6 +26,7 @@
 #include <linux/io.h>
 #include <linux/minmax.h>
 #include <linux/module.h>
+#include <linux/mutex.h>
 #include <linux/printk.h>
 #include <linux/rculist.h>
 #include <linux/rcupdate.h>
@@ -293,6 +295,13 @@ static enum pmt_feature_id lookup_pfid(const char *pfname)
 	return FEATURE_INVALID;
 }
 
+/*
+ * Protects pmt_module, get_feature, put_feature against races between module
+ * load/unload of the pmt_telemetry module and mount/unmount of the resctrl
+ * file system.
+ */
+static DEFINE_MUTEX(aet_register_lock);
+
 static struct module *pmt_module;
 static struct pmt_feature_group *(*get_feature)(enum pmt_feature_id id);
 static void (*put_feature)(struct pmt_feature_group *p);
@@ -308,7 +317,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;
@@ -317,14 +326,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);
 		}
 	}
 
@@ -335,6 +344,7 @@ void intel_aet_register_enumeration(struct module *module,
 				    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;
 	pmt_module = module;
@@ -343,19 +353,38 @@ EXPORT_SYMBOL_NS_GPL(intel_aet_register_enumeration, "INTEL_PMT");
 
 void intel_aet_unregister_enumeration(void)
 {
+	guard(mutex)(&aet_register_lock);
 	pmt_module = NULL;
 	get_feature = NULL;
 	put_feature = NULL;
 }
 EXPORT_SYMBOL_NS_GPL(intel_aet_unregister_enumeration, "INTEL_PMT");
 
+bool intel_aet_pre_mount(void)
+{
+	guard(mutex)(&aet_register_lock);
+
+	if (!get_feature || !put_feature)
+		return false;
+
+	if (!try_module_get(pmt_module))
+		return false;
+
+	if (!aet_get_events()) {
+		module_put(pmt_module);
+		return false;
+	}
+
+	return true;
+}
+
 void __exit intel_aet_exit(void)
 {
 	struct event_group **peg;
 
 	for_each_event_group(peg) {
 		if ((*peg)->pfg) {
-			intel_pmt_put_feature_group((*peg)->pfg);
+			put_feature((*peg)->pfg);
 			(*peg)->pfg = NULL;
 		}
 	}
-- 
2.55.0


^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH v13 19/25] arm,x86,fs/resctrl: Enumerate AET on every resctrl mount
  2026-09-28 22:14 [PATCH v13 00/25] Allow AET to use PMT as loadable module Tony Luck
                   ` (17 preceding siblings ...)
  2026-09-28 22:15 ` [PATCH v13 18/25] x86/resctrl: Use registered function pointers for AET enumeration Tony Luck
@ 2026-09-28 22:15 ` Tony Luck
  2026-09-28 22:15 ` [PATCH v13 20/25] x86/resctrl: Enforce system RMID limit on AET Tony Luck
                   ` (6 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Tony Luck @ 2026-09-28 22:15 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

The pmt_telemetry driver is built-in, and Application Energy Telemetry (AET)
is only enumerated on the first mount of the resctrl file system.

In order to allow the pmt_telemetry driver to be a module, changes are
needed to place a hold on the driver only while the resctrl file system
is mounted. This means that resctrl must enumerate AET features on every
mount, and clean up on every unmount.

There are changes to three software layers:

1) resctrl file system
   Call architecture code for every mount and unmount. Locking is needed
   here so that architecture code can be sure that every call to
   resctrl_arch_pre_mount() occurs while the file system is not mounted,
   and resctrl_arch_unmount() occurs only to clean up a failed mount or
   to unmount the file system.

2) Architecture code
   New function resctrl_arch_unmount(). On x86 this calls the AET code
   if RDT_RESOURCE_PERF_PKG was marked as supporting monitoring by an
   earlier mount attempt. It completes cleanup by removing all domains
   used by AET.

3) AET code
   Disables all AET events and informs pmt_telemetry driver that it is no
   longer using the pmt_feature_group structures it received during mount.
   Releases the hold on the pmt_telemetry driver allowing it to be unloaded.
   All cleanup is handled by intel_aet_unmount() and intel_aet_exit() is
   no longer needed.

Signed-off-by: Tony Luck <tony.luck@intel.com>
---
v13:
	Replace comment about holding resctrl_mount_lock for
	resctrl_arch_pre_mount() and resctrl_arch_unmount()
	with "Serialized against other mount and unmount attempts."

	Dropped stray blank line addition to rdt_get_tree()

	Rewrote commit message. Note that previous iterations of this
	patch series attempted to split into separate parts. But these
	were hard to explain separately.
---
 include/linux/resctrl.h                 | 10 +++++++--
 arch/x86/kernel/cpu/resctrl/internal.h  |  4 ++--
 arch/x86/kernel/cpu/resctrl/core.c      | 21 +++++++++++++++--
 arch/x86/kernel/cpu/resctrl/intel_aet.c | 29 +++++++++++++++++++-----
 drivers/resctrl/mpam_resctrl.c          |  4 ++++
 fs/resctrl/rdtgroup.c                   | 30 ++++++++++++++++++++-----
 6 files changed, 81 insertions(+), 17 deletions(-)

diff --git a/include/linux/resctrl.h b/include/linux/resctrl.h
index c77e24c0d8b6..c40d72e4a957 100644
--- a/include/linux/resctrl.h
+++ b/include/linux/resctrl.h
@@ -611,11 +611,17 @@ 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.
- * No locks are held.
+ * Architecture hook called at beginning of each file system mount attempt.
+ * Serialized against other mount and unmount attempts.
  */
 void resctrl_arch_pre_mount(void);
 
+/*
+ * Architecture hook called when mount fails, or on unmount.
+ * Serialized against other mount and unmount attempts.
+ */
+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 8406addc05f5..c66954bc01e7 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
-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 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 ac67b4523b2d..40466f29e48e 100644
--- a/arch/x86/kernel/cpu/resctrl/core.c
+++ b/arch/x86/kernel/cpu/resctrl/core.c
@@ -811,6 +811,25 @@ 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;
+
+	if (!r->mon_capable)
+		return;
+
+	intel_aet_unmount();
+
+	cpus_read_lock();
+	mutex_lock(&domain_list_lock);
+	for_each_online_cpu(cpu)
+		domain_remove_cpu_mon(cpu, r);
+	r->mon_capable = false;
+	mutex_unlock(&domain_list_lock);
+	cpus_read_unlock();
+}
+
 enum {
 	RDT_FLAG_CMT,
 	RDT_FLAG_MBM_TOTAL,
@@ -1161,8 +1180,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 fbe0a8761bb9..8aa2e18a6bbb 100644
--- a/arch/x86/kernel/cpu/resctrl/intel_aet.c
+++ b/arch/x86/kernel/cpu/resctrl/intel_aet.c
@@ -298,7 +298,7 @@ static enum pmt_feature_id lookup_pfid(const char *pfname)
 /*
  * Protects pmt_module, get_feature, put_feature against races between module
  * load/unload of the pmt_telemetry module and mount/unmount of the resctrl
- * file system.
+ * file system. Also protects pmt_in_use.
  */
 static DEFINE_MUTEX(aet_register_lock);
 
@@ -306,6 +306,11 @@ static struct module *pmt_module;
 static struct pmt_feature_group *(*get_feature)(enum pmt_feature_id id);
 static void (*put_feature)(struct pmt_feature_group *p);
 
+/*
+ * Track whether pmt_telemetry enumeration succeeded during mount for use during unmount.
+ */
+static bool pmt_in_use;
+
 /*
  * 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,
@@ -375,19 +380,33 @@ bool intel_aet_pre_mount(void)
 		return false;
 	}
 
+	pmt_in_use = true;
+
 	return true;
 }
 
-void __exit intel_aet_exit(void)
+void intel_aet_unmount(void)
 {
+	struct rdt_resource *r = &rdt_resources_all[RDT_RESOURCE_PERF_PKG].r_resctrl;
 	struct event_group **peg;
 
+	guard(mutex)(&aet_register_lock);
+	if (!pmt_in_use)
+		return;
+
 	for_each_event_group(peg) {
-		if ((*peg)->pfg) {
-			put_feature((*peg)->pfg);
-			(*peg)->pfg = NULL;
+		struct event_group *e = *peg;
+
+		if (e->pfg) {
+			for (int i = 0; i < e->num_events; i++)
+				resctrl_disable_mon_event(e->evts[i].id);
+			put_feature(e->pfg);
+			e->pfg = NULL;
 		}
 	}
+	module_put(pmt_module);
+	pmt_in_use = false;
+	r->mon.num_rmid = 0;
 }
 
 #define DATA_VALID	BIT_ULL(63)
diff --git a/drivers/resctrl/mpam_resctrl.c b/drivers/resctrl/mpam_resctrl.c
index 360a50eb0cd3..ecea2239afa4 100644
--- a/drivers/resctrl/mpam_resctrl.c
+++ b/drivers/resctrl/mpam_resctrl.c
@@ -121,6 +121,10 @@ void resctrl_arch_pre_mount(void)
 {
 }
 
+void resctrl_arch_unmount(void)
+{
+}
+
 bool resctrl_arch_get_cdp_enabled(enum resctrl_res_level rid)
 {
 	return mpam_resctrl_controls[rid].cdp_enabled;
diff --git a/fs/resctrl/rdtgroup.c b/fs/resctrl/rdtgroup.c
index ecdb5da50179..20e579067570 100644
--- a/fs/resctrl/rdtgroup.c
+++ b/fs/resctrl/rdtgroup.c
@@ -30,6 +30,9 @@
 
 #include "internal.h"
 
+/* Mutex protecting resctrl_mounted and mount/unmount operations */
+static DEFINE_MUTEX(resctrl_mount_lock);
+
 /* Mutex to protect rdtgroup access. */
 DEFINE_MUTEX(rdtgroup_mutex);
 
@@ -48,7 +51,10 @@ LIST_HEAD(resctrl_schema_all);
  */
 static LIST_HEAD(mon_data_kn_priv_list);
 
-/* The filesystem can only be mounted once. */
+/*
+ * The filesystem can only be mounted once. Can only be updated
+ * while holding both resctrl_mount_lock and rdtgroup_mutex.
+ */
 bool resctrl_mounted;
 
 /* Kernel fs node for "info" directory under root */
@@ -3147,6 +3153,7 @@ static void resctrl_unmount(void)
 {
 	struct rdt_resource *r;
 
+	mutex_lock(&resctrl_mount_lock);
 	cpus_read_lock();
 	mutex_lock(&rdtgroup_mutex);
 
@@ -3164,6 +3171,8 @@ static void resctrl_unmount(void)
 	resctrl_mounted = false;
 	mutex_unlock(&rdtgroup_mutex);
 	cpus_read_unlock();
+	resctrl_arch_unmount();
+	mutex_unlock(&resctrl_mount_lock);
 }
 
 static int rdt_get_tree(struct fs_context *fc)
@@ -3175,24 +3184,27 @@ static int rdt_get_tree(struct fs_context *fc)
 	struct rdt_resource *r;
 	int ret;
 
-	DO_ONCE_SLEEPABLE(resctrl_arch_pre_mount);
+	mutex_lock(&resctrl_mount_lock);
 
-	cpus_read_lock();
-	mutex_lock(&rdtgroup_mutex);
 	/*
 	 * resctrl file system can only be mounted once.
 	 */
 	if (resctrl_mounted) {
 		ret = -EBUSY;
-		goto out;
+		goto out_mount_unlock;
 	}
 
 	/* Avoid races from pending operations from a previous mount */
 	if (atomic_read(&rdtgroup_default.waitcount) != 0) {
 		ret = -EBUSY;
-		goto out;
+		goto out_mount_unlock;
 	}
 
+	resctrl_arch_pre_mount();
+
+	cpus_read_lock();
+	mutex_lock(&rdtgroup_mutex);
+
 	if (!resctrl_alloc_capable() && !resctrl_mon_capable()) {
 		ret = invalfc(fc, "No allocation or monitoring features are available or enabled");
 		goto out;
@@ -3287,6 +3299,8 @@ static int rdt_get_tree(struct fs_context *fc)
 	mutex_unlock(&rdtgroup_mutex);
 	cpus_read_unlock();
 
+	mutex_unlock(&resctrl_mount_lock);
+
 	ret = kernfs_get_tree(fc);
 	/*
 	 * resctrl can only be mounted once, new superblock only expected
@@ -3318,6 +3332,10 @@ static int rdt_get_tree(struct fs_context *fc)
 out:
 	mutex_unlock(&rdtgroup_mutex);
 	cpus_read_unlock();
+	resctrl_arch_unmount();
+out_mount_unlock:
+	mutex_unlock(&resctrl_mount_lock);
+
 	return ret;
 }
 
-- 
2.55.0


^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH v13 20/25] x86/resctrl: Enforce system RMID limit on AET
  2026-09-28 22:14 [PATCH v13 00/25] Allow AET to use PMT as loadable module Tony Luck
                   ` (18 preceding siblings ...)
  2026-09-28 22:15 ` [PATCH v13 19/25] arm,x86,fs/resctrl: Enumerate AET on every resctrl mount Tony Luck
@ 2026-09-28 22:15 ` Tony Luck
  2026-09-28 22:15 ` [PATCH v13 21/25] x86/resctrl: Export interface to report telemetry unbind/remove Tony Luck
                   ` (5 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Tony Luck @ 2026-09-28 22:15 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) event groups each support a specific
number of RMIDs. But that number may be higher than the number supported
by the system.

Ensure that info/PERF_PKG_MON/num_rmids does not display an unachievable
value to users by capping the maximum supported RMIDs in the resource to
the system maximum.

Signed-off-by: Tony Luck <tony.luck@intel.com>
---
v13:
	Drop sentence about SNC reducing number of RMIDs as it isn't
	relevant.

	s/lower/higher/ in commit message.

	s/IA32_PQR_ASSOC.RMID/MSR_IA32_PQR_ASSOC.RMID/

	Changed pqr_assoc_num_rmid from static to global.

	Move clamp from arch/x86/kernel/cpu/resctrl/core.c to
	arch/x86/kernel/cpu/resctrl/intel_aet.c
---
 arch/x86/kernel/cpu/resctrl/internal.h  | 2 ++
 arch/x86/kernel/cpu/resctrl/core.c      | 2 +-
 arch/x86/kernel/cpu/resctrl/intel_aet.c | 7 +++++++
 3 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/arch/x86/kernel/cpu/resctrl/internal.h b/arch/x86/kernel/cpu/resctrl/internal.h
index c66954bc01e7..1f080aad1b67 100644
--- a/arch/x86/kernel/cpu/resctrl/internal.h
+++ b/arch/x86/kernel/cpu/resctrl/internal.h
@@ -153,6 +153,8 @@ extern struct rdt_hw_resource rdt_resources_all[];
 
 extern bool intel_rdt_mbm_need_quirk;
 
+extern u32 pqr_assoc_num_rmid;
+
 void arch_mon_domain_online(struct rdt_resource *r, struct rdt_l3_mon_domain *d);
 
 /* CPUID.(EAX=10H, ECX=ResID=1).EAX */
diff --git a/arch/x86/kernel/cpu/resctrl/core.c b/arch/x86/kernel/cpu/resctrl/core.c
index 40466f29e48e..689b9e31fe7a 100644
--- a/arch/x86/kernel/cpu/resctrl/core.c
+++ b/arch/x86/kernel/cpu/resctrl/core.c
@@ -46,7 +46,7 @@ static DEFINE_MUTEX(domain_list_lock);
 DEFINE_PER_CPU(struct resctrl_pqr_state, pqr_state);
 
 /* Number of unique RMID values that can be written to MSR_IA32_PQR_ASSOC.RMID */
-static u32 pqr_assoc_num_rmid;
+u32 pqr_assoc_num_rmid;
 
 static void mba_wrmsr_intel(struct msr_param *m);
 static void cat_wrmsr(struct msr_param *m);
diff --git a/arch/x86/kernel/cpu/resctrl/intel_aet.c b/arch/x86/kernel/cpu/resctrl/intel_aet.c
index 8aa2e18a6bbb..e64e5a44511f 100644
--- a/arch/x86/kernel/cpu/resctrl/intel_aet.c
+++ b/arch/x86/kernel/cpu/resctrl/intel_aet.c
@@ -274,6 +274,12 @@ static bool enable_events(struct event_group *e, struct pmt_feature_group *p)
 	else
 		r->mon.num_rmid = e->num_rmid;
 
+	/*
+	 * AET may claim to support more RMIDs than are permitted to be
+	 * assigned to MSR_IA32_PQR_ASSOC.RMID. Enforce this limit.
+	 */
+	r->mon.num_rmid = min(r->mon.num_rmid, pqr_assoc_num_rmid);
+
 	if (skipped_events)
 		pr_info("%s %s:0x%x monitoring detected (skipped %d events)\n", r->name,
 			e->pfname, e->guid, skipped_events);
@@ -391,6 +397,7 @@ void intel_aet_unmount(void)
 	struct event_group **peg;
 
 	guard(mutex)(&aet_register_lock);
+
 	if (!pmt_in_use)
 		return;
 
-- 
2.55.0


^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH v13 21/25] x86/resctrl: Export interface to report telemetry unbind/remove
  2026-09-28 22:14 [PATCH v13 00/25] Allow AET to use PMT as loadable module Tony Luck
                   ` (19 preceding siblings ...)
  2026-09-28 22:15 ` [PATCH v13 20/25] x86/resctrl: Enforce system RMID limit on AET Tony Luck
@ 2026-09-28 22:15 ` Tony Luck
  2026-09-28 22:15 ` [PATCH v13 22/25] platform/x86/intel/pmt: Inform resctrl when MMIO maps are being removed Tony Luck
                   ` (4 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Tony Luck @ 2026-09-28 22:15 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

Linux allows devices to be unbound from drivers, even if the modules
cannot be unloaded because of reference counts.

For telemetry this results in teardown of the virtual address mappings
of the MMIO regions which hold the event counters. Subsequent access
to these counters will page fault.

Export intel_aet_invalidate() for the pmt_telemetry module to inform
resctrl when invalidation is about to happen.

The mount time call from aet_get_events() to the pmt_telemetry module holds
the existing aet_register_lock and then acquires ep_lock establishing
the lock hierarchy.

The pmt_telemetry module will need to call intel_aet_invalidate() while
holding the ep_lock. If intel_aet_invalidate() tried to use aet_register_lock
for locking it would create an A-B B-A deadlock.

Add a new mutex to protect telemetry_region::addr from simultaneous
invalidation and use by intel_aet_read_event().

Signed-off-by: Tony Luck <tony.luck@intel.com>
---
v13:
	Dropped telemetry_region::addr from list of things protected
	by aet_register_lock.

	Declare and use aet_mmio_lock in this patch instead of next one.

	Explain the reason for the new lock.
---
 include/linux/intel_vsec.h              |  2 ++
 arch/x86/kernel/cpu/resctrl/intel_aet.c | 29 +++++++++++++++++++++++++
 2 files changed, 31 insertions(+)

diff --git a/include/linux/intel_vsec.h b/include/linux/intel_vsec.h
index c04b1d0f3143..bcbf4937c71c 100644
--- a/include/linux/intel_vsec.h
+++ b/include/linux/intel_vsec.h
@@ -262,11 +262,13 @@ void intel_aet_register_enumeration(struct module *module,
 				    struct pmt_feature_group *(*get)(enum pmt_feature_id id),
 				    void (*put)(struct pmt_feature_group *p));
 void intel_aet_unregister_enumeration(void);
+void intel_aet_invalidate(u8 package_id);
 #else
 static inline void intel_aet_register_enumeration(struct module *module,
 						  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) { }
+static inline void intel_aet_invalidate(u8 package_id) { }
 #endif /* CONFIG_X86_CPU_RESCTRL_INTEL_AET */
 
 #endif
diff --git a/arch/x86/kernel/cpu/resctrl/intel_aet.c b/arch/x86/kernel/cpu/resctrl/intel_aet.c
index e64e5a44511f..59066e1c6333 100644
--- a/arch/x86/kernel/cpu/resctrl/intel_aet.c
+++ b/arch/x86/kernel/cpu/resctrl/intel_aet.c
@@ -308,6 +308,9 @@ static enum pmt_feature_id lookup_pfid(const char *pfname)
  */
 static DEFINE_MUTEX(aet_register_lock);
 
+/* Protects telemetry_region::addr. */
+static DEFINE_MUTEX(aet_mmio_lock);
+
 static struct module *pmt_module;
 static struct pmt_feature_group *(*get_feature)(enum pmt_feature_id id);
 static void (*put_feature)(struct pmt_feature_group *p);
@@ -371,6 +374,30 @@ void intel_aet_unregister_enumeration(void)
 }
 EXPORT_SYMBOL_NS_GPL(intel_aet_unregister_enumeration, "INTEL_PMT");
 
+/*
+ * pmt_telemetry driver calls this for unbind/remove operations that
+ * will invalidate the virtual addresses of MMIO registers provided
+ * by intel_pmt_get_regions_by_feature().
+ */
+void intel_aet_invalidate(u8 package_id)
+{
+	struct event_group **peg;
+
+	guard(mutex)(&aet_mmio_lock);
+
+	for_each_event_group(peg) {
+		struct event_group *e = *peg;
+
+		if (!e->pfg)
+			continue;
+		for (int i = 0; i < e->pfg->count; i++) {
+			if (e->pfg->regions[i].plat_info.package_id == package_id)
+				e->pfg->regions[i].addr = NULL;
+		}
+	}
+}
+EXPORT_SYMBOL_NS_GPL(intel_aet_invalidate, "INTEL_PMT");
+
 bool intel_aet_pre_mount(void)
 {
 	guard(mutex)(&aet_register_lock);
@@ -435,6 +462,8 @@ int intel_aet_read_event(int domid, u32 rmid, void *arch_priv, u64 *val)
 	void *pevt0;
 	u32 idx;
 
+	guard(mutex)(&aet_mmio_lock);
+
 	pevt0 = pevt - pevt->idx;
 	e = container_of(pevt0, struct event_group, evts);
 	idx = rmid * e->num_events;
-- 
2.55.0


^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH v13 22/25] platform/x86/intel/pmt: Inform resctrl when MMIO maps are being removed
  2026-09-28 22:14 [PATCH v13 00/25] Allow AET to use PMT as loadable module Tony Luck
                   ` (20 preceding siblings ...)
  2026-09-28 22:15 ` [PATCH v13 21/25] x86/resctrl: Export interface to report telemetry unbind/remove Tony Luck
@ 2026-09-28 22:15 ` Tony Luck
  2026-09-28 22:15 ` [PATCH v13 23/25] x86/resctrl: Require 64-bit x86 for resctrl support Tony Luck
                   ` (3 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Tony Luck @ 2026-09-28 22:15 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

When a telemetry device is unbound from its driver or deleted the
pmt_telemetry driver invalidates all the MMIO mappings for that
device. When resctrl reads a telemetry event it faults on the access
to the event counter.

Before destroying devices, tell resctrl that the virtual addresses
supplied by an earlier call to intel_pmt_get_regions_by_feature()
are about to be invalidated and should not be used again.

Signed-off-by: Tony Luck <tony.luck@intel.com>
---
v13:
	Context paragraph added describing the problem.

	New aet_mmio_lock moved to previous patch to avoid
	churn here changing lines that were just changed there.

	Add a comment in code that all entries for a removed device
	are on the same package.
---
 drivers/platform/x86/intel/pmt/telemetry.c | 30 ++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/drivers/platform/x86/intel/pmt/telemetry.c b/drivers/platform/x86/intel/pmt/telemetry.c
index 57eb2967a4d0..bd63653802d9 100644
--- a/drivers/platform/x86/intel/pmt/telemetry.c
+++ b/drivers/platform/x86/intel/pmt/telemetry.c
@@ -366,12 +366,42 @@ pmt_telem_find_and_register_endpoint(struct device *dev, u32 guid, u16 pos)
 }
 EXPORT_SYMBOL_NS_GPL(pmt_telem_find_and_register_endpoint, "INTEL_PMT_TELEMETRY");
 
+static int pmt_telem_get_package_id(struct pmt_telem_priv *priv)
+{
+	int i;
+
+	for (i = 0; i < priv->num_entries; i++) {
+		struct intel_pmt_entry *entry = &priv->entry[i];
+		struct pci_dev *pdev = to_pci_dev(entry->ep->dev);
+		struct oobmsm_plat_info *plat_info;
+
+		plat_info = intel_vsec_get_mapping(pdev);
+		if (!IS_ERR(plat_info)) {
+			/* All entries for a device have the same package ID */
+			return plat_info->package_id;
+		}
+	}
+
+	return -ENODEV;
+}
+
 static void pmt_telem_remove(struct auxiliary_device *auxdev)
 {
 	struct pmt_telem_priv *priv = auxiliary_get_drvdata(auxdev);
+	int package_id;
 	int i;
 
 	mutex_lock(&ep_lock);
+	package_id = pmt_telem_get_package_id(priv);
+	/*
+	 * Tell resctrl/AET that virtual mappings for MMIO space in a CPU
+	 * package are about to be torn down.
+	 */
+	if (package_id < 0)
+		dev_dbg(&auxdev->dev, "Unable to determine package ID for removed device\n");
+	else
+		intel_aet_invalidate(package_id);
+
 	for (i = 0; i < priv->num_entries; i++) {
 		struct intel_pmt_entry *entry = &priv->entry[i];
 
-- 
2.55.0


^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH v13 23/25] x86/resctrl: Require 64-bit x86 for resctrl support
  2026-09-28 22:14 [PATCH v13 00/25] Allow AET to use PMT as loadable module Tony Luck
                   ` (21 preceding siblings ...)
  2026-09-28 22:15 ` [PATCH v13 22/25] platform/x86/intel/pmt: Inform resctrl when MMIO maps are being removed Tony Luck
@ 2026-09-28 22:15 ` Tony Luck
  2026-09-28 22:15 ` [PATCH v13 24/25] x86/resctrl: Simplify Kconfig options for resctrl Tony Luck
                   ` (2 subsequent siblings)
  25 siblings, 0 replies; 27+ messages in thread
From: Tony Luck @ 2026-09-28 22:15 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 Application Energy Telemetry (AET) provides event counts in 64-bit
registers in MMIO space. For accurate results these should be read with a
single 64-bit load operation from the CPU.

In preparation for the removal of the separate CONFIG_X86_CPU_RESCTRL_INTEL_AET
configuration option, move the X86_64 dependency to X86_CPU_RESCTRL.

This is in line with Dave Hansen's proposal[1] for an addition to Linux
documentation that details reduced 32-bit x86 support.

Signed-off-by: Tony Luck <tony.luck@intel.com>
Link: https://lore.kernel.org/all/c6ab0c24-8931-4f0d-9be6-23498ab4c38b@intel.com/ # [1]
---
v13:
	Re-order tags
	s/This in line/This is in line/
	s/the state of/reduced/
---
 arch/x86/Kconfig | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 15fd9ec5ecac..06b5d0c4633e 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -518,7 +518,7 @@ 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
 	select ARCH_HAS_CPU_RESCTRL
 	select RESCTRL_FS
@@ -541,7 +541,7 @@ config X86_CPU_RESCTRL
 
 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
+	depends on X86_CPU_RESCTRL && CPU_SUP_INTEL && INTEL_PMT_TELEMETRY=y && INTEL_TPMI=y
 	help
 	  Enable per-RMID telemetry events in resctrl.
 
-- 
2.55.0


^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH v13 24/25] x86/resctrl: Simplify Kconfig options for resctrl
  2026-09-28 22:14 [PATCH v13 00/25] Allow AET to use PMT as loadable module Tony Luck
                   ` (22 preceding siblings ...)
  2026-09-28 22:15 ` [PATCH v13 23/25] x86/resctrl: Require 64-bit x86 for resctrl support Tony Luck
@ 2026-09-28 22:15 ` Tony Luck
  2026-09-28 22:15 ` [PATCH v13 25/25] x86,fs/resctrl: Document telemetry mount timing caveat Tony Luck
  2026-09-29  0:29 ` [PATCH v13 00/25] Allow AET to use PMT as loadable module Luck, Tony
  25 siblings, 0 replies; 27+ messages in thread
From: Tony Luck @ 2026-09-28 22:15 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 required other config options to be set to "built-in".  There is
no longer a requirement that INTEL_PMT_TELEMETRY or INTEL_TPMI be built-in.

Drop CONFIG_X86_CPU_RESCTRL_INTEL_AET and unconditionally include
AET (Application Energy Telemetry) as part of X86_CPU_RESCTRL.

Now that AET is unconditionally part of x86 resctrl the "intel_"
prefix on these function names is no longer appropriate. Switch
to "rdt_" to match other names in "internal.h":

intel_aet_pre_mount()		-> rdt_aet_pre_mount()
intel_aet_unmount()		-> rdt_aet_unmount()
intel_aet_read_event()		-> rdt_aet_read_event()
intel_aet_mon_domain_setup()	-> rdt_aet_mon_domain_setup()
intel_handle_aet_option()	-> rdt_handle_aet_option()

Signed-off-by: Tony Luck <tony.luck@intel.com>
Link: https://lore.kernel.org/all/CAHk-=whigg3hvOy7c1j1MXFy6o6CHp0g4Tc3Y-MAk+XDssHU0A@mail.gmail.com # [1]
---
v13:
	Re-order tags.
	Swap "intel_" prefix to "rdt_".
---
 include/linux/intel_vsec.h              |  4 ++--
 arch/x86/kernel/cpu/resctrl/internal.h  | 23 +++++------------------
 arch/x86/kernel/cpu/resctrl/core.c      |  8 ++++----
 arch/x86/kernel/cpu/resctrl/intel_aet.c | 12 ++++++------
 arch/x86/kernel/cpu/resctrl/monitor.c   |  2 +-
 arch/x86/Kconfig                        | 13 -------------
 arch/x86/kernel/cpu/resctrl/Makefile    |  3 +--
 7 files changed, 19 insertions(+), 46 deletions(-)

diff --git a/include/linux/intel_vsec.h b/include/linux/intel_vsec.h
index bcbf4937c71c..885f8e3ab057 100644
--- a/include/linux/intel_vsec.h
+++ b/include/linux/intel_vsec.h
@@ -257,7 +257,7 @@ static inline void
 intel_pmt_put_feature_group(struct pmt_feature_group *feature_group) {}
 #endif
 
-#ifdef CONFIG_X86_CPU_RESCTRL_INTEL_AET
+#ifdef CONFIG_X86_CPU_RESCTRL
 void intel_aet_register_enumeration(struct module *module,
 				    struct pmt_feature_group *(*get)(enum pmt_feature_id id),
 				    void (*put)(struct pmt_feature_group *p));
@@ -269,6 +269,6 @@ static inline void intel_aet_register_enumeration(struct module *module,
 						  void (*put)(struct pmt_feature_group *p)) { }
 static inline void intel_aet_unregister_enumeration(void) { }
 static inline void intel_aet_invalidate(u8 package_id) { }
-#endif /* CONFIG_X86_CPU_RESCTRL_INTEL_AET */
+#endif /* CONFIG_X86_CPU_RESCTRL */
 
 #endif
diff --git a/arch/x86/kernel/cpu/resctrl/internal.h b/arch/x86/kernel/cpu/resctrl/internal.h
index 1f080aad1b67..2a987cfc4b1b 100644
--- a/arch/x86/kernel/cpu/resctrl/internal.h
+++ b/arch/x86/kernel/cpu/resctrl/internal.h
@@ -235,24 +235,11 @@ bool rdt_cpu_has(int flag);
 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,
+bool rdt_aet_pre_mount(void);
+void rdt_aet_unmount(void);
+int rdt_aet_read_event(int domid, u32 rmid, void *arch_priv, u64 *val);
+void rdt_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
+bool rdt_handle_aet_option(bool force_off, char *tok);
 
 #endif /* _ASM_X86_RESCTRL_INTERNAL_H */
diff --git a/arch/x86/kernel/cpu/resctrl/core.c b/arch/x86/kernel/cpu/resctrl/core.c
index 689b9e31fe7a..78cb1e8cd747 100644
--- a/arch/x86/kernel/cpu/resctrl/core.c
+++ b/arch/x86/kernel/cpu/resctrl/core.c
@@ -616,7 +616,7 @@ static void domain_add_cpu_mon(int cpu, struct rdt_resource *r)
 		break;
 	case RDT_RESOURCE_PERF_PKG:
 		if (!hdr)
-			intel_aet_mon_domain_setup(cpu, id, r, add_pos);
+			rdt_aet_mon_domain_setup(cpu, id, r, add_pos);
 		break;
 	default:
 		pr_warn_once("Unknown resource rid=%d\n", r->rid);
@@ -795,7 +795,7 @@ void resctrl_arch_pre_mount(void)
 	struct rdt_resource *r = &rdt_resources_all[RDT_RESOURCE_PERF_PKG].r_resctrl;
 	int cpu;
 
-	if (!intel_aet_pre_mount())
+	if (!rdt_aet_pre_mount())
 		return;
 
 	/*
@@ -819,7 +819,7 @@ void resctrl_arch_unmount(void)
 	if (!r->mon_capable)
 		return;
 
-	intel_aet_unmount();
+	rdt_aet_unmount();
 
 	cpus_read_lock();
 	mutex_lock(&domain_list_lock);
@@ -885,7 +885,7 @@ static int __init set_rdt_options(char *str)
 		force_off = *tok == '!';
 		if (force_off)
 			tok++;
-		if (intel_handle_aet_option(force_off, tok))
+		if (rdt_handle_aet_option(force_off, tok))
 			continue;
 		for (o = rdt_options; o < &rdt_options[NUM_RDT_OPTIONS]; o++) {
 			if (strcmp(tok, o->name) == 0) {
diff --git a/arch/x86/kernel/cpu/resctrl/intel_aet.c b/arch/x86/kernel/cpu/resctrl/intel_aet.c
index 59066e1c6333..5dd47b65823b 100644
--- a/arch/x86/kernel/cpu/resctrl/intel_aet.c
+++ b/arch/x86/kernel/cpu/resctrl/intel_aet.c
@@ -139,7 +139,7 @@ static struct event_group *known_event_groups[] = {
 	     _peg < &known_event_groups[ARRAY_SIZE(known_event_groups)];	\
 	     _peg++)
 
-bool intel_handle_aet_option(bool force_off, char *tok)
+bool rdt_handle_aet_option(bool force_off, char *tok)
 {
 	struct event_group **peg;
 	bool ret = false;
@@ -194,7 +194,7 @@ static bool group_has_usable_regions(struct event_group *e, struct pmt_feature_g
 		if (skip_telem_region(&p->regions[i], e)) {
 			/*
 			 * Clear the address field of regions that did not pass the checks in
-			 * skip_telem_region() so they will not be used by intel_aet_read_event().
+			 * skip_telem_region() so they will not be used by rdt_aet_read_event().
 			 * This is safe to do because intel_pmt_get_regions_by_feature() allocates
 			 * a new pmt_feature_group structure to return to each caller and only makes
 			 * use of the pmt_feature_group::kref field when intel_pmt_put_feature_group()
@@ -398,7 +398,7 @@ void intel_aet_invalidate(u8 package_id)
 }
 EXPORT_SYMBOL_NS_GPL(intel_aet_invalidate, "INTEL_PMT");
 
-bool intel_aet_pre_mount(void)
+bool rdt_aet_pre_mount(void)
 {
 	guard(mutex)(&aet_register_lock);
 
@@ -418,7 +418,7 @@ bool intel_aet_pre_mount(void)
 	return true;
 }
 
-void intel_aet_unmount(void)
+void rdt_aet_unmount(void)
 {
 	struct rdt_resource *r = &rdt_resources_all[RDT_RESOURCE_PERF_PKG].r_resctrl;
 	struct event_group **peg;
@@ -452,7 +452,7 @@ void intel_aet_unmount(void)
  * the MMIO read indicates that data is not valid.  Return success if at
  * least one aggregator has valid data.
  */
-int intel_aet_read_event(int domid, u32 rmid, void *arch_priv, u64 *val)
+int rdt_aet_read_event(int domid, u32 rmid, void *arch_priv, u64 *val)
 {
 	struct pmt_event *pevt = arch_priv;
 	struct event_group *e;
@@ -492,7 +492,7 @@ int intel_aet_read_event(int domid, u32 rmid, void *arch_priv, u64 *val)
 	return valid ? 0 : -EINVAL;
 }
 
-void intel_aet_mon_domain_setup(int cpu, int id, struct rdt_resource *r,
+void rdt_aet_mon_domain_setup(int cpu, int id, struct rdt_resource *r,
 				struct list_head *add_pos)
 {
 	struct rdt_perf_pkg_mon_domain *d;
diff --git a/arch/x86/kernel/cpu/resctrl/monitor.c b/arch/x86/kernel/cpu/resctrl/monitor.c
index bd45d72d1d05..0701ec3ef4e0 100644
--- a/arch/x86/kernel/cpu/resctrl/monitor.c
+++ b/arch/x86/kernel/cpu/resctrl/monitor.c
@@ -255,7 +255,7 @@ int resctrl_arch_rmid_read(struct rdt_resource *r, struct rdt_domain_hdr *hdr,
 	resctrl_arch_rmid_read_context_check();
 
 	if (r->rid == RDT_RESOURCE_PERF_PKG)
-		return intel_aet_read_event(hdr->id, rmid, arch_priv, val);
+		return rdt_aet_read_event(hdr->id, rmid, arch_priv, val);
 
 	if (!domain_header_is_valid(hdr, RESCTRL_MON_DOMAIN, RDT_RESOURCE_L3))
 		return -EINVAL;
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 06b5d0c4633e..47f92613434e 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -539,19 +539,6 @@ config X86_CPU_RESCTRL
 
 	  Say N if unsure.
 
-config X86_CPU_RESCTRL_INTEL_AET
-	bool "Intel Application Energy Telemetry"
-	depends on 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..9daf1c0abb80 100644
--- a/arch/x86/kernel/cpu/resctrl/Makefile
+++ b/arch/x86/kernel/cpu/resctrl/Makefile
@@ -1,7 +1,6 @@
 # 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)		+= ctrlmondata.o intel_aet.o
 obj-$(CONFIG_RESCTRL_FS_PSEUDO_LOCK)	+= pseudo_lock.o
 
 # To allow define_trace.h's recursive include:
-- 
2.55.0


^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH v13 25/25] x86,fs/resctrl: Document telemetry mount timing caveat
  2026-09-28 22:14 [PATCH v13 00/25] Allow AET to use PMT as loadable module Tony Luck
                   ` (23 preceding siblings ...)
  2026-09-28 22:15 ` [PATCH v13 24/25] x86/resctrl: Simplify Kconfig options for resctrl Tony Luck
@ 2026-09-28 22:15 ` Tony Luck
  2026-09-29  0:29 ` [PATCH v13 00/25] Allow AET to use PMT as loadable module Luck, Tony
  25 siblings, 0 replies; 27+ messages in thread
From: Tony Luck @ 2026-09-28 22:15 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

The PMT driver enumerates telemetry features asynchronously, so an
automatic mount of resctrl from /etc/fstab early in boot may occur before
those features are available, resulting in them not being enabled in the
mounted instance.

Add a footnote to the 'If telemetry monitoring is enabled' sentence
explaining the race and providing a solution.

Signed-off-by: Tony Luck <tony.luck@intel.com>
---
v13:
	Drop the "Mounting resctrl with telemetry" section. Include the
	solution in the footnote.
---
 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 b52795e03303..dcae1076f863 100644
--- a/Documentation/filesystems/resctrl.rst
+++ b/Documentation/filesystems/resctrl.rst
@@ -629,7 +629,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.)
@@ -668,6 +668,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, so
+   an automatic mount of resctrl from ``/etc/fstab`` at boot may not enable
+   them. To avoid this race, defer the mount until after the ``pmt_telemetry``
+   module has loaded.
+
 "mon_hw_id":
 	Available only with debug option. The identifier used by hardware
 	for the monitor group. On x86 this is the RMID.
-- 
2.55.0


^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v13 00/25] Allow AET to use PMT as loadable module
  2026-09-28 22:14 [PATCH v13 00/25] Allow AET to use PMT as loadable module Tony Luck
                   ` (24 preceding siblings ...)
  2026-09-28 22:15 ` [PATCH v13 25/25] x86,fs/resctrl: Document telemetry mount timing caveat Tony Luck
@ 2026-09-29  0:29 ` Luck, Tony
  25 siblings, 0 replies; 27+ messages in thread
From: Luck, Tony @ 2026-09-29  0:29 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

Sashiko summary (full version: https://sashiko.dev/#/patchset/20260928221509.68002-1-tony.luck%40intel.com)

Patch 4: [PATCH v13 04/25] x86/resctrl: Centralize monitoring feature enumeration

	Sashiko thinks I broke AMD & Hygon by adding the dependency:

		{ X86_FEATURE_CQM_LLC,			X86_FEATURE_CQM       }

	and this code:

		> +	/* Any monitoring at all? */
	> +	if (!cpu_feature_enabled(X86_FEATURE_CQM))
	> +		return false;

	But Babu said he tested v12 which had this same change. So perhaps bogus?


Patch 21: [PATCH v13 21/25] x86/resctrl: Export interface to report telemetry unbind/remove

	Sashiko says my new locks still have races. This one looks real.  See below(*).

	But also a bogus warning that intel_aet_read_event() may be called from
	IPI handler on nohz CPUs. All AET events are read from MMIO, so can be
	accessed on any CPU, so there is never an smp_call_*() via IPI.

Patch 22: [PATCH v13 22/25] platform/x86/intel/pmt: Inform resctrl when MMIO maps are being removed

	Bogus concern about ACPI telemetry devices. They don't exist.

---

* I asked another AI if it could fix my locking issue. It's given me some
  slightly complicated code that has some scoped_guard() bits to hold and
  release locks. I'm staring at it now to see if I like it.

-Tony

^ permalink raw reply	[flat|nested] 27+ messages in thread

end of thread, other threads:[~2026-09-29  0:29 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-28 22:14 [PATCH v13 00/25] Allow AET to use PMT as loadable module Tony Luck
2026-09-28 22:14 ` [PATCH v13 01/25] fs/resctrl: Ensure default group reports tasks on monitor-only systems Tony Luck
2026-09-28 22:14 ` [PATCH v13 02/25] x86/cpufeatures: Add missing CQM feature dependency Tony Luck
2026-09-28 22:14 ` [PATCH v13 03/25] x86/resctrl: Check if monitoring features are supported Tony Luck
2026-09-28 22:14 ` [PATCH v13 04/25] x86/resctrl: Centralize monitoring feature enumeration Tony Luck
2026-09-28 22:14 ` [PATCH v13 05/25] x86/resctrl: Apply Intel MBM quirk from rdt_get_l3_mon_config() Tony Luck
2026-09-28 22:14 ` [PATCH v13 06/25] x86/resctrl: Delete resctrl_cpu_detect() Tony Luck
2026-09-28 22:14 ` [PATCH v13 07/25] arm,x86,fs/resctrl: Replace architecture resctrl_arch_{alloc,mon}_capable() Tony Luck
2026-09-28 22:14 ` [PATCH v13 08/25] x86/resctrl: Update special case for Intel Haswell enumeration Tony Luck
2026-09-28 22:14 ` [PATCH v13 09/25] x86/resctrl: Delete rdt_alloc_capable and rdt_mon_capable Tony Luck
2026-09-28 22:14 ` [PATCH v13 10/25] fs/resctrl: Remove redundant calls to resctrl_mon_capable() Tony Luck
2026-09-28 22:14 ` [PATCH v13 11/25] x86/resctrl: Honor rdt={perf|energy} options to force enable AET events Tony Luck
2026-09-28 22:14 ` [PATCH v13 12/25] fs/resctrl: Add interface to disable a monitor event Tony Luck
2026-09-28 22:14 ` [PATCH v13 13/25] arm,x86,fs/resctrl: Allocate maximum needed rmid_ptrs[] Tony Luck
2026-09-28 22:14 ` [PATCH v13 14/25] arm,x86,fs/resctrl: Use right size for L3 monitor data structures Tony Luck
2026-09-28 22:14 ` [PATCH v13 15/25] x86,fs/resctrl: Handle systems where AET is the only resource Tony Luck
2026-09-28 22:15 ` [PATCH v13 16/25] x86/resctrl: Add PMT registration API for AET enumeration callbacks Tony Luck
2026-09-28 22:15 ` [PATCH v13 17/25] platform/x86/intel/pmt: Register enumeration functions with resctrl Tony Luck
2026-09-28 22:15 ` [PATCH v13 18/25] x86/resctrl: Use registered function pointers for AET enumeration Tony Luck
2026-09-28 22:15 ` [PATCH v13 19/25] arm,x86,fs/resctrl: Enumerate AET on every resctrl mount Tony Luck
2026-09-28 22:15 ` [PATCH v13 20/25] x86/resctrl: Enforce system RMID limit on AET Tony Luck
2026-09-28 22:15 ` [PATCH v13 21/25] x86/resctrl: Export interface to report telemetry unbind/remove Tony Luck
2026-09-28 22:15 ` [PATCH v13 22/25] platform/x86/intel/pmt: Inform resctrl when MMIO maps are being removed Tony Luck
2026-09-28 22:15 ` [PATCH v13 23/25] x86/resctrl: Require 64-bit x86 for resctrl support Tony Luck
2026-09-28 22:15 ` [PATCH v13 24/25] x86/resctrl: Simplify Kconfig options for resctrl Tony Luck
2026-09-28 22:15 ` [PATCH v13 25/25] x86,fs/resctrl: Document telemetry mount timing caveat Tony Luck
2026-09-29  0:29 ` [PATCH v13 00/25] Allow AET to use PMT as loadable module Luck, Tony

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®