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: Find and enable usable telemetry events

Every event group has a private copy of the data of all telemetry event
aggregators (aka "telemetry regions") tracking its feature type. Included
may be regions that have the same feature type but tracking different GUID
from the event group's.

Traverse the event group's telemetry region data and mark all regions that
are not usable by the event group as unusable by clearing those regions'
MMIO addresses. A region is considered unusable if:
1) GUID does not match the GUID of the event group.
2) Package ID is invalid.
3) The enumerated size of the MMIO region does not match the expected
value from the XML description file.

Hereafter any telemetry region with an MMIO address is considered valid for
the event group it is associated with.

Enable all the event group's events as long as there is at least one usable
region from where data for its events can be read. Enabling of an event can
fail if the same event has already been enabled as part of another event
group. It should never happen that the same event is described by different
GUID supported by the same system so just WARN (via resctrl_enable_mon_event())
and skip the event.

Note that it is architecturally possible that some telemetry events are only
supported by a subset of the packages in the system. It is not expected that
systems will ever do this. If they do the user will see event files in resctrl
that always return "Unavailable".

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)
7e6df961 8ccb1f8f

+68 -7
+61 -2
arch/x86/kernel/cpu/resctrl/intel_aet.c
··· 16 16 #include <linux/init.h> 17 17 #include <linux/intel_pmt_features.h> 18 18 #include <linux/intel_vsec.h> 19 + #include <linux/printk.h> 19 20 #include <linux/resctrl.h> 20 21 #include <linux/resctrl_types.h> 21 22 #include <linux/stddef.h> 23 + #include <linux/topology.h> 22 24 #include <linux/types.h> 23 25 24 26 #include "internal.h" ··· 112 110 _peg < &known_event_groups[ARRAY_SIZE(known_event_groups)]; \ 113 111 _peg++) 114 112 115 - /* Stub for now */ 113 + static bool skip_telem_region(struct telemetry_region *tr, struct event_group *e) 114 + { 115 + if (tr->guid != e->guid) 116 + return true; 117 + if (tr->plat_info.package_id >= topology_max_packages()) { 118 + pr_warn("Bad package %u in guid 0x%x\n", tr->plat_info.package_id, 119 + tr->guid); 120 + return true; 121 + } 122 + if (tr->size != e->mmio_size) { 123 + pr_warn("MMIO space wrong size (%zu bytes) for guid 0x%x. Expected %zu bytes.\n", 124 + tr->size, e->guid, e->mmio_size); 125 + return true; 126 + } 127 + 128 + return false; 129 + } 130 + 131 + static bool group_has_usable_regions(struct event_group *e, struct pmt_feature_group *p) 132 + { 133 + bool usable_regions = false; 134 + 135 + for (int i = 0; i < p->count; i++) { 136 + if (skip_telem_region(&p->regions[i], e)) { 137 + /* 138 + * Clear the address field of regions that did not pass the checks in 139 + * skip_telem_region() so they will not be used by intel_aet_read_event(). 140 + * This is safe to do because intel_pmt_get_regions_by_feature() allocates 141 + * a new pmt_feature_group structure to return to each caller and only makes 142 + * use of the pmt_feature_group::kref field when intel_pmt_put_feature_group() 143 + * returns the structure. 144 + */ 145 + p->regions[i].addr = NULL; 146 + 147 + continue; 148 + } 149 + usable_regions = true; 150 + } 151 + 152 + return usable_regions; 153 + } 154 + 116 155 static bool enable_events(struct event_group *e, struct pmt_feature_group *p) 117 156 { 118 - return false; 157 + struct rdt_resource *r = &rdt_resources_all[RDT_RESOURCE_PERF_PKG].r_resctrl; 158 + int skipped_events = 0; 159 + 160 + if (!group_has_usable_regions(e, p)) 161 + return false; 162 + 163 + for (int j = 0; j < e->num_events; j++) { 164 + if (!resctrl_enable_mon_event(e->evts[j].id, true, 165 + e->evts[j].bin_bits, &e->evts[j])) 166 + skipped_events++; 167 + } 168 + if (e->num_events == skipped_events) { 169 + pr_info("No events enabled in %s %s:0x%x\n", r->name, e->pfname, e->guid); 170 + return false; 171 + } 172 + 173 + return true; 119 174 } 120 175 121 176 static enum pmt_feature_id lookup_pfid(const char *pfname)
+6 -4
fs/resctrl/monitor.c
··· 997 997 MON_EVENT(PMT_EVENT_UOPS_RETIRED, "uops_retired", RDT_RESOURCE_PERF_PKG, false), 998 998 }; 999 999 1000 - void resctrl_enable_mon_event(enum resctrl_event_id eventid, bool any_cpu, 1000 + bool resctrl_enable_mon_event(enum resctrl_event_id eventid, bool any_cpu, 1001 1001 unsigned int binary_bits, void *arch_priv) 1002 1002 { 1003 1003 if (WARN_ON_ONCE(eventid < QOS_FIRST_EVENT || eventid >= QOS_NUM_EVENTS || 1004 1004 binary_bits > MAX_BINARY_BITS)) 1005 - return; 1005 + return false; 1006 1006 if (mon_event_all[eventid].enabled) { 1007 1007 pr_warn("Duplicate enable for event %d\n", eventid); 1008 - return; 1008 + return false; 1009 1009 } 1010 1010 if (binary_bits && !mon_event_all[eventid].is_floating_point) { 1011 1011 pr_warn("Event %d may not be floating point\n", eventid); 1012 - return; 1012 + return false; 1013 1013 } 1014 1014 1015 1015 mon_event_all[eventid].any_cpu = any_cpu; 1016 1016 mon_event_all[eventid].binary_bits = binary_bits; 1017 1017 mon_event_all[eventid].arch_priv = arch_priv; 1018 1018 mon_event_all[eventid].enabled = true; 1019 + 1020 + return true; 1019 1021 } 1020 1022 1021 1023 bool resctrl_is_mon_event_enabled(enum resctrl_event_id eventid)
+1 -1
include/linux/resctrl.h
··· 414 414 u32 resctrl_arch_system_num_rmid_idx(void); 415 415 int resctrl_arch_update_domains(struct rdt_resource *r, u32 closid); 416 416 417 - void resctrl_enable_mon_event(enum resctrl_event_id eventid, bool any_cpu, 417 + bool resctrl_enable_mon_event(enum resctrl_event_id eventid, bool any_cpu, 418 418 unsigned int binary_bits, void *arch_priv); 419 419 420 420 bool resctrl_is_mon_event_enabled(enum resctrl_event_id eventid);