From: Xingang Wang wangxingang5@huawei.com
ascend inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/I49RB2 CVE: NA
-------------------------------------------------
When group rmid changes, as introduced by 6bbf2791b ("mpam: Add support for group rmid modify") the sysfs monitor data file rmid needs to update as well. This add support for updating rmid for monitoring, and then update the group configuration. When update failed, roll back to the previous rmid.
Signed-off-by: Xingang Wang wangxingang5@huawei.com Signed-off-by: Shaobo Wang bobo.shaobowang@huawei.com --- arch/arm64/kernel/mpam/mpam_ctrlmon.c | 33 ++++++++++++------ arch/arm64/kernel/mpam/mpam_resctrl.c | 50 ++++++++++++++++++++++++--- 2 files changed, 67 insertions(+), 16 deletions(-)
diff --git a/arch/arm64/kernel/mpam/mpam_ctrlmon.c b/arch/arm64/kernel/mpam/mpam_ctrlmon.c index a4a298a45..d292a0dbe 100644 --- a/arch/arm64/kernel/mpam/mpam_ctrlmon.c +++ b/arch/arm64/kernel/mpam/mpam_ctrlmon.c @@ -667,20 +667,31 @@ static int resctrl_mkdir_mondata_dom(struct kernfs_node *parent_kn,
md.u.cdp_both_mon = s->cdp_mc_both;
+ if (!parent_kn) { + pr_err("%s: error parent_kn null\n", __func__); + return -EINVAL; + } + snprintf(name, sizeof(name), "mon_%s_%02d", s->name, d->id); - kn = __kernfs_create_file(parent_kn, name, 0444, - GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, 0, - &kf_mondata_ops, md.priv, NULL, NULL); - if (IS_ERR(kn)) - return PTR_ERR(kn); - - ret = resctrl_group_kn_set_ugid(kn); - if (ret) { - pr_info("%s: create name %s, error ret %d\n", __func__, name, ret); - kernfs_remove(kn); - return ret; + kn = kernfs_find_and_get(parent_kn, name); + if (!kn) { + kn = __kernfs_create_file(parent_kn, name, 0444, + GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, 0, + &kf_mondata_ops, md.priv, NULL, NULL); + if (IS_ERR(kn)) + return PTR_ERR(kn); + + ret = resctrl_group_kn_set_ugid(kn); + if (ret) { + pr_info("%s: create name %s, error ret %d\n", + __func__, name, ret); + kernfs_remove(kn); + return ret; + } }
+ kn->priv = md.priv; + /* Could we remove the MATCH_* param ? */ rr->mon_write(d, md.priv);
diff --git a/arch/arm64/kernel/mpam/mpam_resctrl.c b/arch/arm64/kernel/mpam/mpam_resctrl.c index 991af33f2..05381caae 100644 --- a/arch/arm64/kernel/mpam/mpam_resctrl.c +++ b/arch/arm64/kernel/mpam/mpam_resctrl.c @@ -1873,6 +1873,8 @@ static ssize_t resctrl_group_rmid_write(struct kernfs_open_file *of, int partid; int pmg; int rmid; + int old_rmid; + int old_reqpartid; struct task_struct *p, *t;
if (kstrtoint(strstrip(buf), 0, &rmid) || rmid < 0) @@ -1907,6 +1909,9 @@ static ssize_t resctrl_group_rmid_write(struct kernfs_open_file *of, goto unlock; }
+ old_rmid = rdtgrp->mon.rmid; + old_reqpartid = rdtgrp->closid.reqpartid; + /* * we use intpartid as group control, use reqpartid for config * synchronization and monitor, only update the reqpartid @@ -1914,22 +1919,57 @@ static ssize_t resctrl_group_rmid_write(struct kernfs_open_file *of, rdtgrp->closid.reqpartid = partid; rdtgrp->mon.rmid = rmid;
+ /* update rmid for mondata */ + ret = resctrl_mkdir_mondata_all_subdir(rdtgrp->mon.mon_data_kn, rdtgrp); + if (ret) { + rdt_last_cmd_puts("update rmid for mondata failed\n"); + goto rollback; + } + + /* update groups config */ + ret = resctrl_update_groups_config(rdtgrp); + if (ret) { + rdt_last_cmd_puts("update groups config failed\n"); + goto rollback; + } + read_lock(&tasklist_lock); for_each_process_thread(p, t) { - if (t->closid == rdtgrp->closid.intpartid) - __resctrl_group_move_task(t, rdtgrp); + if (t->closid == rdtgrp->closid.intpartid) { + ret = __resctrl_group_move_task(t, rdtgrp); + if (ret) { + read_unlock(&tasklist_lock); + goto rollback; + } + } } read_unlock(&tasklist_lock);
update_closid_rmid(&rdtgrp->cpu_mask, rdtgrp); - rmid_free(rdtgrp->mon.rmid); - + rmid_free(old_rmid); unlock: resctrl_group_kn_unlock(of->kn); if (ret) return ret; - return nbytes; + +rollback: + rdtgrp->mon.rmid = old_rmid; + rdtgrp->closid.reqpartid = old_reqpartid; + + /* the old rmid is valid, so mkdir mondata here won't fail */ + resctrl_mkdir_mondata_all_subdir(rdtgrp->mon.mon_data_kn, rdtgrp); + + read_lock(&tasklist_lock); + for_each_process_thread(p, t) { + if (t->closid == rdtgrp->closid.intpartid) + WARN_ON_ONCE(__resctrl_group_move_task(t, rdtgrp)); + } + read_unlock(&tasklist_lock); + + rmid_free(rmid); + resctrl_group_kn_unlock(of->kn); + return ret; }
/* rdtgroup information files for one cache resource. */