[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250521225049.132551-22-tony.luck@intel.com>
Date: Wed, 21 May 2025 15:50:39 -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 v5 21/29] x86/resctrl: x86/resctrl: Read core 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.
At run time when a user reads an event file the file system code
provides the enum resctrl_event_id for the event.
Create a lookup table indexed by event id to provide the telem_entry
structure and the event index into MMIO space.
Enable the events marked as readable from any CPU.
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 | 1 +
arch/x86/kernel/cpu/resctrl/intel_aet.c | 53 +++++++++++++++++++++++++
arch/x86/kernel/cpu/resctrl/monitor.c | 6 +++
arch/x86/Kconfig | 2 +-
4 files changed, 61 insertions(+), 1 deletion(-)
diff --git a/arch/x86/kernel/cpu/resctrl/internal.h b/arch/x86/kernel/cpu/resctrl/internal.h
index 2b2d4b5a4643..42da0a222c7c 100644
--- a/arch/x86/kernel/cpu/resctrl/internal.h
+++ b/arch/x86/kernel/cpu/resctrl/internal.h
@@ -169,5 +169,6 @@ void rdt_domain_reconfigure_cdp(struct rdt_resource *r);
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, u64 *val);
#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 bf8e2a6126d2..be52c9302a80 100644
--- a/arch/x86/kernel/cpu/resctrl/intel_aet.c
+++ b/arch/x86/kernel/cpu/resctrl/intel_aet.c
@@ -13,6 +13,7 @@
#include <linux/cleanup.h>
#include <linux/cpu.h>
+#include <linux/io.h>
#include <linux/resctrl.h>
#include <linux/slab.h>
@@ -128,6 +129,16 @@ static bool skip_this_region(struct telemetry_region *tr, struct event_group *e)
return false;
}
+/**
+ * struct evtinfo - lookup table from resctrl_event_id to useful information
+ * @event_group: Pointer to the telem_entry structure for this event
+ * @idx: Counter index within each per-RMID block of counters
+ */
+static struct evtinfo {
+ struct event_group *event_group;
+ int idx;
+} evtinfo[QOS_NUM_EVENTS];
+
static void free_mmio_info(struct mmio_info **mmi)
{
int num_pkgs = topology_max_packages();
@@ -199,6 +210,15 @@ static int configure_events(struct event_group *e, struct pmt_feature_group *p)
}
e->pkginfo = no_free_ptr(pkginfo);
+ for (int i = 0; i < e->num_events; i++) {
+ enum resctrl_event_id evt;
+
+ evt = e->evts[i].evtid;
+ evtinfo[evt].event_group = e;
+ evtinfo[evt].idx = e->evts[i].evt_idx;
+ resctrl_enable_mon_event(evt, true, e->evts[i].bin_bits);
+ }
+
return 0;
}
@@ -266,3 +286,36 @@ void __exit intel_aet_exit(void)
free_mmio_info((*peg)->pkginfo);
}
}
+
+#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 evtid, u64 *val)
+{
+ struct evtinfo *info = &evtinfo[evtid];
+ struct mmio_info *mmi;
+ u64 evtcount;
+ int idx;
+
+ idx = rmid * info->event_group->num_events;
+ idx += info->idx;
+ mmi = info->event_group->pkginfo[domid];
+
+ if (idx * sizeof(u64) + sizeof(u64) > info->event_group->mmio_size) {
+ pr_warn_once("MMIO index %d out of range\n", idx);
+ return -EIO;
+ }
+
+ for (int i = 0; i < mmi->count; 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 1f6dc253112f..c99aa9dacfd8 100644
--- a/arch/x86/kernel/cpu/resctrl/monitor.c
+++ b/arch/x86/kernel/cpu/resctrl/monitor.c
@@ -230,6 +230,12 @@ int resctrl_arch_rmid_read(struct rdt_resource *r, struct rdt_l3_mon_domain *d,
resctrl_arch_rmid_read_context_check();
+ if (r->rid == RDT_RESOURCE_PERF_PKG)
+ return intel_aet_read_event(d->hdr.id, rmid, eventid, val);
+
+ if (r->rid != RDT_RESOURCE_L3)
+ return -EIO;
+
prmid = logical_rmid_to_physical_rmid(cpu, rmid);
ret = __rmid_read_phys(prmid, eventid, &msr_val);
if (ret)
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 52cfb69c343f..24df3f04a115 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -506,7 +506,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
--
2.49.0
Powered by blists - more mailing lists