Skip to content

Commit 67640e3

Browse files
aeglbp3tk0v
authored andcommitted
x86/resctrl: Handle number of RMIDs supported by RDT_RESOURCE_PERF_PKG
There are now three meanings for "number of RMIDs": 1) The number for legacy features enumerated by CPUID leaf 0xF. This is the maximum number of distinct values that can be loaded into MSR_IA32_PQR_ASSOC. Note that systems with Sub-NUMA Cluster mode enabled will force scaling down the CPUID enumerated value by the number of SNC nodes per L3-cache. 2) The number of registers in MMIO space for each event. This is enumerated in the XML files and is the value initialized into event_group::num_rmid. 3) The number of "hardware counters" (this isn't a strictly accurate description of how things work, but serves as a useful analogy that does describe the limitations) feeding to those MMIO registers. This is enumerated in telemetry_region::num_rmids returned by intel_pmt_get_regions_by_feature(). Event groups with insufficient "hardware counters" to track all RMIDs are difficult for users to use, since the system may reassign "hardware counters" at any time. This means that users cannot reliably collect two consecutive event counts to compute the rate at which events are occurring. Disable such event groups by default. The user may override this with a command line "rdt=" option. In this case limit an under-resourced event group's number of possible monitor resource groups to the lowest number of "hardware counters". Scan all enabled event groups and assign the RDT_RESOURCE_PERF_PKG resource "num_rmid" value to the smallest of these values as this value will be used later to compare against the number of RMIDs supported by other resources to determine how many monitoring resource groups are supported. N.B. Change type of resctrl_mon::num_rmid to u32 to match its usage and the type of event_group::num_rmid so that min(r->num_rmid, e->num_rmid) won't complain about mixing signed and unsigned types. 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 842e7f9 commit 67640e3

3 files changed

Lines changed: 54 additions & 3 deletions

File tree

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

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include <linux/intel_pmt_features.h>
2323
#include <linux/intel_vsec.h>
2424
#include <linux/io.h>
25+
#include <linux/minmax.h>
2526
#include <linux/printk.h>
2627
#include <linux/rculist.h>
2728
#include <linux/rcupdate.h>
@@ -60,10 +61,14 @@ struct pmt_event {
6061
* Valid if the system supports the event group,
6162
* NULL otherwise.
6263
* @force_off: True when "rdt" command line or architecture code disables
63-
* this event group.
64+
* this event group due to insufficient RMIDs.
6465
* @force_on: True when "rdt" command line overrides disable of this
6566
* event group.
6667
* @guid: Unique number per XML description file.
68+
* @num_rmid: Number of RMIDs supported by this group. May be
69+
* adjusted downwards if enumeration from
70+
* intel_pmt_get_regions_by_feature() indicates fewer
71+
* RMIDs can be tracked simultaneously.
6772
* @mmio_size: Number of bytes of MMIO registers for this group.
6873
* @num_events: Number of events in this group.
6974
* @evts: Array of event descriptors.
@@ -76,6 +81,7 @@ struct event_group {
7681

7782
/* Remaining fields initialized from XML file. */
7883
u32 guid;
84+
u32 num_rmid;
7985
size_t mmio_size;
8086
unsigned int num_events;
8187
struct pmt_event evts[] __counted_by(num_events);
@@ -90,6 +96,7 @@ struct event_group {
9096
static struct event_group energy_0x26696143 = {
9197
.pfname = "energy",
9298
.guid = 0x26696143,
99+
.num_rmid = 576,
93100
.mmio_size = XML_MMIO_SIZE(576, 2, 3),
94101
.num_events = 2,
95102
.evts = {
@@ -104,6 +111,7 @@ static struct event_group energy_0x26696143 = {
104111
static struct event_group perf_0x26557651 = {
105112
.pfname = "perf",
106113
.guid = 0x26557651,
114+
.num_rmid = 576,
107115
.mmio_size = XML_MMIO_SIZE(576, 7, 3),
108116
.num_events = 7,
109117
.evts = {
@@ -198,6 +206,23 @@ static bool group_has_usable_regions(struct event_group *e, struct pmt_feature_g
198206
return usable_regions;
199207
}
200208

209+
static bool all_regions_have_sufficient_rmid(struct event_group *e, struct pmt_feature_group *p)
210+
{
211+
struct telemetry_region *tr;
212+
213+
for (int i = 0; i < p->count; i++) {
214+
if (!p->regions[i].addr)
215+
continue;
216+
tr = &p->regions[i];
217+
if (tr->num_rmids < e->num_rmid) {
218+
e->force_off = true;
219+
return false;
220+
}
221+
}
222+
223+
return true;
224+
}
225+
201226
static bool enable_events(struct event_group *e, struct pmt_feature_group *p)
202227
{
203228
struct rdt_resource *r = &rdt_resources_all[RDT_RESOURCE_PERF_PKG].r_resctrl;
@@ -209,6 +234,27 @@ static bool enable_events(struct event_group *e, struct pmt_feature_group *p)
209234
if (!group_has_usable_regions(e, p))
210235
return false;
211236

237+
/*
238+
* Only enable event group with insufficient RMIDs if the user requested
239+
* it from the kernel command line.
240+
*/
241+
if (!all_regions_have_sufficient_rmid(e, p) && !e->force_on) {
242+
pr_info("%s %s:0x%x monitoring not enabled due to insufficient RMIDs\n",
243+
r->name, e->pfname, e->guid);
244+
return false;
245+
}
246+
247+
for (int i = 0; i < p->count; i++) {
248+
if (!p->regions[i].addr)
249+
continue;
250+
/*
251+
* e->num_rmid only adjusted lower if user (via rdt= kernel
252+
* parameter) forces an event group with insufficient RMID
253+
* to be enabled.
254+
*/
255+
e->num_rmid = min(e->num_rmid, p->regions[i].num_rmids);
256+
}
257+
212258
for (int j = 0; j < e->num_events; j++) {
213259
if (!resctrl_enable_mon_event(e->evts[j].id, true,
214260
e->evts[j].bin_bits, &e->evts[j]))
@@ -219,6 +265,11 @@ static bool enable_events(struct event_group *e, struct pmt_feature_group *p)
219265
return false;
220266
}
221267

268+
if (r->mon.num_rmid)
269+
r->mon.num_rmid = min(r->mon.num_rmid, e->num_rmid);
270+
else
271+
r->mon.num_rmid = e->num_rmid;
272+
222273
return true;
223274
}
224275

fs/resctrl/rdtgroup.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1158,7 +1158,7 @@ static int rdt_num_rmids_show(struct kernfs_open_file *of,
11581158
{
11591159
struct rdt_resource *r = rdt_kn_parent_priv(of->kn);
11601160

1161-
seq_printf(seq, "%d\n", r->mon.num_rmid);
1161+
seq_printf(seq, "%u\n", r->mon.num_rmid);
11621162

11631163
return 0;
11641164
}

include/linux/resctrl.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,7 @@ enum resctrl_schema_fmt {
295295
* events of monitor groups created via mkdir.
296296
*/
297297
struct resctrl_mon {
298-
int num_rmid;
298+
u32 num_rmid;
299299
unsigned int mbm_cfg_mask;
300300
int num_mbm_cntrs;
301301
bool mbm_cntr_assignable;

0 commit comments

Comments
 (0)