Skip to content

Commit 9bf9511

Browse files
committed
Merge tag 'x86_cache_updates_for_5.8' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 cache resource control updates from Borislav Petkov: "Add support for wider Memory Bandwidth Monitoring counters by querying their width from CPUID. As a prerequsite for that, streamline and unify the CPUID detection of the respective resource control attributes. By Reinette Chatre" * tag 'x86_cache_updates_for_5.8' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86/resctrl: Support wider MBM counters x86/resctrl: Support CPUID enumeration of MBM counter width x86/resctrl: Maintain MBM counter width per resource x86/resctrl: Query LLC monitoring properties once during boot x86/resctrl: Remove unnecessary RMID checks x86/cpu: Move resctrl CPUID code to resctrl/ x86/resctrl: Rename asm/resctrl_sched.h to asm/resctrl.h
2 parents ef34ba6 + 0c4d5ba commit 9bf9511

File tree

14 files changed

+91
-65
lines changed

14 files changed

+91
-65
lines changed

MAINTAINERS

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14269,7 +14269,7 @@ M: Reinette Chatre <[email protected]>
1426914269
1427014270
S: Supported
1427114271
F: Documentation/x86/resctrl*
14272-
F: arch/x86/include/asm/resctrl_sched.h
14272+
F: arch/x86/include/asm/resctrl.h
1427314273
F: arch/x86/kernel/cpu/resctrl/
1427414274
F: tools/testing/selftests/resctrl/
1427514275

arch/x86/include/asm/processor.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,9 +113,10 @@ struct cpuinfo_x86 {
113113
/* in KB - valid for CPUS which support this call: */
114114
unsigned int x86_cache_size;
115115
int x86_cache_alignment; /* In bytes */
116-
/* Cache QoS architectural values: */
116+
/* Cache QoS architectural values, valid only on the BSP: */
117117
int x86_cache_max_rmid; /* max index */
118118
int x86_cache_occ_scale; /* scale to bytes */
119+
int x86_cache_mbm_width_offset;
119120
int x86_power;
120121
unsigned long loops_per_jiffy;
121122
/* cpuid returned max cores value: */

arch/x86/include/asm/resctrl_sched.h renamed to arch/x86/include/asm/resctrl.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/* SPDX-License-Identifier: GPL-2.0 */
2-
#ifndef _ASM_X86_RESCTRL_SCHED_H
3-
#define _ASM_X86_RESCTRL_SCHED_H
2+
#ifndef _ASM_X86_RESCTRL_H
3+
#define _ASM_X86_RESCTRL_H
44

55
#ifdef CONFIG_X86_CPU_RESCTRL
66

@@ -84,10 +84,13 @@ static inline void resctrl_sched_in(void)
8484
__resctrl_sched_in();
8585
}
8686

87+
void resctrl_cpu_detect(struct cpuinfo_x86 *c);
88+
8789
#else
8890

8991
static inline void resctrl_sched_in(void) {}
92+
static inline void resctrl_cpu_detect(struct cpuinfo_x86 *c) {}
9093

9194
#endif /* CONFIG_X86_CPU_RESCTRL */
9295

93-
#endif /* _ASM_X86_RESCTRL_SCHED_H */
96+
#endif /* _ASM_X86_RESCTRL_H */

arch/x86/kernel/cpu/amd.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include <asm/pci-direct.h>
1919
#include <asm/delay.h>
2020
#include <asm/debugreg.h>
21+
#include <asm/resctrl.h>
2122

2223
#ifdef CONFIG_X86_64
2324
# include <asm/mmconfig.h>
@@ -597,6 +598,8 @@ static void bsp_init_amd(struct cpuinfo_x86 *c)
597598
x86_amd_ls_cfg_ssbd_mask = 1ULL << bit;
598599
}
599600
}
601+
602+
resctrl_cpu_detect(c);
600603
}
601604

602605
static void early_detect_mem_encrypt(struct cpuinfo_x86 *c)

arch/x86/kernel/cpu/common.c

Lines changed: 0 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -854,30 +854,6 @@ static void init_speculation_control(struct cpuinfo_x86 *c)
854854
}
855855
}
856856

