Skip to content

Commit 3357d1d

Browse files
committed
Merge tag 'x86_cache_for_v6.14_rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 resource control updates from Borislav Petkov: - Extend resctrl with the capability of total memory bandwidth monitoring, thus accomodating systems which support only total but not local memory bandwidth monitoring. Add the respective new mount options - The usual cleanups * tag 'x86_cache_for_v6.14_rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86/resctrl: Document the new "mba_MBps_event" file x86/resctrl: Add write option to "mba_MBps_event" file x86/resctrl: Add "mba_MBps_event" file to CTRL_MON directories x86/resctrl: Make mba_sc use total bandwidth if local is not supported x86/resctrl: Compute memory bandwidth for all supported events x86/resctrl: Modify update_mba_bw() to use per CTRL_MON group event x86/resctrl: Prepare for per-CTRL_MON group mba_MBps control x86/resctrl: Introduce resctrl_file_fflags_init() to initialize fflags x86/resctrl: Use kthread_run_on_cpu()
2 parents d80825e + faf6ef6 commit 3357d1d

File tree

7 files changed

+178
-87
lines changed

7 files changed

+178
-87
lines changed

Documentation/arch/x86/resctrl.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,16 @@ When monitoring is enabled all MON groups will also contain:
384384
Available only with debug option. The identifier used by hardware
385385
for the monitor group. On x86 this is the RMID.
386386

387+
When the "mba_MBps" mount option is used all CTRL_MON groups will also contain:
388+
389+
"mba_MBps_event":
390+
Reading this file shows which memory bandwidth event is used
391+
as input to the software feedback loop that keeps memory bandwidth
392+
below the value specified in the schemata file. Writing the
393+
name of one of the supported memory bandwidth events found in
394+
/sys/fs/resctrl/info/L3_MON/mon_features changes the input
395+
event.
396+
387397
Resource allocation rules
388398
-------------------------
389399

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

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,9 @@ static __init bool __get_mem_config_intel(struct rdt_resource *r)
234234
r->membw.throttle_mode = THREAD_THROTTLE_PER_THREAD;
235235
else
236236
r->membw.throttle_mode = THREAD_THROTTLE_MAX;
237-
thread_throttle_mode_init();
237+
238+
resctrl_file_fflags_init("thread_throttle_mode",
239+
RFTYPE_CTRL_INFO | RFTYPE_RES_MB);
238240

239241
r->alloc_capable = true;
240242

@@ -961,6 +963,11 @@ static __init bool get_rdt_mon_resources(void)
961963
if (!rdt_mon_features)
962964
return false;
963965

966+
if (is_mbm_local_enabled())
967+
mba_mbps_default_event = QOS_L3_MBM_LOCAL_EVENT_ID;
968+
else if (is_mbm_total_enabled())
969+
mba_mbps_default_event = QOS_L3_MBM_TOTAL_EVENT_ID;
970+
964971
return !rdt_get_mon_l3_config(r);
965972
}
966973

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

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -518,6 +518,76 @@ static int smp_mon_event_count(void *arg)
518518
return 0;
519519
}
520520

