Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

authored by

Tony Luck and committed by
Borislav Petkov (AMD)
51541f6c 7e6df961

+75 -1
+1 -1
arch/x86/Kconfig
··· 542 542 543 543 config X86_CPU_RESCTRL_INTEL_AET 544 544 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 546 546 help 547 547 Enable per-RMID telemetry events in resctrl. 548 548
+51
arch/x86/kernel/cpu/resctrl/intel_aet.c
··· 11 11 12 12 #define pr_fmt(fmt) "resctrl: " fmt 13 13 14 + #include <linux/bits.h> 14 15 #include <linux/compiler_types.h> 16 + #include <linux/container_of.h> 15 17 #include <linux/err.h> 18 + #include <linux/errno.h> 16 19 #include <linux/init.h> 17 20 #include <linux/intel_pmt_features.h> 18 21 #include <linux/intel_vsec.h> 22 + #include <linux/io.h> 19 23 #include <linux/printk.h> 20 24 #include <linux/resctrl.h> 21 25 #include <linux/resctrl_types.h> ··· 235 231 (*peg)->pfg = NULL; 236 232 } 237 233 } 234 + } 235 + 236 + #define DATA_VALID BIT_ULL(63) 237 + #define DATA_BITS GENMASK_ULL(62, 0) 238 + 239 + /* 240 + * Read counter for an event on a domain (summing all aggregators on the 241 + * domain). If an aggregator hasn't received any data for a specific RMID, 242 + * the MMIO read indicates that data is not valid. Return success if at 243 + * least one aggregator has valid data. 244 + */ 245 + int intel_aet_read_event(int domid, u32 rmid, void *arch_priv, u64 *val) 246 + { 247 + struct pmt_event *pevt = arch_priv; 248 + struct event_group *e; 249 + bool valid = false; 250 + u64 total = 0; 251 + u64 evtcount; 252 + void *pevt0; 253 + u32 idx; 254 + 255 + pevt0 = pevt - pevt->idx; 256 + e = container_of(pevt0, struct event_group, evts); 257 + idx = rmid * e->num_events; 258 + idx += pevt->idx; 259 + 260 + if (idx * sizeof(u64) + sizeof(u64) > e->mmio_size) { 261 + pr_warn_once("MMIO index %u out of range\n", idx); 262 + return -EIO; 263 + } 264 + 265 + for (int i = 0; i < e->pfg->count; i++) { 266 + if (!e->pfg->regions[i].addr) 267 + continue; 268 + if (e->pfg->regions[i].plat_info.package_id != domid) 269 + continue; 270 + evtcount = readq(e->pfg->regions[i].addr + idx * sizeof(u64)); 271 + if (!(evtcount & DATA_VALID)) 272 + continue; 273 + total += evtcount & DATA_BITS; 274 + valid = true; 275 + } 276 + 277 + if (valid) 278 + *val = total; 279 + 280 + return valid ? 0 : -EINVAL; 238 281 }
+5
arch/x86/kernel/cpu/resctrl/internal.h
··· 225 225 #ifdef CONFIG_X86_CPU_RESCTRL_INTEL_AET 226 226 bool intel_aet_get_events(void); 227 227 void __exit intel_aet_exit(void); 228 + int intel_aet_read_event(int domid, u32 rmid, void *arch_priv, u64 *val); 228 229 #else 229 230 static inline bool intel_aet_get_events(void) { return false; } 230 231 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 + } 231 236 #endif 232 237 233 238 #endif /* _ASM_X86_RESCTRL_INTERNAL_H */
+4
arch/x86/kernel/cpu/resctrl/monitor.c
··· 251 251 int ret; 252 252 253 253 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 + 254 258 if (!domain_header_is_valid(hdr, RESCTRL_MON_DOMAIN, RDT_RESOURCE_L3)) 255 259 return -EINVAL; 256 260
+14
fs/resctrl/monitor.c
··· 527 527 return __l3_mon_event_count(rdtgrp, rr); 528 528 else 529 529 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 + } 530 544 default: 531 545 rr->err = -EINVAL; 532 546 return -EINVAL;