857-
static void init_cqm(struct cpuinfo_x86 *c)
858-
{
859-
if (!cpu_has(c, X86_FEATURE_CQM_LLC)) {
860-
c->x86_cache_max_rmid = -1;
861-
c->x86_cache_occ_scale = -1;
862-
return;
863-
}
864-
865-
/* will be overridden if occupancy monitoring exists */
866-
c->x86_cache_max_rmid = cpuid_ebx(0xf);
867-
868-
if (cpu_has(c, X86_FEATURE_CQM_OCCUP_LLC) ||
869-
cpu_has(c, X86_FEATURE_CQM_MBM_TOTAL) ||
870-
cpu_has(c, X86_FEATURE_CQM_MBM_LOCAL)) {
871-
u32 eax, ebx, ecx, edx;
872-
873-
/* QoS sub-leaf, EAX=0Fh, ECX=1 */
874-
cpuid_count(0xf, 1, &eax, &ebx, &ecx, &edx);
875-
876-
c->x86_cache_max_rmid = ecx;
877-
c->x86_cache_occ_scale = ebx;
878-
}
879-
}
880-
881857
void get_cpu_cap(struct cpuinfo_x86 *c)
882858
{
883859
u32 eax, ebx, ecx, edx;
@@ -945,7 +921,6 @@ void get_cpu_cap(struct cpuinfo_x86 *c)
945921

946922
init_scattered_cpuid_features(c);
947923
init_speculation_control(c);
948-
init_cqm(c);
949924

950925
/*
951926
* Clear/Set all flags overridden by options, after probe.
@@ -1377,20 +1352,6 @@ static void generic_identify(struct cpuinfo_x86 *c)
13771352
#endif
13781353
}
13791354

1380-
static void x86_init_cache_qos(struct cpuinfo_x86 *c)
1381-
{
1382-
/*
1383-
* The heavy lifting of max_rmid and cache_occ_scale are handled
1384-
* in get_cpu_cap(). Here we just set the max_rmid for the boot_cpu
1385-
* in case CQM bits really aren't there in this CPU.
1386-
*/
1387-
if (c != &boot_cpu_data) {
1388-
boot_cpu_data.x86_cache_max_rmid =
1389-
min(boot_cpu_data.x86_cache_max_rmid,
1390-
c->x86_cache_max_rmid);
1391-
}
1392-
}
1393-
13941355
/*
13951356
* Validate that ACPI/mptables have the same information about the
13961357
* effective APIC id and update the package map.
@@ -1503,7 +1464,6 @@ static void identify_cpu(struct cpuinfo_x86 *c)
15031464
#endif
15041465

15051466
x86_init_rdrand(c);
1506-
x86_init_cache_qos(c);
15071467
setup_pku(c);
15081468

15091469
/*

arch/x86/kernel/cpu/intel.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include <asm/cpu_device_id.h>
2323
#include <asm/cmdline.h>
2424
#include <asm/traps.h>
25+
#include <asm/resctrl.h>
2526

2627
#ifdef CONFIG_X86_64
2728
#include <linux/topology.h>
@@ -322,6 +323,11 @@ static void early_init_intel(struct cpuinfo_x86 *c)
322323
detect_ht_early(c);
323324
}
324325

326+
static void bsp_init_intel(struct cpuinfo_x86 *c)
327+
{
328+
resctrl_cpu_detect(c);
329+
}
330+
325331
#ifdef CONFIG_X86_32
326332
/*
327333
* Early probe support logic for ppro memory erratum #50
@@ -961,6 +967,7 @@ static const struct cpu_dev intel_cpu_dev = {
961967
#endif
962968
.c_detect_tlb = intel_detect_tlb,
963969
.c_early_init = early_init_intel,
970+
.c_bsp_init = bsp_init_intel,
964971
.c_init = init_intel,
965972
.c_x86_vendor = X86_VENDOR_INTEL,
966973
};

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

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
#include <linux/cpuhotplug.h>
2323

2424
#include <asm/intel-family.h>
25-
#include <asm/resctrl_sched.h>
25+
#include <asm/resctrl.h>
2626
#include "internal.h"
2727

2828
/* Mutex to protect rdtgroup access. */
@@ -958,6 +958,36 @@ static __init void rdt_init_res_defs(void)
958958

959959
static enum cpuhp_state rdt_online;
960960

