[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20251013223348.103390-20-tony.luck@intel.com>
Date: Mon, 13 Oct 2025 15:33:33 -0700
From: Tony Luck <tony.luck@...el.com>
To: Fenghua Yu <fenghuay@...dia.com>,
Reinette Chatre <reinette.chatre@...el.com>,
Maciej Wieczor-Retman <maciej.wieczor-retman@...el.com>,
Peter Newman <peternewman@...gle.com>,
James Morse <james.morse@....com>,
Babu Moger <babu.moger@....com>,
Drew Fustini <dfustini@...libre.com>,
Dave Martin <Dave.Martin@....com>,
Chen Yu <yu.c.chen@...el.com>
Cc: x86@...nel.org,
linux-kernel@...r.kernel.org,
patches@...ts.linux.dev,
Tony Luck <tony.luck@...el.com>
Subject: [PATCH v12 19/31] x86/resctrl: Read telemetry events
Telemetry events are enabled during the first mount of the resctrl
file system.
Mark telemetry regions that did not pass the sanity checks by
clearing their MMIO address fields so that they will not be
used when reading events.
Introduce intel_aet_read_event() to read telemetry events for resource
RDT_RESOURCE_PERF_PKG. There may be multiple aggregators tracking each
package, so scan all of them and add up all counters. Aggregators may
return an invalid data indication if they have received no records for
a given RMID. Return success to the user if one or more aggregators
provide valid data.
Resctrl now uses readq() so depends on X86_64. Update Kconfig.
Signed-off-by: Tony Luck <tony.luck@...el.com>
---
arch/x86/kernel/cpu/resctrl/internal.h | 7 ++++
arch/x86/kernel/cpu/resctrl/intel_aet.c | 48 +++++++++++++++++++++++++
arch/x86/kernel/cpu/resctrl/monitor.c | 3 ++
fs/resctrl/monitor.c | 14 ++++++++
arch/x86/Kconfig | 2 +-
5 files changed, 73 insertions(+), 1 deletion(-)
diff --git a/arch/x86/kernel/cpu/resctrl/internal.h b/arch/x86/kernel/cpu/resctrl/internal.h
index 886261a82b81..97616c81682b 100644
--- a/arch/x86/kernel/cpu/resctrl/internal.h
+++ b/arch/x86/kernel/cpu/resctrl/internal.h
@@ -220,9 +220,16 @@ 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);
+int intel_aet_read_event(int domid, u32 rmid, enum resctrl_event_id evtid,
+ void *arch_priv, u64 *val);
#else
static inline bool intel_aet_get_events(void) { return false; }
static inline void __exit intel_aet_exit(void) { }
+static inline int intel_aet_read_event(int domid, u32 rmid, enum resctrl_event_id evtid,
+ void *arch_priv, u64 *val)
+{
+ return -EINVAL;
+}
#endif
#endif /* _ASM_X86_RESCTRL_INTERNAL_H */
diff --git a/arch/x86/kernel/cpu/resctrl/intel_aet.c b/arch/x86/kernel/cpu/resctrl/intel_aet.c
index a500b5d384fb..003b6426c8bd 100644
--- a/arch/x86/kernel/cpu/resctrl/intel_aet.c
+++ b/arch/x86/kernel/cpu/resctrl/intel_aet.c
@@ -12,13 +12,17 @@
#define pr_fmt(fmt) "resctrl: " fmt
#include <linux/array_size.h>
+#include <linux/bits.h>
#include <linux/cleanup.h>
#include <linux/compiler_types.h>
+#include <linux/container_of.h>
#include <linux/cpu.h>
#include <linux/err.h>
+#include <linux/errno.h>
#include <linux/init.h>
#include <linux/intel_pmt_features.h>
#include <linux/intel_vsec.h>
+#include <linux/io.h>
#include <linux/overflow.h>
#include <linux/printk.h>
#include <linux/resctrl.h>
@@ -230,3 +234,47 @@ void __exit intel_aet_exit(void)
(*peg)->pfg = NULL;
}
}
+
+#define DATA_VALID BIT_ULL(63)
+#define DATA_BITS GENMASK_ULL(62, 0)
+
+/*
+ * Read counter for an event on a domain (summing all aggregators
+ * on the domain). If an aggregator hasn't received any data for a
+ * specific RMID, 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, enum resctrl_event_id eventid,
+ void *arch_priv, u64 *val)
+{
+ struct pmt_event *pevt = arch_priv;
+ struct event_group *e;
+ bool valid = false;
+ u64 evtcount;
+ void *pevt0;
+ u32 idx;
+
+ pevt0 = pevt - pevt->idx;
+ e = container_of(pevt0, struct event_group, evts);
+ idx = rmid * e->num_events;
+ idx += pevt->idx;
+
+ if (idx * sizeof(u64) + sizeof(u64) > e->mmio_size) {
+ pr_warn_once("MMIO index %u out of range\n", idx);
+ return -EIO;
+ }
+
+ for (int i = 0; i < e->pfg->count; i++) {
+ if (!e->pfg->regions[i].addr)
+ continue;
+ if (e->pfg->regions[i].plat_info.package_id != domid)
+ continue;
+ evtcount = readq(e->pfg->regions[i].addr + idx * sizeof(u64));
+ if (!(evtcount & DATA_VALID))
+ continue;
+ *val += evtcount & DATA_BITS;
+ valid = true;
+ }
+
+ return valid ? 0 : -EINVAL;
+}
diff --git a/arch/x86/kernel/cpu/resctrl/monitor.c b/arch/x86/kernel/cpu/resctrl/monitor.c
index 5565a8752266..6804b83934e8 100644
--- a/arch/x86/kernel/cpu/resctrl/monitor.c
+++ b/arch/x86/kernel/cpu/resctrl/monitor.c
@@ -252,6 +252,9 @@ 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, eventid, arch_priv, val);
+
if (!domain_header_is_valid(hdr, RESCTRL_MON_DOMAIN, RDT_RESOURCE_L3))
return -EINVAL;
diff --git a/fs/resctrl/monitor.c b/fs/resctrl/monitor.c
index faaa2851c5c2..84a0cbe90748 100644
--- a/fs/resctrl/monitor.c
+++ b/fs/resctrl/monitor.c
@@ -526,12 +526,26 @@ static bool cpu_on_correct_domain(struct rmid_read *rr)
static int __mon_event_count(struct rdtgroup *rdtgrp, struct rmid_read *rr)
{
+ u64 tval = 0;
+
if (!cpu_on_correct_domain(rr))
return -EINVAL;
switch (rr->r->rid) {
case RDT_RESOURCE_L3:
return __l3_mon_event_count(rdtgrp, rr);
+
+ case RDT_RESOURCE_PERF_PKG:
+ rr->err = resctrl_arch_rmid_read(rr->r, rr->hdr, rdtgrp->closid,
+ rdtgrp->mon.rmid, rr->evt->evtid,
+ rr->evt->arch_priv,
+ &tval, rr->arch_mon_ctx);
+ if (rr->err)
+ return rr->err;
+
+ rr->val += tval;
+
+ return 0;
default:
return -EINVAL;
}
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index da5775056ec8..60ace4427ede 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -538,7 +538,7 @@ config X86_CPU_RESCTRL
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
+ depends on X86_64 && X86_CPU_RESCTRL && CPU_SUP_INTEL && INTEL_PMT_TELEMETRY=y && INTEL_TPMI=y
help
Enable per-RMID telemetry events in resctrl.
--
2.51.0
Powered by blists - more mailing lists