521+
ssize_t rdtgroup_mba_mbps_event_write(struct kernfs_open_file *of,
522+
char *buf, size_t nbytes, loff_t off)
523+
{
524+
struct rdtgroup *rdtgrp;
525+
int ret = 0;
526+
527+
/* Valid input requires a trailing newline */
528+
if (nbytes == 0 || buf[nbytes - 1] != '\n')
529+
return -EINVAL;
530+
buf[nbytes - 1] = '\0';
531+
532+
rdtgrp = rdtgroup_kn_lock_live(of->kn);
533+
if (!rdtgrp) {
534+
rdtgroup_kn_unlock(of->kn);
535+
return -ENOENT;
536+
}
537+
rdt_last_cmd_clear();
538+
539+
if (!strcmp(buf, "mbm_local_bytes")) {
540+
if (is_mbm_local_enabled())
541+
rdtgrp->mba_mbps_event = QOS_L3_MBM_LOCAL_EVENT_ID;
542+
else
543+
ret = -EINVAL;
544+
} else if (!strcmp(buf, "mbm_total_bytes")) {
545+
if (is_mbm_total_enabled())
546+
rdtgrp->mba_mbps_event = QOS_L3_MBM_TOTAL_EVENT_ID;
547+
else
548+
ret = -EINVAL;
549+
} else {
550+
ret = -EINVAL;
551+
}
552+
553+
if (ret)
554+
rdt_last_cmd_printf("Unsupported event id '%s'\n", buf);
555+
556+
rdtgroup_kn_unlock(of->kn);
557+
558+
return ret ?: nbytes;
559+
}
560+
561+
int rdtgroup_mba_mbps_event_show(struct kernfs_open_file *of,
562+
struct seq_file *s, void *v)
563+
{
564+
struct rdtgroup *rdtgrp;
565+
int ret = 0;
566+
567+
rdtgrp = rdtgroup_kn_lock_live(of->kn);
568+
569+
if (rdtgrp) {
570+
switch (rdtgrp->mba_mbps_event) {
571+
case QOS_L3_MBM_LOCAL_EVENT_ID:
572+
seq_puts(s, "mbm_local_bytes\n");
573+
break;
574+
case QOS_L3_MBM_TOTAL_EVENT_ID:
575+
seq_puts(s, "mbm_total_bytes\n");
576+
break;
577+
default:
578+
pr_warn_once("Bad event %d\n", rdtgrp->mba_mbps_event);
579+
ret = -EINVAL;
580+
break;
581+
}
582+
} else {
583+
ret = -ENOENT;
584+
}
585+
586+
rdtgroup_kn_unlock(of->kn);
587+
588+
return ret;
589+
}
590+
521591
void mon_event_read(struct rmid_read *rr, struct rdt_resource *r,
522592
struct rdt_mon_domain *d, struct rdtgroup *rdtgrp,
523593
cpumask_t *cpumask, int evtid, int first)

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

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,7 @@ struct pseudo_lock_region {
283283
* monitor only or ctrl_mon group
284284
* @mon: mongroup related data
285285
* @mode: mode of resource group
286+
* @mba_mbps_event: input monitoring event id when mba_sc is enabled
286287
* @plr: pseudo-locked region
287288
*/
288289
struct rdtgroup {
@@ -295,6 +296,7 @@ struct rdtgroup {
295296
enum rdt_group_type type;
296297
struct mongroup mon;
297298
enum rdtgrp_mode mode;
299+
enum resctrl_event_id mba_mbps_event;
298300
struct pseudo_lock_region *plr;
299301
};
300302

@@ -508,6 +510,7 @@ extern struct mutex rdtgroup_mutex;
508510
extern struct rdt_hw_resource rdt_resources_all[];
509511
extern struct rdtgroup rdtgroup_default;
510512
extern struct dentry *debugfs_resctrl;
513+
extern enum resctrl_event_id mba_mbps_default_event;
511514

512515
enum resctrl_res_level {
513516
RDT_RESOURCE_L3,
@@ -607,6 +610,10 @@ ssize_t rdtgroup_schemata_write(struct kernfs_open_file *of,
607610
char *buf, size_t nbytes, loff_t off);
608611
int rdtgroup_schemata_show(struct kernfs_open_file *of,
609612
struct seq_file *s, void *v);
613+
ssize_t rdtgroup_mba_mbps_event_write(struct kernfs_open_file *of,
614+
char *buf, size_t nbytes, loff_t off);
615+
int rdtgroup_mba_mbps_event_show(struct kernfs_open_file *of,
616+
struct seq_file *s, void *v);
610617
bool rdtgroup_cbm_overlaps(struct resctrl_schema *s, struct rdt_ctrl_domain *d,
611618
unsigned long cbm, int closid, bool exclusive);
612619
unsigned int rdtgroup_cbm_to_size(struct rdt_resource *r, struct rdt_ctrl_domain *d,
@@ -647,10 +654,8 @@ void cqm_handle_limbo(struct work_struct *work);
647654
bool has_busy_rmid(struct rdt_mon_domain *d);
648655
void __check_limbo(struct rdt_mon_domain *d, bool force_free);
649656
void rdt_domain_reconfigure_cdp(struct rdt_resource *r);
650-
void __init thread_throttle_mode_init(void);
651-
void __init mbm_config_rftype_init(const char *config);
657+
void resctrl_file_fflags_init(const char *config, unsigned long fflags);
652658
void rdt_staged_configs_clear(void);
653659
bool closid_allocated(unsigned int closid);
654660
int resctrl_find_cleanest_closid(void);
655-
656661
#endif /* _ASM_X86_RESCTRL_INTERNAL_H */

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

Lines changed: 46 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -663,9 +663,12 @@ static int __mon_event_count(u32 closid, u32 rmid, struct rmid_read *rr)
663663
*/
664664
static void mbm_bw_count(u32 closid, u32 rmid, struct rmid_read *rr)
665665
{
666-
u32 idx = resctrl_arch_rmid_idx_encode(closid, rmid);
667-
struct mbm_state *m = &rr->d->mbm_local[idx];
668666
u64 cur_bw, bytes, cur_bytes;
667+
struct mbm_state *m;
668+
669+
m = get_mbm_state(rr->d, closid, rmid, rr->evtid);
670+
if (WARN_ON_ONCE(!m))
671+
return;
669672

670673
cur_bytes = rr->val;
671674
bytes = cur_bytes - m->prev_bw_bytes;
@@ -752,20 +755,20 @@ static void update_mba_bw(struct rdtgroup *rgrp, struct rdt_mon_domain *dom_mbm)
752755
u32 closid, rmid, cur_msr_val, new_msr_val;
753756
struct mbm_state *pmbm_data, *cmbm_data;
754757
struct rdt_ctrl_domain *dom_mba;
758+
enum resctrl_event_id evt_id;
755759
struct rdt_resource *r_mba;
756-
u32 cur_bw, user_bw, idx;
757760
struct list_head *head;
758761
struct rdtgroup *entry;
759-
760-
if (!is_mbm_local_enabled())
761-
return;
762+
u32 cur_bw, user_bw;
762763

763764
r_mba = &rdt_resources_all[RDT_RESOURCE_MBA].r_resctrl;
765+
evt_id = rgrp->mba_mbps_event;
764766

765767
closid = rgrp->closid;
766768
rmid = rgrp->mon.rmid;
767-
idx = resctrl_arch_rmid_idx_encode(closid, rmid);
768-
pmbm_data = &dom_mbm->mbm_local[idx];
769+
pmbm_data = get_mbm_state(dom_mbm, closid, rmid, evt_id);
770+
if (WARN_ON_ONCE(!pmbm_data))
771+
return;
769772

770773
dom_mba = get_ctrl_domain_from_cpu(smp_processor_id(), r_mba);
771774
if (!dom_mba) {
@@ -784,7 +787,9 @@ static void update_mba_bw(struct rdtgroup *rgrp, struct rdt_mon_domain *dom_mbm)
784787
*/
785788
head = &rgrp->mon.crdtgrp_list;
786789
list_for_each_entry(entry, head, mon.crdtgrp_list) {
787-
cmbm_data = &dom_mbm->mbm_local[entry->mon.rmid];
790+
cmbm_data = get_mbm_state(dom_mbm, entry->closid, entry->mon.rmid, evt_id);
791+
if (WARN_ON_ONCE(!cmbm_data))
792+
return;
788793
cur_bw += cmbm_data->prev_bw;
789794
}
790795

@@ -813,54 +818,45 @@ static void update_mba_bw(struct rdtgroup *rgrp, struct rdt_mon_domain *dom_mbm)
813818
resctrl_arch_update_one(r_mba, dom_mba, closid, CDP_NONE, new_msr_val);
814819
}
815820

816-
static void mbm_update(struct rdt_resource *r, struct rdt_mon_domain *d,
817-
u32 closid, u32 rmid)
821+
static void mbm_update_one_event(struct rdt_resource *r, struct rdt_mon_domain *d,
822+
u32 closid, u32 rmid, enum resctrl_event_id evtid)
818823
{
819824
struct rmid_read rr = {0};
820825

821826
rr.r = r;
822827
rr.d = d;
828+
rr.evtid = evtid;
829+
rr.arch_mon_ctx = resctrl_arch_mon_ctx_alloc(rr.r, rr.evtid);
830+
if (IS_ERR(rr.arch_mon_ctx)) {
831+
pr_warn_ratelimited("Failed to allocate monitor context: %ld",
832+
PTR_ERR(rr.arch_mon_ctx));
833+
return;
834+
}
835+
836+
__mon_event_count(closid, rmid, &rr);
823837

824838
/*
825-
* This is protected from concurrent reads from user
826-
* as both the user and we hold the global mutex.
839+
* If the software controller is enabled, compute the
840+
* bandwidth for this event id.
827841
*/
828-
if (is_mbm_total_enabled()) {
829-
rr.evtid = QOS_L3_MBM_TOTAL_EVENT_ID;
830-
rr.val = 0;
831-
rr.arch_mon_ctx = resctrl_arch_mon_ctx_alloc(rr.r, rr.evtid);
832-
if (IS_ERR(rr.arch_mon_ctx)) {
833-
pr_warn_ratelimited("Failed to allocate monitor context: %ld",
834-
PTR_ERR(rr.arch_mon_ctx));
835-
return;
836-
}
837-
838-
__mon_event_count(closid, rmid, &rr);
842+
if (is_mba_sc(NULL))
843+
mbm_bw_count(closid, rmid, &rr);
839844

840-
resctrl_arch_mon_ctx_free(rr.r, rr.evtid, rr.arch_mon_ctx);
841-
}
842-
if (is_mbm_local_enabled()) {
843-
rr.evtid = QOS_L3_MBM_LOCAL_EVENT_ID;
844-
rr.val = 0;
845-
rr.arch_mon_ctx = resctrl_arch_mon_ctx_alloc(rr.r, rr.evtid);
846-
if (IS_ERR(rr.arch_mon_ctx)) {
847-
pr_warn_ratelimited("Failed to allocate monitor context: %ld",
848-
PTR_ERR(rr.arch_mon_ctx));
849-
return;
850-
}
851-
852-
__mon_event_count(closid, rmid, &rr);
845+
resctrl_arch_mon_ctx_free(rr.r, rr.evtid, rr.arch_mon_ctx);
846+
}
853847

854-
/*
855-
* Call the MBA software controller only for the
856-
* control groups and when user has enabled
857-
* the software controller explicitly.
858-
*/
859-
if (is_mba_sc(NULL))
860-
mbm_bw_count(closid, rmid, &rr);
848+
static void mbm_update(struct rdt_resource *r, struct rdt_mon_domain *d,
849+
u32 closid, u32 rmid)
850+
{
851+
/*
852+
* This is protected from concurrent reads from user as both
853+
* the user and overflow handler hold the global mutex.
854+
*/
855+
if (is_mbm_total_enabled())
856+
mbm_update_one_event(r, d, closid, rmid, QOS_L3_MBM_TOTAL_EVENT_ID);
861857

862-
resctrl_arch_mon_ctx_free(rr.r, rr.evtid, rr.arch_mon_ctx);
863-
}
858+
if (is_mbm_local_enabled())
859+
mbm_update_one_event(r, d, closid, rmid, QOS_L3_MBM_LOCAL_EVENT_ID);
864860
}
865861

866862
/*
@@ -1224,11 +1220,13 @@ int __init rdt_get_mon_l3_config(struct rdt_resource *r)
12241220

12251221
if (rdt_cpu_has(X86_FEATURE_CQM_MBM_TOTAL)) {
12261222
mbm_total_event.configurable = true;
1227-
mbm_config_rftype_init("mbm_total_bytes_config");
1223+
resctrl_file_fflags_init("mbm_total_bytes_config",
1224+
RFTYPE_MON_INFO | RFTYPE_RES_CACHE);
12281225
}
12291226
if (rdt_cpu_has(X86_FEATURE_CQM_MBM_LOCAL)) {
12301227
mbm_local_event.configurable = true;
1231-
mbm_config_rftype_init("mbm_local_bytes_config");
1228+
resctrl_file_fflags_init("mbm_local_bytes_config",
1229+
RFTYPE_MON_INFO | RFTYPE_RES_CACHE);
12321230
}
12331231
}
12341232

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

Lines changed: 8 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1205,29 +1205,21 @@ static int pseudo_lock_measure_cycles(struct rdtgroup *rdtgrp, int sel)
12051205
plr->cpu = cpu;
12061206

12071207
if (sel == 1)
1208-
thread = kthread_create_on_node(measure_cycles_lat_fn, plr,
1209-
cpu_to_node(cpu),
1210-
"pseudo_lock_measure/%u",
1211-
cpu);
1208+
thread = kthread_run_on_cpu(measure_cycles_lat_fn, plr,
1209+
cpu, "pseudo_lock_measure/%u");
12121210
else if (sel == 2)
1213-
thread = kthread_create_on_node(measure_l2_residency, plr,
1214-
cpu_to_node(cpu),
1215-
"pseudo_lock_measure/%u",
1216-
cpu);
1211+
thread = kthread_run_on_cpu(measure_l2_residency, plr,
1212+
cpu, "pseudo_lock_measure/%u");
12171213
else if (sel == 3)
1218-
thread = kthread_create_on_node(measure_l3_residency, plr,
1219-
cpu_to_node(cpu),
1220-
"pseudo_lock_measure/%u",
1221-
cpu);
1214+
thread = kthread_run_on_cpu(measure_l3_residency, plr,
1215+
cpu, "pseudo_lock_measure/%u");
12221216
else
12231217
goto out;
12241218

12251219
if (IS_ERR(thread)) {
12261220
ret = PTR_ERR(thread);
12271221
goto out;
12281222
}
1229-
kthread_bind(thread, cpu);
1230-
wake_up_process(thread);
12311223

12321224
ret = wait_event_interruptible(plr->lock_thread_wq,
12331225
plr->thread_done == 1);
@@ -1315,18 +1307,14 @@ int rdtgroup_pseudo_lock_create(struct rdtgroup *rdtgrp)
13151307

13161308
plr->thread_done = 0;
13171309

1318-
thread = kthread_create_on_node(pseudo_lock_fn, rdtgrp,
1319-
cpu_to_node(plr->cpu),
1320-
"pseudo_lock/%u", plr->cpu);
1310+
thread = kthread_run_on_cpu(pseudo_lock_fn, rdtgrp,
1311+
plr->cpu, "pseudo_lock/%u");
13211312
if (IS_ERR(thread)) {
13221313
ret = PTR_ERR(thread);
13231314
rdt_last_cmd_printf("Locking thread returned error %d\n", ret);
13241315
goto out_cstates;
13251316
}
13261317

1327-
kthread_bind(thread, plr->cpu);
1328-
wake_up_process(thread);
1329-
13301318
ret = wait_event_interruptible(plr->lock_thread_wq,
13311319
plr->thread_done == 1);
13321320
if (ret < 0) {

0 commit comments

Comments
 (0)