Skip to content

Commit 46637d4

Browse files
rchatresuryasaimadhu
authored andcommitted
x86/resctrl: Maintain MBM counter width per resource
The original Memory Bandwidth Monitoring (MBM) architectural definition defines counters of up to 62 bits in the IA32_QM_CTR MSR, and the first-generation MBM implementation uses 24 bit counters. Software is required to poll at 1 second or faster to ensure that data is retrieved before a counter rollover occurs more than once under worst conditions. As system bandwidths scale the software requirement is maintained with the introduction of a per-resource enumerable MBM counter width. In preparation for supporting hardware with an enumerable MBM counter width the current globally static MBM counter width is moved to a per-resource MBM counter width. Currently initialized to 24 always to result in no functional change. In essence there is one function, mbm_overflow_count() that needs to know the counter width to handle rollovers. The static value used within mbm_overflow_count() will be replaced with a value discovered from the hardware. Support for learning the MBM counter width from hardware is added in the change that follows. Signed-off-by: Reinette Chatre <[email protected]> Signed-off-by: Borislav Petkov <[email protected]> Link: https://lkml.kernel.org/r/e36743b9800f16ce600f86b89127391f61261f23.1588715690.git.reinette.chatre@intel.com
1 parent 923f3a2 commit 46637d4

File tree

4 files changed

+24
-14
lines changed

4 files changed

+24
-14
lines changed

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

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -495,14 +495,16 @@ int rdtgroup_schemata_show(struct kernfs_open_file *of,
495495
return ret;
496496
}
497497

498-
void mon_event_read(struct rmid_read *rr, struct rdt_domain *d,
499-
struct rdtgroup *rdtgrp, int evtid, int first)
498+
void mon_event_read(struct rmid_read *rr, struct rdt_resource *r,
499+
struct rdt_domain *d, struct rdtgroup *rdtgrp,
500+
int evtid, int first)
500501
{
501502
/*
502503
* setup the parameters to send to the IPI to read the data.
503504
*/
504505
rr->rgrp = rdtgrp;
505506
rr->evtid = evtid;
507+
rr->r = r;
506508
rr->d = d;
507509
rr->val = 0;
508510
rr->first = first;
@@ -539,7 +541,7 @@ int rdtgroup_mondata_show(struct seq_file *m, void *arg)
539541
goto out;
540542
}
541543

542-
mon_event_read(&rr, d, rdtgrp, evtid, false);
544+
mon_event_read(&rr, r, d, rdtgrp, evtid, false);
543545

544546
if (rr.val & RMID_VAL_ERROR)
545547
seq_puts(m, "Error\n");

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ union mon_data_bits {
8787

8888
struct rmid_read {
8989
struct rdtgroup *rgrp;
90+
struct rdt_resource *r;
9091
struct rdt_domain *d;
9192
int evtid;
9293
bool first;
@@ -460,6 +461,7 @@ struct rdt_resource {
460461
struct list_head evt_list;
461462
int num_rmid;
462463
unsigned int mon_scale;
464+
unsigned int mbm_width;
463465
unsigned long fflags;
464466
};
465467

@@ -587,8 +589,9 @@ void rmdir_mondata_subdir_allrdtgrp(struct rdt_resource *r,
587589
unsigned int dom_id);
588590
void mkdir_mondata_subdir_allrdtgrp(struct rdt_resource *r,
589591
struct rdt_domain *d);
590-
void mon_event_read(struct rmid_read *rr, struct rdt_domain *d,
591-
struct rdtgroup *rdtgrp, int evtid, int first);
592+
void mon_event_read(struct rmid_read *rr, struct rdt_resource *r,
593+
struct rdt_domain *d, struct rdtgroup *rdtgrp,
594+
int evtid, int first);
592595
void mbm_setup_overflow_handler(struct rdt_domain *dom,
593596
unsigned long delay_ms);
594597
void mbm_handle_overflow(struct work_struct *work);

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

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -214,9 +214,9 @@ void free_rmid(u32 rmid)
214214
list_add_tail(&entry->list, &rmid_free_lru);
215215
}
216216

217-
static u64 mbm_overflow_count(u64 prev_msr, u64 cur_msr)
217+
static u64 mbm_overflow_count(u64 prev_msr, u64 cur_msr, unsigned int width)
218218
{
219-
u64 shift = 64 - MBM_CNTR_WIDTH, chunks;
219+
u64 shift = 64 - width, chunks;
220220

221221
chunks = (cur_msr << shift) - (prev_msr << shift);
222222
return chunks >>= shift;
@@ -256,7 +256,7 @@ static int __mon_event_count(u32 rmid, struct rmid_read *rr)
256256
return 0;
257257
}
258258

259-
chunks = mbm_overflow_count(m->prev_msr, tval);
259+
chunks = mbm_overflow_count(m->prev_msr, tval, rr->r->mbm_width);
260260
m->chunks += chunks;
261261
m->prev_msr = tval;
262262

@@ -278,7 +278,7 @@ static void mbm_bw_count(u32 rmid, struct rmid_read *rr)
278278
if (tval & (RMID_VAL_ERROR | RMID_VAL_UNAVAIL))
279279
return;
280280

281-
chunks = mbm_overflow_count(m->prev_bw_msr, tval);
281+
chunks = mbm_overflow_count(m->prev_bw_msr, tval, rr->r->mbm_width);
282282
m->chunks_bw += chunks;
283283
m->chunks = m->chunks_bw;
284284
cur_bw = (chunks * r->mon_scale) >> 20;
@@ -433,11 +433,12 @@ static void update_mba_bw(struct rdtgroup *rgrp, struct rdt_domain *dom_mbm)
433433
}
434434
}
435435

