Skip to content

Commit 6b10cf7

Browse files
aeglbp3tk0v
authored andcommitted
x86,fs/resctrl: Use struct rdt_domain_hdr when reading counters
Convert the whole call sequence from mon_event_read() to resctrl_arch_rmid_read() to pass resource independent struct rdt_domain_hdr instead of an L3 specific domain structure to prepare for monitoring events in other resources. This additional layer of indirection obscures which aspects of event counting depend on a valid domain. Event initialization, support for assignable counters, and normal event counting implicitly depend on a valid domain while summing of domains does not. Split summing domains from the core event counting handling to make their respective dependencies obvious. 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 ad5c2ff commit 6b10cf7

5 files changed

Lines changed: 78 additions & 50 deletions

File tree

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

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -238,19 +238,25 @@ static u64 get_corrected_val(struct rdt_resource *r, struct rdt_mon_domain *d,
238238
return chunks * hw_res->mon_scale;
239239
}
240240

241-
int resctrl_arch_rmid_read(struct rdt_resource *r, struct rdt_mon_domain *d,
241+
int resctrl_arch_rmid_read(struct rdt_resource *r, struct rdt_domain_hdr *hdr,
242242
u32 unused, u32 rmid, enum resctrl_event_id eventid,
243243
u64 *val, void *ignored)
244244
{
245-
struct rdt_hw_mon_domain *hw_dom = resctrl_to_arch_mon_dom(d);
246-
int cpu = cpumask_any(&d->hdr.cpu_mask);
245+
struct rdt_hw_mon_domain *hw_dom;
247246
struct arch_mbm_state *am;
247+
struct rdt_mon_domain *d;
248248
u64 msr_val;
249249
u32 prmid;
250+
int cpu;
250251
int ret;
251252

252253
resctrl_arch_rmid_read_context_check();
254+
if (!domain_header_is_valid(hdr, RESCTRL_MON_DOMAIN, RDT_RESOURCE_L3))
255+
return -EINVAL;
253256

257+
d = container_of(hdr, struct rdt_mon_domain, hdr);
258+
hw_dom = resctrl_to_arch_mon_dom(d);
259+
cpu = cpumask_any(&hdr->cpu_mask);
254260
prmid = logical_rmid_to_physical_rmid(cpu, rmid);
255261
ret = __rmid_read_phys(prmid, eventid, &msr_val);
256262

fs/resctrl/ctrlmondata.c

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -554,25 +554,18 @@ void mon_event_read(struct rmid_read *rr, struct rdt_resource *r,
554554
struct rdt_domain_hdr *hdr, struct rdtgroup *rdtgrp,
555555
cpumask_t *cpumask, int evtid, int first)
556556
{
557-
struct rdt_mon_domain *d = NULL;
558557
int cpu;
559558

560559
/* When picking a CPU from cpu_mask, ensure it can't race with cpuhp */
561560
lockdep_assert_cpus_held();
562561

563-
if (hdr) {
564-
if (!domain_header_is_valid(hdr, RESCTRL_MON_DOMAIN, RDT_RESOURCE_L3))
565-
return;
566-
d = container_of(hdr, struct rdt_mon_domain, hdr);
567-
}
568-
569562
/*
570563
* Setup the parameters to pass to mon_event_count() to read the data.
571564
*/
572565
rr->rgrp = rdtgrp;
573566
rr->evtid = evtid;
574567
rr->r = r;
575-
rr->d = d;
568+
rr->hdr = hdr;
576569
rr->first = first;
577570
if (resctrl_arch_mbm_cntr_assign_enabled(r) &&
578571
resctrl_is_mbm_event(evtid)) {

fs/resctrl/internal.h

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -106,24 +106,26 @@ struct mon_data {
106106
* resource group then its event count is summed with the count from all
107107
* its child resource groups.
108108
* @r: Resource describing the properties of the event being read.
109-
* @d: Domain that the counter should be read from. If NULL then sum all
110-
* domains in @r sharing L3 @ci.id
109+
* @hdr: Header of domain that the counter should be read from. If NULL then
110+
* sum all domains in @r sharing L3 @ci.id
111111
* @evtid: Which monitor event to read.
112112
* @first: Initialize MBM counter when true.
113-
* @ci: Cacheinfo for L3. Only set when @d is NULL. Used when summing domains.
113+
* @ci: Cacheinfo for L3. Only set when @hdr is NULL. Used when summing
114+
* domains.
114115
* @is_mbm_cntr: true if "mbm_event" counter assignment mode is enabled and it
115116
* is an MBM event.
116117
* @err: Error encountered when reading counter.
117-
* @val: Returned value of event counter. If @rgrp is a parent resource group,
118-
* @val includes the sum of event counts from its child resource groups.
119-
* If @d is NULL, @val includes the sum of all domains in @r sharing @ci.id,
120-
* (summed across child resource groups if @rgrp is a parent resource group).
118+
* @val: Returned value of event counter. If @rgrp is a parent resource
119+
* group, @val includes the sum of event counts from its child
120+
* resource groups. If @hdr is NULL, @val includes the sum of all
121+
* domains in @r sharing @ci.id, (summed across child resource groups
122+
* if @rgrp is a parent resource group).
121123
* @arch_mon_ctx: Hardware monitor allocated for this read request (MPAM only).
122124
*/
123125
struct rmid_read {
124126
struct rdtgroup *rgrp;
125127
struct rdt_resource *r;
126-
struct rdt_mon_domain *d;
128+
struct rdt_domain_hdr *hdr;
127129
enum resctrl_event_id evtid;
128130
bool first;
129131
struct cacheinfo *ci;

fs/resctrl/monitor.c

Lines changed: 56 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ void __check_limbo(struct rdt_mon_domain *d, bool force_free)
159159
break;
160160

161161
entry = __rmid_entry(idx);
162-
if (resctrl_arch_rmid_read(r, d, entry->closid, entry->rmid,
162+
if (resctrl_arch_rmid_read(r, &d->hdr, entry->closid, entry->rmid,
163163
QOS_L3_OCCUP_EVENT_ID, &val,
164164
arch_mon_ctx)) {
165165
rmid_dirty = true;
@@ -421,11 +421,16 @@ static int __l3_mon_event_count(struct rdtgroup *rdtgrp, struct rmid_read *rr)
421421
struct rdt_mon_domain *d;
422422
int cntr_id = -ENOENT;
423423
struct mbm_state *m;
424-
int err, ret;
425424
u64 tval = 0;
426425

426+
if (!domain_header_is_valid(rr->hdr, RESCTRL_MON_DOMAIN, RDT_RESOURCE_L3)) {
427+
rr->err = -EIO;
428+
return -EINVAL;
429+
}
430+
d = container_of(rr->hdr, struct rdt_mon_domain, hdr);
431+
427432
if (rr->is_mbm_cntr) {
428-
cntr_id = mbm_cntr_get(rr->r, rr->d, rdtgrp, rr->evtid);
433+
cntr_id = mbm_cntr_get(rr->r, d, rdtgrp, rr->evtid);
429434
if (cntr_id < 0) {
430435
rr->err = -ENOENT;
431436
return -EINVAL;
@@ -434,31 +439,50 @@ static int __l3_mon_event_count(struct rdtgroup *rdtgrp, struct rmid_read *rr)
434439

435440
if (rr->first) {
436441
if (rr->is_mbm_cntr)
437-
resctrl_arch_reset_cntr(rr->r, rr->d, closid, rmid, cntr_id, rr->evtid);
442+
resctrl_arch_reset_cntr(rr->r, d, closid, rmid, cntr_id, rr->evtid);
438443
else
439-
resctrl_arch_reset_rmid(rr->r, rr->d, closid, rmid, rr->evtid);
440-
m = get_mbm_state(rr->d, closid, rmid, rr->evtid);
444+
resctrl_arch_reset_rmid(rr->r, d, closid, rmid, rr->evtid);
445+
m = get_mbm_state(d, closid, rmid, rr->evtid);
441446
if (m)
442447
memset(m, 0, sizeof(struct mbm_state));
443448
return 0;
444449
}
445450

446-
if (rr->d) {
447-
/* Reading a single domain, must be on a CPU in that domain. */
448-
if (!cpumask_test_cpu(cpu, &rr->d->hdr.cpu_mask))
449-
return -EINVAL;
450-
if (rr->is_mbm_cntr)
451-
rr->err = resctrl_arch_cntr_read(rr->r, rr->d, closid, rmid, cntr_id,
452-
rr->evtid, &tval);
453-
else
454-
rr->err = resctrl_arch_rmid_read(rr->r, rr->d, closid, rmid,
455-
rr->evtid, &tval, rr->arch_mon_ctx);
456-
if (rr->err)
457-
return rr->err;
451+
/* Reading a single domain, must be on a CPU in that domain. */
452+
if (!cpumask_test_cpu(cpu, &d->hdr.cpu_mask))
453+
return -EINVAL;
454+
if (rr->is_mbm_cntr)
455+
rr->err = resctrl_arch_cntr_read(rr->r, d, closid, rmid, cntr_id,
456+
rr->evtid, &tval);
457+
else
458+
rr->err = resctrl_arch_rmid_read(rr->r, rr->hdr, closid, rmid,
459+
rr->evtid, &tval, rr->arch_mon_ctx);
460+
if (rr->err)
461+
return rr->err;
458462

459-
rr->val += tval;
463+
rr->val += tval;
460464

461-
return 0;
465+
return 0;
466+
}
467+
468+
static int __l3_mon_event_count_sum(struct rdtgroup *rdtgrp, struct rmid_read *rr)
469+
{
470+
int cpu = smp_processor_id();
471+
u32 closid = rdtgrp->closid;
472+
u32 rmid = rdtgrp->mon.rmid;
473+
struct rdt_mon_domain *d;
474+
u64 tval = 0;
475+
int err, ret;
476+
477+
/*
478+
* Summing across domains is only done for systems that implement
479+
* Sub-NUMA Cluster. There is no overlap with systems that support
480+
* assignable counters.
481+
*/
482+
if (rr->is_mbm_cntr) {
483+
pr_warn_once("Summing domains using assignable counters is not supported\n");
484+
rr->err = -EINVAL;
485+
return -EINVAL;
462486
}
463487

464488
/* Summing domains that share a cache, must be on a CPU for that cache. */
@@ -476,12 +500,8 @@ static int __l3_mon_event_count(struct rdtgroup *rdtgrp, struct rmid_read *rr)
476500
list_for_each_entry(d, &rr->r->mon_domains, hdr.list) {
477501
if (d->ci_id != rr->ci->id)
478502
continue;
479-
if (rr->is_mbm_cntr)
480-
err = resctrl_arch_cntr_read(rr->r, d, closid, rmid, cntr_id,
481-
rr->evtid, &tval);
482-
else
483-
err = resctrl_arch_rmid_read(rr->r, d, closid, rmid,
484-
rr->evtid, &tval, rr->arch_mon_ctx);
503+
err = resctrl_arch_rmid_read(rr->r, &d->hdr, closid, rmid,
504+
rr->evtid, &tval, rr->arch_mon_ctx);
485505
if (!err) {
486506
rr->val += tval;
487507
ret = 0;
@@ -498,7 +518,10 @@ static int __mon_event_count(struct rdtgroup *rdtgrp, struct rmid_read *rr)
498518
{
499519
switch (rr->r->rid) {
500520
case RDT_RESOURCE_L3:
501-
return __l3_mon_event_count(rdtgrp, rr);
521+
if (rr->hdr)
522+
return __l3_mon_event_count(rdtgrp, rr);
523+
else
524+
return __l3_mon_event_count_sum(rdtgrp, rr);
502525
default:
503526
rr->err = -EINVAL;
504527
return -EINVAL;
@@ -522,9 +545,13 @@ static void mbm_bw_count(struct rdtgroup *rdtgrp, struct rmid_read *rr)
522545
u64 cur_bw, bytes, cur_bytes;
523546
u32 closid = rdtgrp->closid;
524547
u32 rmid = rdtgrp->mon.rmid;
548+
struct rdt_mon_domain *d;
525549
struct mbm_state *m;
526550

527-
m = get_mbm_state(rr->d, closid, rmid, rr->evtid);
551+
if (!domain_header_is_valid(rr->hdr, RESCTRL_MON_DOMAIN, RDT_RESOURCE_L3))
552+
return;
553+
d = container_of(rr->hdr, struct rdt_mon_domain, hdr);
554+
m = get_mbm_state(d, closid, rmid, rr->evtid);
528555
if (WARN_ON_ONCE(!m))
529556
return;
530557

@@ -697,7 +724,7 @@ static void mbm_update_one_event(struct rdt_resource *r, struct rdt_mon_domain *
697724
struct rmid_read rr = {0};
698725

699726
rr.r = r;
700-
rr.d = d;
727+
rr.hdr = &d->hdr;
701728
rr.evtid = evtid;
702729
if (resctrl_arch_mbm_cntr_assign_enabled(r)) {
703730
rr.is_mbm_cntr = true;

include/linux/resctrl.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -517,7 +517,7 @@ void resctrl_offline_cpu(unsigned int cpu);
517517
* resctrl_arch_rmid_read() - Read the eventid counter corresponding to rmid
518518
* for this resource and domain.
519519
* @r: resource that the counter should be read from.
520-
* @d: domain that the counter should be read from.
520+
* @hdr: Header of domain that the counter should be read from.
521521
* @closid: closid that matches the rmid. Depending on the architecture, the
522522
* counter may match traffic of both @closid and @rmid, or @rmid
523523
* only.
@@ -538,7 +538,7 @@ void resctrl_offline_cpu(unsigned int cpu);
538538
* Return:
539539
* 0 on success, or -EIO, -EINVAL etc on error.
540540
*/
541-
int resctrl_arch_rmid_read(struct rdt_resource *r, struct rdt_mon_domain *d,
541+
int resctrl_arch_rmid_read(struct rdt_resource *r, struct rdt_domain_hdr *hdr,
542542
u32 closid, u32 rmid, enum resctrl_event_id eventid,
543543
u64 *val, void *arch_mon_ctx);
544544

0 commit comments

Comments
 (0)