From: Wang ShaoBo bobo.shaobowang@huawei.com
hulk inclusion category: feature bugzilla: 34278 CVE: NA
-------------------------------------------------
Some resource's properities such as closid and rmid are exported like Intel-RDT in our resctrl design, but there also has two main differences, one is MB(Memory Bandwidth), for we MB is also divided into two directories MB and MB_MON to show respective properties about control and monitor type as same as LxCache, another is we adopt features sysfile under resources' directories, which indicates the properties of control type of corresponding resource, for instance MB hardlimit.
e.g. > mount -t resctrl resctrl /sys/fs/resctrl -o mbHdl > cd /sys/fs/resctrl/ && cat info/MB/features mbHdl@1 #indicate MBHDL setting's upper bound is 1 > cat schemata L3:0=7fff;1=7fff;2=7fff;3=7fff MB:0=100;1=100;2=100;3=100 MBHDL:0=1;1=1;2=1;3=1
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 | 4 + arch/arm64/kernel/mpam/mpam_resctrl.c | 240 ++++++++++++++++++++------ fs/resctrlfs.c | 22 +-- 3 files changed, 200 insertions(+), 66 deletions(-)
diff --git a/arch/arm64/include/asm/mpam.h b/arch/arm64/include/asm/mpam.h index e6fd2b7c72b0..930658a775d6 100644 --- a/arch/arm64/include/asm/mpam.h +++ b/arch/arm64/include/asm/mpam.h @@ -246,6 +246,8 @@ struct resctrl_schema { bool cdp_mc_both; };
+extern struct list_head resctrl_all_schema; + /** * struct rdt_domain - group of cpus sharing an RDT resource * @list: all instances of this resource @@ -349,6 +351,8 @@ struct raw_resctrl_resource { int (*mon_write)(struct rdt_domain *d, void *md_priv);
struct resctrl_ctrl_feature ctrl_features[SCHEMA_NUM_CTRL_TYPE]; + + unsigned long fflags; };
/* 64bit arm64 specified */ diff --git a/arch/arm64/kernel/mpam/mpam_resctrl.c b/arch/arm64/kernel/mpam/mpam_resctrl.c index 2b9f0f7dca93..503244cb7e97 100644 --- a/arch/arm64/kernel/mpam/mpam_resctrl.c +++ b/arch/arm64/kernel/mpam/mpam_resctrl.c @@ -136,6 +136,7 @@ struct raw_resctrl_resource raw_resctrl_resources_all[] = { .format_str = "%d=%0*x", .mon_read = cache_rdmon, .mon_write = common_wrmon, + .fflags = RFTYPE_RES_CACHE, .ctrl_features = { [SCHEMA_COMM] = { .type = SCHEMA_COMM, @@ -161,6 +162,7 @@ struct raw_resctrl_resource raw_resctrl_resources_all[] = { .format_str = "%d=%0*x", .mon_read = cache_rdmon, .mon_write = common_wrmon, + .fflags = RFTYPE_RES_CACHE, .ctrl_features = { [SCHEMA_COMM] = { .type = SCHEMA_COMM, @@ -186,6 +188,7 @@ struct raw_resctrl_resource raw_resctrl_resources_all[] = { .format_str = "%d=%0*d", .mon_read = mbw_rdmon, .mon_write = common_wrmon, + .fflags = RFTYPE_RES_MB, .ctrl_features = { [SCHEMA_COMM] = { .type = SCHEMA_COMM, @@ -510,6 +513,14 @@ static void mpam_resctrl_closid_collect(void) } }
+static u32 get_nr_closid(void) +{ + if (!intpartid_free_map) + return 0; + + return num_intpartid; +} + int closid_bitmap_init(void) { int pos; @@ -558,6 +569,14 @@ struct rmid_transform { }; static struct rmid_transform rmid_remap_matrix;
+static u32 get_nr_rmids(void) +{ + if (!rmid_remap_matrix.remap_enabled) + return 0; + + return rmid_remap_matrix.nr_usage; +} + /* * a rmid remap matrix is delivered for transforming partid pmg to rmid, * this matrix is organized like this: @@ -868,7 +887,6 @@ static int __rmid_alloc(int partid) goto out;
return rmid[0]; - out: rmid_free(rmid[0]); return ret; @@ -1352,48 +1370,6 @@ int cpus_ctrl_write(struct rdtgroup *rdtgrp, cpumask_var_t newmask, return 0; }
-static int resctrl_num_partid_show(struct kernfs_open_file *of, - struct seq_file *seq, void *v) -{ - struct resctrl_resource *r = of->kn->parent->priv; - struct raw_resctrl_resource *rr = r->res; - u16 num_partid; - - num_partid = rr->num_partid; - - seq_printf(seq, "%d\n", num_partid); - - return 0; -} - -static int resctrl_num_pmg_show(struct kernfs_open_file *of, - struct seq_file *seq, void *v) -{ - struct resctrl_resource *r = of->kn->parent->priv; - struct raw_resctrl_resource *rr = r->res; - u16 num_pmg; - - num_pmg = rr->num_pmg; - - seq_printf(seq, "%d\n", num_pmg); - - return 0; -} - -static int resctrl_num_mon_show(struct kernfs_open_file *of, - struct seq_file *seq, void *v) -{ - struct resctrl_resource *r = of->kn->parent->priv; - struct raw_resctrl_resource *rr = r->res; - u16 num_mon; - - num_mon = rr->num_mon; - - seq_printf(seq, "%d\n", num_mon); - - return 0; -} - int cpus_mon_write(struct rdtgroup *rdtgrp, cpumask_var_t newmask, cpumask_var_t tmpmask) { @@ -1578,7 +1554,7 @@ void rdt_last_cmd_printf(const char *fmt, ...) va_end(ap); }
-static int rdt_last_cmd_status_show(struct kernfs_open_file *of, +static int resctrl_last_cmd_status_show(struct kernfs_open_file *of, struct seq_file *seq, void *v) { int len; @@ -1593,6 +1569,116 @@ static int rdt_last_cmd_status_show(struct kernfs_open_file *of, return 0; }
+static int resctrl_num_closids_show(struct kernfs_open_file *of, + struct seq_file *seq, void *v) +{ + u32 flag, times; + + hw_alloc_times_validate(times, flag); + + seq_printf(seq, "%u\n", get_nr_closid() / times); + return 0; +} + +static int resctrl_cbm_mask_show(struct kernfs_open_file *of, + struct seq_file *seq, void *v) +{ + struct resctrl_resource *r = of->kn->parent->priv; + struct raw_resctrl_resource *rr = r->res; + + seq_printf(seq, "%x\n", rr->ctrl_features[SCHEMA_COMM].default_ctrl); + return 0; +} + +static int resctrl_min_cbm_bits_show(struct kernfs_open_file *of, + struct seq_file *seq, void *v) +{ + struct resctrl_resource *r = of->kn->parent->priv; + + seq_printf(seq, "%u\n", r->cache.min_cbm_bits); + return 0; +} + +static int resctrl_shareable_bits_show(struct kernfs_open_file *of, + struct seq_file *seq, void *v) +{ + struct resctrl_resource *r = of->kn->parent->priv; + + seq_printf(seq, "%x\n", r->cache.shareable_bits); + return 0; +} + +static int resctrl_features_show(struct kernfs_open_file *of, + struct seq_file *seq, void *v) +{ + enum resctrl_ctrl_type type; + struct resctrl_resource *r = of->kn->parent->priv; + struct raw_resctrl_resource *rr = r->res; + + for_each_extend_ctrl_type(type) { + if (!rr->ctrl_features[type].enabled) + continue; + /* + * we define the range of ctrl features with integer, + * here give maximum upper bound to user space. + */ + switch (rr->ctrl_features[type].base) { + case 10: + seq_printf(seq, "%s@%u\n", rr->ctrl_features[type].name, + rr->ctrl_features[type].max_wd - 1); + break; + case 16: + seq_printf(seq, "%s@%x\n", rr->ctrl_features[type].name, + rr->ctrl_features[type].max_wd - 1); + break; + default: + break; + } + } + return 0; +} + +static int resctrl_min_bandwidth_show(struct kernfs_open_file *of, + struct seq_file *seq, void *v) +{ + struct resctrl_resource *r = of->kn->parent->priv; + + seq_printf(seq, "%u\n", r->mbw.min_bw); + return 0; +} + +static int resctrl_bandwidth_gran_show(struct kernfs_open_file *of, + struct seq_file *seq, void *v) +{ + struct resctrl_resource *r = of->kn->parent->priv; + + seq_printf(seq, "%u\n", r->mbw.bw_gran); + return 0; +} + +static int resctrl_num_rmids_show(struct kernfs_open_file *of, + struct seq_file *seq, void *v) +{ + u32 flag, times; + + hw_alloc_times_validate(times, flag); + seq_printf(seq, "%u\n", get_nr_rmids() / times); + return 0; +} + +static int resctrl_num_monitors_show(struct kernfs_open_file *of, + struct seq_file *seq, void *v) +{ + struct resctrl_resource *r = of->kn->parent->priv; + struct raw_resctrl_resource *rr = r->res; + u32 flag, times; + + hw_alloc_times_validate(times, flag); + seq_printf(seq, "%u\n", rr->num_mon / times); + return 0; +} + + static ssize_t resctrl_group_tasks_write(struct kernfs_open_file *of, char *buf, size_t nbytes, loff_t off) { @@ -1649,32 +1735,74 @@ static int resctrl_group_tasks_show(struct kernfs_open_file *of, /* rdtgroup information files for one cache resource. */ static struct rftype res_specific_files[] = { { - .name = "num_partids", + .name = "last_cmd_status", + .mode = 0444, + .kf_ops = &resctrl_group_kf_single_ops, + .seq_show = resctrl_last_cmd_status_show, + .fflags = RF_TOP_INFO, + }, + { + .name = "num_closids", .mode = 0444, .kf_ops = &resctrl_group_kf_single_ops, - .seq_show = resctrl_num_partid_show, + .seq_show = resctrl_num_closids_show, .fflags = RF_CTRL_INFO, }, { - .name = "num_pmgs", + .name = "cbm_mask", .mode = 0444, .kf_ops = &resctrl_group_kf_single_ops, - .seq_show = resctrl_num_pmg_show, - .fflags = RF_MON_INFO, + .seq_show = resctrl_cbm_mask_show, + .fflags = RF_CTRL_INFO | RFTYPE_RES_CACHE, }, { - .name = "num_monitors", + .name = "min_cbm_bits", .mode = 0444, .kf_ops = &resctrl_group_kf_single_ops, - .seq_show = resctrl_num_mon_show, + .seq_show = resctrl_min_cbm_bits_show, + .fflags = RF_CTRL_INFO | RFTYPE_RES_CACHE, + }, + { + .name = "shareable_bits", + .mode = 0444, + .kf_ops = &resctrl_group_kf_single_ops, + .seq_show = resctrl_shareable_bits_show, + .fflags = RF_CTRL_INFO | RFTYPE_RES_CACHE, + }, + { + .name = "features", + .mode = 0444, + .kf_ops = &resctrl_group_kf_single_ops, + .seq_show = resctrl_features_show, + .fflags = RF_CTRL_INFO, + }, + { + .name = "min_bandwidth", + .mode = 0444, + .kf_ops = &resctrl_group_kf_single_ops, + .seq_show = resctrl_min_bandwidth_show, + .fflags = RF_CTRL_INFO | RFTYPE_RES_MB, + }, + { + .name = "bandwidth_gran", + .mode = 0444, + .kf_ops = &resctrl_group_kf_single_ops, + .seq_show = resctrl_bandwidth_gran_show, + .fflags = RF_CTRL_INFO | RFTYPE_RES_MB, + }, + { + .name = "num_rmids", + .mode = 0444, + .kf_ops = &resctrl_group_kf_single_ops, + .seq_show = resctrl_num_rmids_show, .fflags = RF_MON_INFO, }, { - .name = "last_cmd_status", - .mode = 0444, - .kf_ops = &resctrl_group_kf_single_ops, - .seq_show = rdt_last_cmd_status_show, - .fflags = RF_TOP_INFO, + .name = "num_monitors", + .mode = 0444, + .kf_ops = &resctrl_group_kf_single_ops, + .seq_show = resctrl_num_monitors_show, + .fflags = RF_MON_INFO, }, { .name = "cpus", diff --git a/fs/resctrlfs.c b/fs/resctrlfs.c index 2b6731c21532..e2891529ec11 100644 --- a/fs/resctrlfs.c +++ b/fs/resctrlfs.c @@ -180,11 +180,12 @@ static int resctrl_group_mkdir_info_resdir(struct resctrl_resource *r, char *nam
static int resctrl_group_create_info_dir(struct kernfs_node *parent_kn) { + struct resctrl_schema *s; struct resctrl_resource *r; + struct raw_resctrl_resource *rr; unsigned long fflags; char name[32]; int ret; - enum resctrl_resource_level level;
/* create the directory */ kn_info = kernfs_create_dir(parent_kn, "info", parent_kn->mode, NULL); @@ -196,25 +197,27 @@ static int resctrl_group_create_info_dir(struct kernfs_node *parent_kn) if (ret) goto out_destroy;
- for (level = RDT_RESOURCE_SMMU; level < RDT_NUM_RESOURCES; level++) { - r = mpam_resctrl_get_resource(level); + list_for_each_entry(s, &resctrl_all_schema, list) { + r = s->res; if (!r) continue; + rr = r->res; if (r->alloc_enabled) { - fflags = r->fflags | RF_CTRL_INFO; - ret = resctrl_group_mkdir_info_resdir(r, r->name, fflags); + fflags = rr->fflags | RF_CTRL_INFO; + ret = resctrl_group_mkdir_info_resdir(r, s->name, fflags); if (ret) goto out_destroy; } }
- for (level = RDT_RESOURCE_SMMU; level < RDT_NUM_RESOURCES; level++) { - r = mpam_resctrl_get_resource(level); + list_for_each_entry(s, &resctrl_all_schema, list) { + r = s->res; if (!r) continue; + rr = r->res; if (r->mon_enabled) { - fflags = r->fflags | RF_MON_INFO; - snprintf(name, sizeof(name), "%s_MON", r->name); + fflags = rr->fflags | RF_MON_INFO; + snprintf(name, sizeof(name), "%s_MON", s->name); ret = resctrl_group_mkdir_info_resdir(r, name, fflags); if (ret) goto out_destroy; @@ -314,7 +317,6 @@ mongroup_create_dir(struct kernfs_node *parent_kn, struct resctrl_group *prgrp, /* create the directory */ kn = kernfs_create_dir(parent_kn, name, parent_kn->mode, prgrp); if (IS_ERR(kn)) { - pr_info("%s: create dir %s, error\n", __func__, name); return PTR_ERR(kn); }