[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250711235341.113933-23-tony.luck@intel.com>
Date: Fri, 11 Jul 2025 16:53:29 -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>,
Anil Keshavamurthy <anil.s.keshavamurthy@...el.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 v7 22/31] x86/resctrl: Read telemetry events
The resctrl file system passes requests to read event monitor files to
the architecture resctrl_arch_rmid_read() to collect values
from hardware counters.
Use the resctrl resource to differentiate between calls to read legacy
L3 events from the new telemetry events (which are attached to
RDT_RESOURCE_PERF_PKG).
There may be multiple aggregators tracking each package, so scan all of
them and add up all counters.
Enable the events marked as readable from any CPU providing an
mon_evt::arch_priv pointer to the struct pmt_event for each
event.
At run time when a user reads an event file the file system code
provides the enum resctrl_event_id for the event and the arch_priv
pointer that was supplied when the event was enabled.
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 | 46 +++++++++++++++++++++++++
arch/x86/kernel/cpu/resctrl/monitor.c | 3 ++
arch/x86/Kconfig | 2 +-
4 files changed, 57 insertions(+), 1 deletion(-)
diff --git a/arch/x86/kernel/cpu/resctrl/internal.h b/arch/x86/kernel/cpu/resctrl/internal.h
index 36a2072c19c7..0081fb5a4420 100644
--- a/arch/x86/kernel/cpu/resctrl/internal.h
+++ b/arch/x86/kernel/cpu/resctrl/internal.h
@@ -172,9 +172,16 @@ void rdt_domain_reconfigure_cdp(struct rdt_resource *r);
#ifdef CONFIG_X86_RESCTRL_CPU_INTEL_AET
bool intel_aet_get_events(void);
void __exit intel_aet_exit(void);
+int intel_aet_read_event(int domid, int 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, int 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 f4bf0f2ccf26..bd6011a95d12 100644
--- a/arch/x86/kernel/cpu/resctrl/intel_aet.c
+++ b/arch/x86/kernel/cpu/resctrl/intel_aet.c
@@ -14,6 +14,7 @@
#include <linux/cleanup.h>
#include <linux/cpu.h>
#include <linux/intel_vsec.h>
+#include <linux/io.h>
#include <linux/resctrl.h>
#include <linux/slab.h>
@@ -213,6 +214,13 @@ static int discover_events(struct event_group *e, struct pmt_feature_group *p)
list_add(&e->list, &active_event_groups);
+ for (int i = 0; i < e->num_events; i++) {
+ enum resctrl_event_id eventid;
+
+ eventid = e->evts[i].id;
+ resctrl_enable_mon_event(eventid, true, e->evts[i].bin_bits, &e->evts[i]);
+ }
+
return 0;
}
@@ -279,3 +287,41 @@ void __exit intel_aet_exit(void)
list_del(&evg->list);
}
}
+
+#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).
+ */
+int intel_aet_read_event(int domid, int rmid, enum resctrl_event_id eventid,
+ void *arch_priv, u64 *val)
+{
+ struct pmt_event *pevt = arch_priv;
+ struct pkg_mmio_info *mmi;
+ struct event_group *e;
+ u64 evtcount;
+ void *pevt0;
+ int idx;
+
+ pevt0 = pevt - pevt->idx;
+ e = container_of(pevt0, struct event_group, evts);
+ idx = rmid * e->num_events;
+ idx += pevt->idx;
+ mmi = e->pkginfo[domid];
+
+ if (idx * sizeof(u64) + sizeof(u64) > e->mmio_size) {
+ pr_warn_once("MMIO index %d out of range\n", idx);
+ return -EIO;
+ }
+
+ for (int i = 0; i < mmi->num_regions; i++) {
+ evtcount = readq(mmi->addrs[i] + idx * sizeof(u64));
+ if (!(evtcount & DATA_VALID))
+ return -EINVAL;
+ *val += evtcount & DATA_BITS;
+ }
+
+ return 0;
+}
diff --git a/arch/x86/kernel/cpu/resctrl/monitor.c b/arch/x86/kernel/cpu/resctrl/monitor.c
index 185b203f6321..51d7d99336c6 100644
--- a/arch/x86/kernel/cpu/resctrl/monitor.c
+++ b/arch/x86/kernel/cpu/resctrl/monitor.c
@@ -232,6 +232,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 (r->rid != RDT_RESOURCE_L3)
return -EINVAL;
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 21c2d1022b15..512286ef6d71 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -530,7 +530,7 @@ config X86_CPU_RESCTRL
config X86_RESCTRL_CPU_INTEL_AET
bool "Intel Application Energy Telemetry" if INTEL_PMT_DISCOVERY=y
- depends on X86_CPU_RESCTRL && CPU_SUP_INTEL
+ depends on X86_64 && X86_CPU_RESCTRL && CPU_SUP_INTEL
help
Enable per-RMID telemetry events in resctrl
--
2.50.0
Powered by blists - more mailing lists