Skip to content

Commit 4d044c5

Browse files
James Morsesuryasaimadhu
authored andcommitted
x86/resctrl: Abstract __rmid_read()
__rmid_read() selects the specified eventid and returns the counter value from the MSR. The error handling is architecture specific, and handled by the callers, rdtgroup_mondata_show() and __mon_event_count(). Error handling should be handled by architecture specific code, as a different architecture may have different requirements. MPAM's counters can report that they are 'not ready', requiring a second read after a short delay. This should be hidden from resctrl. Make __rmid_read() the architecture specific function for reading a counter. Rename it resctrl_arch_rmid_read() and move the error handling into it. A read from a counter that hardware supports but resctrl does not now returns -EINVAL instead of -EIO from the default case in __mon_event_count(). It isn't possible for user-space to see this change as resctrl doesn't expose counters it doesn't support. Signed-off-by: James Morse <[email protected]> Signed-off-by: Borislav Petkov <[email protected]> Reviewed-by: Jamie Iles <[email protected]> Reviewed-by: Shaopeng Tan <[email protected]> Reviewed-by: Reinette Chatre <[email protected]> Tested-by: Xin Hao <[email protected]> Tested-by: Shaopeng Tan <[email protected]> Tested-by: Cristian Marussi <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent fea62d3 commit 4d044c5

File tree

4 files changed

+43
-25
lines changed

4 files changed

+43
-25
lines changed

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -579,9 +579,9 @@ int rdtgroup_mondata_show(struct seq_file *m, void *arg)
579579

580580
mon_event_read(&rr, r, d, rdtgrp, evtid, false);
581581

582-
if (rr.val & RMID_VAL_ERROR)
582+
if (rr.err == -EIO)
583583
seq_puts(m, "Error\n");
584-
else if (rr.val & RMID_VAL_UNAVAIL)
584+
else if (rr.err == -EINVAL)
585585
seq_puts(m, "Unavailable\n");
586586
else
587587
seq_printf(m, "%llu\n", rr.val * hw_res->mon_scale);

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ struct rmid_read {
9494
struct rdt_domain *d;
9595
enum resctrl_event_id evtid;
9696
bool first;
97+
int err;
9798
u64 val;
9899
};
99100

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

Lines changed: 39 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -167,9 +167,9 @@ void resctrl_arch_reset_rmid(struct rdt_resource *r, struct rdt_domain *d,
167167
memset(am, 0, sizeof(*am));
168168
}
169169

170-
static u64 __rmid_read(u32 rmid, enum resctrl_event_id eventid)
170+
int resctrl_arch_rmid_read(u32 rmid, enum resctrl_event_id eventid, u64 *val)
171171
{
172-
u64 val;
172+
u64 msr_val;
173173

174174
/*
175175
* As per the SDM, when IA32_QM_EVTSEL.EvtID (bits 7:0) is configured
@@ -180,14 +180,24 @@ static u64 __rmid_read(u32 rmid, enum resctrl_event_id eventid)
180180
* are error bits.
181181
*/
182182
wrmsr(MSR_IA32_QM_EVTSEL, eventid, rmid);
183-
rdmsrl(MSR_IA32_QM_CTR, val);
183+
rdmsrl(MSR_IA32_QM_CTR, msr_val);
184184

185-
return val;
185+
if (msr_val & RMID_VAL_ERROR)
186+
return -EIO;
187+
if (msr_val & RMID_VAL_UNAVAIL)
188+
return -EINVAL;
189+
190+
*val = msr_val;
191+
192+
return 0;
186193
}
187194

