Skip to content

Commit 51541f6

Browse files
aeglbp3tk0v
authored andcommitted
x86/resctrl: Read telemetry 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. The user will see "Unavailable" if none of the aggregators on a package provide valid counts. Resctrl now uses readq() so depends on X86_64. Update Kconfig. Signed-off-by: Tony Luck <tony.luck@intel.com> Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de> Reviewed-by: Reinette Chatre <reinette.chatre@intel.com> Link: https://lore.kernel.org/20251217172121.12030-1-tony.luck@intel.com
1 parent 7e6df96 commit 51541f6

5 files changed

Lines changed: 75 additions & 1 deletion

File tree

arch/x86/Kconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -542,7 +542,7 @@ config X86_CPU_RESCTRL
542542

543543
config X86_CPU_RESCTRL_INTEL_AET
544544
bool "Intel Application Energy Telemetry"
545-
depends on X86_CPU_RESCTRL && CPU_SUP_INTEL && INTEL_PMT_TELEMETRY=y && INTEL_TPMI=y
545+
depends on X86_64 && X86_CPU_RESCTRL && CPU_SUP_INTEL && INTEL_PMT_TELEMETRY=y && INTEL_TPMI=y
546546
help
547547
Enable per-RMID telemetry events in resctrl.
548548

arch/x86/kernel/cpu/resctrl/intel_aet.c

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,15 @@
1111

1212
#define pr_fmt(fmt) "resctrl: " fmt
1313

14+
#include <linux/bits.h>
1415
#include <linux/compiler_types.h>
16+
#include <linux/container_of.h>
1517
#include <linux/err.h>
18+
#include <linux/errno.h>
1619
#include <linux/init.h>
1720
#include <linux/intel_pmt_features.h>
1821
#include <linux/intel_vsec.h>
22+
#include <linux/io.h>
1923
#include <linux/printk.h>
2024
#include <linux/resctrl.h>
2125
#include <linux/resctrl_types.h>
@@ -232,3 +236,50 @@ void __exit intel_aet_exit(void)
232236
}
233237
}
234238
}
239+
240+
#define DATA_VALID BIT_ULL(63)
241+
#define DATA_BITS GENMASK_ULL(62, 0)
242+
243+
/*
244+
* Read counter for an event on a domain (summing all aggregators on the
245+
* domain). If an aggregator hasn't received any data for a specific RMID,
246+
* the MMIO read indicates that data is not valid. Return success if at
247+
* least one aggregator has valid data.
248+
*/
249+
int intel_aet_read_event(int domid, u32 rmid, void *arch_priv, u64 *val)
250+
{
251+
struct pmt_event *pevt = arch_priv;
252+
struct event_group *e;
253+
bool valid = false;
254+
u64 total = 0;
255+
u64 evtcount;
256+
void *pevt0;
257+
u32 idx;
258+
259+
pevt0 = pevt - pevt->idx;
260+
e = container_of(pevt0, struct event_group, evts);
261+
idx = rmid * e->num_events;
262+
idx += pevt->idx;
263+
264+
if (idx * sizeof(u64) + sizeof(u64) > e->mmio_size) {
265+
pr_warn_once("MMIO index %u out of range\n", idx);
266+
return -EIO;
267+
}
268+
269+
for (int i = 0; i < e->pfg->count; i++) {
270+
if (!e->pfg->regions[i].addr)
271+
continue;
272+
if (e->pfg->regions[i].plat_info.package_id != domid)
273+
continue;
274+
evtcount = readq(e->pfg->regions[i].addr + idx * sizeof(u64));
275+
if (!(evtcount & DATA_VALID))
276+
continue;
277+
total += evtcount & DATA_BITS;
278+
valid = true;
279+
}
280+
281+
if (valid)
282+
*val = total;
283+
284+
return valid ? 0 : -EINVAL;
285+
}

arch/x86/kernel/cpu/resctrl/internal.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,9 +225,14 @@ void resctrl_arch_mbm_cntr_assign_set_one(struct rdt_resource *r);
225225
#ifdef CONFIG_X86_CPU_RESCTRL_INTEL_AET
226226
bool intel_aet_get_events(void);
227227
void __exit intel_aet_exit(void);
228+
int intel_aet_read_event(int domid, u32 rmid, void *arch_priv, u64 *val);
228229
#else
229230
static inline bool intel_aet_get_events(void) { return false; }
230231
static inline void __exit intel_aet_exit(void) { }
232+
static inline int intel_aet_read_event(int domid, u32 rmid, void *arch_priv, u64 *val)
233+
{
234+
return -EINVAL;
235+
}
231236
#endif
232237

233238
#endif /* _ASM_X86_RESCTRL_INTERNAL_H */

arch/x86/kernel/cpu/resctrl/monitor.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,10 @@ int resctrl_arch_rmid_read(struct rdt_resource *r, struct rdt_domain_hdr *hdr,
251251
int ret;
252252

253253
resctrl_arch_rmid_read_context_check();
254+
255+
if (r->rid == RDT_RESOURCE_PERF_PKG)
256+
return intel_aet_read_event(hdr->id, rmid, arch_priv, val);
257+
254258
if (!domain_header_is_valid(hdr, RESCTRL_MON_DOMAIN, RDT_RESOURCE_L3))
255259
return -EINVAL;
256260

fs/resctrl/monitor.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -527,6 +527,20 @@ static int __mon_event_count(struct rdtgroup *rdtgrp, struct rmid_read *rr)
527527
return __l3_mon_event_count(rdtgrp, rr);
528528
else
529529
return __l3_mon_event_count_sum(rdtgrp, rr);
530+
case RDT_RESOURCE_PERF_PKG: {
531+
u64 tval = 0;
532+
533+
rr->err = resctrl_arch_rmid_read(rr->r, rr->hdr, rdtgrp->closid,
534+
rdtgrp->mon.rmid, rr->evt->evtid,
535+
rr->evt->arch_priv,
536+
&tval, rr->arch_mon_ctx);
537+
if (rr->err)
538+
return rr->err;
539+
540+
rr->val += tval;
541+
542+
return 0;
543+
}
530544
default:
531545
rr->err = -EINVAL;
532546
return -EINVAL;

0 commit comments

Comments
 (0)