From: Wang ShaoBo bobo.shaobowang@huawei.com
hulk inclusion category: feature bugzilla: 34278 CVE: NA
-------------------------------------------------
If cdp enabled, LxCODE and LxDATA are assigned two different partid each occupies a monitor, but because not all features use cdp mode, for instance MB(Memory Bandwidth), we should make sure this two partid/ monitor be operated simultaneously for display.
e.g.
+- code stream (partid = 0, monitor = 0) ----+---> L3CODE cpu-+ + +- data stream (partid = 1, monitor = 1) ----+---> L3DATA | +---> MB
Signed-off-by: Wang ShaoBo bobo.shaobowang@huawei.com Reviewed-by: Xiongfeng Wang wangxiongfeng2@huawei.com Reviewed-by: Cheng Jian cj.chengjian@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com Signed-off-by: Cheng Jian cj.chengjian@huawei.com --- arch/arm64/include/asm/mpam.h | 5 ++ arch/arm64/kernel/mpam/mpam_ctrlmon.c | 81 ++++++++++++++++++++++----- 2 files changed, 72 insertions(+), 14 deletions(-)
diff --git a/arch/arm64/include/asm/mpam.h b/arch/arm64/include/asm/mpam.h index 7dd34caa8a86..5fac0fb3c807 100644 --- a/arch/arm64/include/asm/mpam.h +++ b/arch/arm64/include/asm/mpam.h @@ -195,6 +195,7 @@ do { \ * @new_ctrl: new ctrl value to be loaded * @have_new_ctrl: did user provide new_ctrl for this domain * @new_ctrl_type: CDP property of the new ctrl + * @cdp_both_ctrl: did cdp both control if cdp enabled */ struct resctrl_staged_config { hw_closid_t hw_closid; @@ -202,6 +203,7 @@ struct resctrl_staged_config { bool have_new_ctrl; enum resctrl_conf_type conf_type; enum resctrl_ctrl_type ctrl_type; + bool cdp_both_ctrl; };
/* later move to resctrl common directory */ @@ -219,6 +221,7 @@ struct resctrl_schema_ctrl { * @conf_type: Type of configuration, e.g. code/data/both * @res: The rdt_resource for this entry * @schemata_ctrl_list: Type of ctrl configuration. e.g. priority/hardlimit + * @cdp_mc_both: did cdp both mon/ctrl if cdp enabled */ struct resctrl_schema { struct list_head list; @@ -226,6 +229,7 @@ struct resctrl_schema { enum resctrl_conf_type conf_type; struct resctrl_resource *res; struct list_head schema_ctrl_list; + bool cdp_mc_both; };
/** @@ -341,6 +345,7 @@ union mon_data_bits { u8 partid; u8 pmg; u8 mon; + u8 cdp_both_mon; } u; };
diff --git a/arch/arm64/kernel/mpam/mpam_ctrlmon.c b/arch/arm64/kernel/mpam/mpam_ctrlmon.c index 019cb57e5c46..808a16209129 100644 --- a/arch/arm64/kernel/mpam/mpam_ctrlmon.c +++ b/arch/arm64/kernel/mpam/mpam_ctrlmon.c @@ -60,6 +60,15 @@ static int add_schema(enum resctrl_conf_type t, struct resctrl_resource *r) s->res = r; s->conf_type = t;
+ /* + * code and data is separated for resources LxCache but + * not for MB(Memory Bandwidth), it's necessary to set + * cdp_mc_both to let resctrl know operating the two closid/ + * monitor simultaneously when configuring/monitoring. + */ + if (is_resctrl_cdp_enabled()) + s->cdp_mc_both = !r->cdp_enable; + switch (t) { case CDP_CODE: suffix = "CODE"; @@ -168,6 +177,24 @@ void schemata_list_destroy(void) } }
+static void +resctrl_dom_ctrl_config(bool cdp_both_ctrl, struct resctrl_resource *r, + struct rdt_domain *dom, struct msr_param *para) +{ + struct raw_resctrl_resource *rr; + + rr = r->res; + rr->msr_update(r, dom, para); + + if (cdp_both_ctrl) { + hw_closid_t hw_closid; + + resctrl_cdp_map(clos, para->closid->reqpartid, CDP_DATA, hw_closid); + para->closid->reqpartid = hw_closid_val(hw_closid); + rr->msr_update(r, dom, para); + } +} + static void resctrl_group_update_domain_ctrls(struct rdtgroup *rdtgrp, struct resctrl_resource *r, struct rdt_domain *dom) { @@ -175,15 +202,11 @@ static void resctrl_group_update_domain_ctrls(struct rdtgroup *rdtgrp, struct resctrl_staged_config *cfg; enum resctrl_ctrl_type type; hw_closid_t hw_closid; - struct raw_resctrl_resource *rr; struct sd_closid closid; struct list_head *head; struct rdtgroup *entry; struct msr_param para; - - bool update_on; - - rr = r->res; + bool update_on, cdp_both_ctrl;
cfg = dom->staged_cfg; para.closid = &closid; @@ -192,6 +215,7 @@ static void resctrl_group_update_domain_ctrls(struct rdtgroup *rdtgrp, if (!cfg[i].have_new_ctrl) continue; update_on = false; + cdp_both_ctrl = cfg[i].cdp_both_ctrl; /* * for ctrl group configuration, hw_closid of cfg[i] equals * to rdtgrp->closid.intpartid. @@ -215,7 +239,7 @@ static void resctrl_group_update_domain_ctrls(struct rdtgroup *rdtgrp, } } if (update_on) - rr->msr_update(r, dom, ¶); + resctrl_dom_ctrl_config(cdp_both_ctrl, r, dom, ¶);
/* * we should synchronize all child mon groups' @@ -225,8 +249,9 @@ static void resctrl_group_update_domain_ctrls(struct rdtgroup *rdtgrp, list_for_each_entry(entry, head, mon.crdtgrp_list) { resctrl_cdp_map(clos, entry->closid.reqpartid, cfg[i].conf_type, hw_closid); + closid.reqpartid = hw_closid_val(hw_closid); - rr->msr_update(r, dom, ¶); + resctrl_dom_ctrl_config(cdp_both_ctrl, r, dom, ¶); } } } @@ -504,13 +529,33 @@ static inline char *get_resource_name(char *name) return res; }
+static u64 resctrl_dom_mon_data(struct resctrl_resource *r, + struct rdt_domain *d, void *md_priv) +{ + u64 ret; + union mon_data_bits md; + struct raw_resctrl_resource *rr; + + md.priv = md_priv; + rr = r->res; + ret = rr->mon_read(d, md.priv); + if (md.u.cdp_both_mon) { + hw_closid_t hw_closid; + + resctrl_cdp_map(clos, md.u.partid, CDP_DATA, hw_closid); + md.u.partid = hw_closid_val(hw_closid); + ret += rr->mon_read(d, md.priv); + } + + return ret; +} + int resctrl_group_mondata_show(struct seq_file *m, void *arg) { struct kernfs_open_file *of = m->private; struct rdtgroup *rdtgrp; struct rdt_domain *d; struct resctrl_resource *r; - struct raw_resctrl_resource *rr; union mon_data_bits md; int ret = 0; char *resname = get_resource_name(kernfs_node_name(of)); @@ -528,7 +573,6 @@ int resctrl_group_mondata_show(struct seq_file *m, void *arg) md.priv = of->kn->priv;
r = mpam_resctrl_get_resource(md.u.rid); - rr = r->res;
/* show monitor data */ d = mpam_find_domain(r, md.u.domid, NULL); @@ -538,7 +582,8 @@ int resctrl_group_mondata_show(struct seq_file *m, void *arg) goto out; }
- usage = rr->mon_read(d, md.priv); + usage = resctrl_dom_mon_data(r, d, md.priv); + /* * if this rdtgroup is ctrlmon group, also collect it's * mon groups' monitor data. @@ -562,7 +607,7 @@ int resctrl_group_mondata_show(struct seq_file *m, void *arg) md.u.partid = hw_closid_val(hw_closid); md.u.pmg = entry->mon.rmid; md.u.mon = entry->mon.mon; - usage += rr->mon_read(d, md.priv); + usage += resctrl_dom_mon_data(r, d, md.priv); } }
@@ -618,6 +663,7 @@ static int resctrl_mkdir_mondata_dom(struct kernfs_node *parent_kn, resctrl_cdp_map(mon, prgrp->mon.mon, s->conf_type, hw_monid); md.u.mon = hw_monid_val(hw_monid); md.u.pmg = prgrp->mon.rmid; + md.u.cdp_both_mon = s->cdp_mc_both;
snprintf(name, sizeof(name), "mon_%s_%02d", s->name, d->id); kn = __kernfs_create_file(parent_kn, name, 0444, @@ -686,14 +732,20 @@ int resctrl_mkdir_mondata_all_subdir(struct kernfs_node *parent_kn, }
/* Initialize MBA resource with default values. */ -static void rdtgroup_init_mba(struct resctrl_resource *r, u32 closid) +static void rdtgroup_init_mba(struct resctrl_schema *s, u32 closid) { struct resctrl_staged_config *cfg; + struct resctrl_resource *r; struct rdt_domain *d; enum resctrl_ctrl_type t;
- list_for_each_entry(d, &r->domains, list) { + r = s->res; + if (WARN_ON(!r)) + return; + + list_for_each_entry(d, &s->res->domains, list) { cfg = &d->staged_cfg[CDP_BOTH]; + cfg->cdp_both_ctrl = s->cdp_mc_both; cfg->new_ctrl[SCHEMA_COMM] = r->default_ctrl[SCHEMA_COMM]; resctrl_cdp_map(clos, closid, CDP_BOTH, cfg->hw_closid); cfg->have_new_ctrl = true; @@ -731,6 +783,7 @@ static int rdtgroup_init_cat(struct resctrl_schema *s, u32 closid)
list_for_each_entry(d, &s->res->domains, list) { cfg = &d->staged_cfg[conf_type]; + cfg->cdp_both_ctrl = s->cdp_mc_both; cfg->have_new_ctrl = false; cfg->new_ctrl[SCHEMA_COMM] = r->cache.shareable_bits; used_b = r->cache.shareable_bits; @@ -773,7 +826,7 @@ int resctrl_group_init_alloc(struct rdtgroup *rdtgrp) list_for_each_entry(s, &resctrl_all_schema, list) { r = s->res; if (r->rid == RDT_RESOURCE_MC) { - rdtgroup_init_mba(r, rdtgrp->closid.intpartid); + rdtgroup_init_mba(s, rdtgrp->closid.intpartid); } else { ret = rdtgroup_init_cat(s, rdtgrp->closid.intpartid); if (ret < 0)