961+
/* Runs once on the BSP during boot. */
962+
void resctrl_cpu_detect(struct cpuinfo_x86 *c)
963+
{
964+
if (!cpu_has(c, X86_FEATURE_CQM_LLC)) {
965+
c->x86_cache_max_rmid = -1;
966+
c->x86_cache_occ_scale = -1;
967+
c->x86_cache_mbm_width_offset = -1;
968+
return;
969+
}
970+
971+
/* will be overridden if occupancy monitoring exists */
972+
c->x86_cache_max_rmid = cpuid_ebx(0xf);
973+
974+
if (cpu_has(c, X86_FEATURE_CQM_OCCUP_LLC) ||
975+
cpu_has(c, X86_FEATURE_CQM_MBM_TOTAL) ||
976+
cpu_has(c, X86_FEATURE_CQM_MBM_LOCAL)) {
977+
u32 eax, ebx, ecx, edx;
978+
979+
/* QoS sub-leaf, EAX=0Fh, ECX=1 */
980+
cpuid_count(0xf, 1, &eax, &ebx, &ecx, &edx);
981+
982+
c->x86_cache_max_rmid = ecx;
983+
c->x86_cache_occ_scale = ebx;
984+
if (c->x86_vendor == X86_VENDOR_INTEL)
985+
c->x86_cache_mbm_width_offset = eax & 0xff;
986+
else
987+
c->x86_cache_mbm_width_offset = -1;
988+
}
989+
}
990+
961991
static int __init resctrl_late_init(void)
962992
{
963993
struct rdt_resource *r;

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: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131

3232
#define CQM_LIMBOCHECK_INTERVAL 1000
3333

34-
#define MBM_CNTR_WIDTH 24
34+
#define MBM_CNTR_WIDTH_BASE 24
3535
#define MBM_OVERFLOW_INTERVAL 1000
3636
#define MAX_MBA_BW 100u
3737
#define MBA_IS_LINEAR 0x4
@@ -40,6 +40,12 @@
4040

4141
#define RMID_VAL_ERROR BIT_ULL(63)
4242
#define RMID_VAL_UNAVAIL BIT_ULL(62)
43+
/*
44+
* With the above fields in use 62 bits remain in MSR_IA32_QM_CTR for
45+
* data to be returned. The counter width is discovered from the hardware
46+
* as an offset from MBM_CNTR_WIDTH_BASE.
47+
*/
48+
#define MBM_CNTR_WIDTH_OFFSET_MAX (62 - MBM_CNTR_WIDTH_BASE)
4349

4450

4551
struct rdt_fs_context {
@@ -87,6 +93,7 @@ union mon_data_bits {
8793

8894
struct rmid_read {
8995
struct rdtgroup *rgrp;
96+
struct rdt_resource *r;
9097
struct rdt_domain *d;
9198
int evtid;
9299
bool first;
@@ -460,6 +467,7 @@ struct rdt_resource {
460467
struct list_head evt_list;
461468
int num_rmid;
462469
unsigned int mon_scale;
470+
unsigned int mbm_width;
463471
unsigned long fflags;
464472
};
465473

@@ -587,8 +595,9 @@ void rmdir_mondata_subdir_allrdtgrp(struct rdt_resource *r,
587595
unsigned int dom_id);
588596
void mkdir_mondata_subdir_allrdtgrp(struct rdt_resource *r,
589597
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);
598+
void mon_event_read(struct rmid_read *rr, struct rdt_resource *r,
599+
struct rdt_domain *d, struct rdtgroup *rdtgrp,
600+
int evtid, int first);
592601
void mbm_setup_overflow_handler(struct rdt_domain *dom,
593602
unsigned long delay_ms);
594603
void mbm_handle_overflow(struct work_struct *work);

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

Lines changed: 19 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);
@@ -614,11 +618,18 @@ static void l3_mon_evt_init(struct rdt_resource *r)
614618

615619
int rdt_get_mon_l3_config(struct rdt_resource *r)
616620
{
621+
unsigned int mbm_offset = boot_cpu_data.x86_cache_mbm_width_offset;
617622
unsigned int cl_size = boot_cpu_data.x86_cache_size;
618623
int ret;
619624

620625
r->mon_scale = boot_cpu_data.x86_cache_occ_scale;
621626
r->num_rmid = boot_cpu_data.x86_cache_max_rmid + 1;
627+
r->mbm_width = MBM_CNTR_WIDTH_BASE;
628+
629+
if (mbm_offset > 0 && mbm_offset <= MBM_CNTR_WIDTH_OFFSET_MAX)
630+
r->mbm_width += mbm_offset;
631+
else if (mbm_offset > MBM_CNTR_WIDTH_OFFSET_MAX)
632+
pr_warn("Ignoring impossible MBM counter offset\n");
622633

623634
/*
624635
* A reasonable upper limit on the max threshold is the number

0 commit comments

Comments
 (0)