188195
static bool rmid_dirty(struct rmid_entry *entry)
189196
{
190-
u64 val = __rmid_read(entry->rmid, QOS_L3_OCCUP_EVENT_ID);
197+
u64 val = 0;
198+
199+
if (resctrl_arch_rmid_read(entry->rmid, QOS_L3_OCCUP_EVENT_ID, &val))
200+
return true;
191201

192202
return val >= resctrl_cqm_threshold;
193203
}
@@ -259,17 +269,19 @@ static void add_rmid_to_limbo(struct rmid_entry *entry)
259269
{
260270
struct rdt_resource *r;
261271
struct rdt_domain *d;
262-
int cpu;
263-
u64 val;
272+
int cpu, err;
273+
u64 val = 0;
264274

265275
r = &rdt_resources_all[RDT_RESOURCE_L3].r_resctrl;
266276

267277
entry->busy = 0;
268278
cpu = get_cpu();
269279
list_for_each_entry(d, &r->domains, list) {
270280
if (cpumask_test_cpu(cpu, &d->cpu_mask)) {
271-
val = __rmid_read(entry->rmid, QOS_L3_OCCUP_EVENT_ID);
272-
if (val <= resctrl_cqm_threshold)
281+
err = resctrl_arch_rmid_read(entry->rmid,
282+
QOS_L3_OCCUP_EVENT_ID,
283+
&val);
284+
if (err || val <= resctrl_cqm_threshold)
273285
continue;
274286
}
275287

@@ -315,19 +327,19 @@ static u64 mbm_overflow_count(u64 prev_msr, u64 cur_msr, unsigned int width)
315327
return chunks >> shift;
316328
}
317329

318-
static u64 __mon_event_count(u32 rmid, struct rmid_read *rr)
330+
static int __mon_event_count(u32 rmid, struct rmid_read *rr)
319331
{
320332
struct rdt_hw_resource *hw_res = resctrl_to_arch_res(rr->r);
321333
struct mbm_state *m;
322-
u64 chunks, tval;
334+
u64 chunks, tval = 0;
323335

324336
if (rr->first)
325337
resctrl_arch_reset_rmid(rr->r, rr->d, rmid, rr->evtid);
326338

327-
tval = __rmid_read(rmid, rr->evtid);
328-
if (tval & (RMID_VAL_ERROR | RMID_VAL_UNAVAIL)) {
329-
return tval;
330-
}
339+
rr->err = resctrl_arch_rmid_read(rmid, rr->evtid, &tval);
340+
if (rr->err)
341+
return rr->err;
342+
331343
switch (rr->evtid) {
332344
case QOS_L3_OCCUP_EVENT_ID:
333345
rr->val += tval;
@@ -341,9 +353,9 @@ static u64 __mon_event_count(u32 rmid, struct rmid_read *rr)
341353
default:
342354
/*
343355
* Code would never reach here because an invalid
344-
* event id would fail the __rmid_read.
356+
* event id would fail in resctrl_arch_rmid_read().
345357
*/
346-
return RMID_VAL_ERROR;
358+
return -EINVAL;
347359
}
348360

349361
if (rr->first) {
@@ -399,11 +411,11 @@ void mon_event_count(void *info)
399411
struct rdtgroup *rdtgrp, *entry;
400412
struct rmid_read *rr = info;
401413
struct list_head *head;
402-
u64 ret_val;
414+
int ret;
403415

404416
rdtgrp = rr->rgrp;
405417

406-
ret_val = __mon_event_count(rdtgrp->mon.rmid, rr);
418+
ret = __mon_event_count(rdtgrp->mon.rmid, rr);
407419

408420
/*
409421
* For Ctrl groups read data from child monitor groups and
@@ -415,13 +427,17 @@ void mon_event_count(void *info)
415427
if (rdtgrp->type == RDTCTRL_GROUP) {
416428
list_for_each_entry(entry, head, mon.crdtgrp_list) {
417429
if (__mon_event_count(entry->mon.rmid, rr) == 0)
418-
ret_val = 0;
430+
ret = 0;
419431
}
420432
}
421433

422-
/* Report error if none of rmid_reads are successful */
423-
if (ret_val)
424-
rr->val = ret_val;
434+
/*
435+
* __mon_event_count() calls for newly created monitor groups may
436+
* report -EINVAL/Unavailable if the monitor hasn't seen any traffic.
437+
* Discard error if any of the monitor event reads succeeded.
438+
*/
439+
if (ret == 0)
440+
rr->err = 0;
425441
}
426442

427443
/*

include/linux/resctrl.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,7 @@ u32 resctrl_arch_get_config(struct rdt_resource *r, struct rdt_domain *d,
219219
u32 closid, enum resctrl_conf_type type);
220220
int resctrl_online_domain(struct rdt_resource *r, struct rdt_domain *d);
221221
void resctrl_offline_domain(struct rdt_resource *r, struct rdt_domain *d);
222+
int resctrl_arch_rmid_read(u32 rmid, enum resctrl_event_id eventid, u64 *res);
222223

223224
/**
224225
* resctrl_arch_reset_rmid() - Reset any private state associated with rmid

0 commit comments

Comments
 (0)