436-
static void mbm_update(struct rdt_domain *d, int rmid)
436+
static void mbm_update(struct rdt_resource *r, struct rdt_domain *d, int rmid)
437437
{
438438
struct rmid_read rr;
439439

440440
rr.first = false;
441+
rr.r = r;
441442
rr.d = d;
442443

443444
/*
@@ -510,23 +511,26 @@ void mbm_handle_overflow(struct work_struct *work)
510511
struct rdtgroup *prgrp, *crgrp;
511512
int cpu = smp_processor_id();
512513
struct list_head *head;
514+
struct rdt_resource *r;
513515
struct rdt_domain *d;
514516

515517
mutex_lock(&rdtgroup_mutex);
516518

517519
if (!static_branch_likely(&rdt_mon_enable_key))
518520
goto out_unlock;
519521

520-
d = get_domain_from_cpu(cpu, &rdt_resources_all[RDT_RESOURCE_L3]);
522+
r = &rdt_resources_all[RDT_RESOURCE_L3];
523+
524+
d = get_domain_from_cpu(cpu, r);
521525
if (!d)
522526
goto out_unlock;
523527

524528
list_for_each_entry(prgrp, &rdt_all_groups, rdtgroup_list) {
525-
mbm_update(d, prgrp->mon.rmid);
529+
mbm_update(r, d, prgrp->mon.rmid);
526530

527531
head = &prgrp->mon.crdtgrp_list;
528532
list_for_each_entry(crgrp, head, mon.crdtgrp_list)
529-
mbm_update(d, crgrp->mon.rmid);
533+
mbm_update(r, d, crgrp->mon.rmid);
530534

531535
if (is_mba_sc(NULL))
532536
update_mba_bw(prgrp, d);
@@ -619,6 +623,7 @@ int rdt_get_mon_l3_config(struct rdt_resource *r)
619623

620624
r->mon_scale = boot_cpu_data.x86_cache_occ_scale;
621625
r->num_rmid = boot_cpu_data.x86_cache_max_rmid + 1;
626+
r->mbm_width = MBM_CNTR_WIDTH;
622627

623628
/*
624629
* A reasonable upper limit on the max threshold is the number

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2472,7 +2472,7 @@ static int mkdir_mondata_subdir(struct kernfs_node *parent_kn,
24722472
goto out_destroy;
24732473

24742474
if (is_mbm_event(mevt->evtid))
2475-
mon_event_read(&rr, d, prgrp, mevt->evtid, true);
2475+
mon_event_read(&rr, r, d, prgrp, mevt->evtid, true);
24762476
}
24772477
kernfs_activate(kn);
24782478
return 0;

0 commit comments

Comments
 (0)