From: Wang ShaoBo bobo.shaobowang@huawei.com
hulk inclusion category: feature bugzilla: 34278 CVE: NA
-------------------------------------------------
Structure resctrl_ctrl_feature taken by resources is introduced to manage ctrl features, of which characteristic like max width from outer input and the base we parse from.
Now it is more practical for declaring a new ctrl feature, such as SCHEMA_PRI feature, only associated with internal priority setting exported by mpam devices, where informations is collected from mpam_resctrl_resource_init(), and next be chosen open or close by user options.
ctrl_ctrl_feature structure contains a flags field to avoid duplicated control type, for instance, SCHEMA_COMM feature selectes cpbm (Cache portion bitmap) as resource Cache default control type, so we should not enable this feature no longer if user manually selectes cpbm control type through mount options.
This field evt in ctrl_ctrl_feature structure is enum rdt_event_id type variable which works like eee4ad2a36e6 ("arm64/mpam: Add hook-events id for ctrl features") illustrates.
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 --- arch/arm64/include/asm/mpam.h | 25 ++- arch/arm64/kernel/mpam/mpam_ctrlmon.c | 29 ++- arch/arm64/kernel/mpam/mpam_internal.h | 1 + arch/arm64/kernel/mpam/mpam_resctrl.c | 287 ++++++++++++------------- arch/arm64/kernel/mpam/mpam_setup.c | 136 +++++++----- include/linux/resctrlfs.h | 3 - 6 files changed, 260 insertions(+), 221 deletions(-)
diff --git a/arch/arm64/include/asm/mpam.h b/arch/arm64/include/asm/mpam.h index 0414fdc5cb0e..e6fd2b7c72b0 100644 --- a/arch/arm64/include/asm/mpam.h +++ b/arch/arm64/include/asm/mpam.h @@ -124,14 +124,28 @@ enum resctrl_ctrl_type { SCHEMA_NUM_CTRL_TYPE };
+struct resctrl_ctrl_feature { + enum resctrl_ctrl_type type; + int flags; + const char *name; + + u32 max_wd; + + int base; + int evt; + + int default_ctrl; + + bool capable; + bool enabled; +}; + #define for_each_ctrl_type(t) \ for (t = SCHEMA_COMM; t != SCHEMA_NUM_CTRL_TYPE; t++)
#define for_each_extend_ctrl_type(t) \ for (t = SCHEMA_PRI; t != SCHEMA_NUM_CTRL_TYPE; t++)
-bool resctrl_ctrl_extend_bits_match(u32 bitmap, enum resctrl_ctrl_type type); - enum resctrl_conf_type { CDP_BOTH = 0, CDP_CODE, @@ -319,11 +333,10 @@ struct raw_resctrl_resource { u16 num_intpartid; u16 num_pmg;
- u16 extend_ctrls_wd[SCHEMA_NUM_CTRL_TYPE]; - void (*msr_update)(struct resctrl_resource *r, struct rdt_domain *d, struct msr_param *para); - u64 (*msr_read)(struct rdt_domain *d, struct msr_param *para); + u64 (*msr_read)(struct resctrl_resource *r, struct rdt_domain *d, + struct msr_param *para);
int data_width; const char *format_str; @@ -334,6 +347,8 @@ struct raw_resctrl_resource { u16 num_mon; u64 (*mon_read)(struct rdt_domain *d, void *md_priv); int (*mon_write)(struct rdt_domain *d, void *md_priv); + + struct resctrl_ctrl_feature ctrl_features[SCHEMA_NUM_CTRL_TYPE]; };
/* 64bit arm64 specified */ diff --git a/arch/arm64/kernel/mpam/mpam_ctrlmon.c b/arch/arm64/kernel/mpam/mpam_ctrlmon.c index eda30c5c9730..5f0481356d32 100644 --- a/arch/arm64/kernel/mpam/mpam_ctrlmon.c +++ b/arch/arm64/kernel/mpam/mpam_ctrlmon.c @@ -92,8 +92,8 @@ static int add_schema(enum resctrl_conf_type t, struct resctrl_resource *r) rr = r->res; INIT_LIST_HEAD(&s->schema_ctrl_list); for_each_extend_ctrl_type(type) { - if (!resctrl_ctrl_extend_bits_match(r->ctrl_extend_bits, type) || - !rr->extend_ctrls_wd[type]) + if (!rr->ctrl_features[type].enabled || + !rr->ctrl_features[type].max_wd) continue;
sc = kzalloc(sizeof(*sc), GFP_KERNEL); @@ -281,6 +281,9 @@ parse_line(char *line, struct resctrl_resource *r, unsigned long dom_id; hw_closid_t hw_closid;
+ if (!rr->ctrl_features[ctrl_type].enabled) + return -EINVAL; + next: if (!line || line[0] == '\0') return 0; @@ -428,6 +431,9 @@ static void show_doms(struct seq_file *s, struct resctrl_resource *r, bool prev_auto_fill = false; u32 reg_val;
+ if (!rr->ctrl_features[type].enabled) + return; + para.closid = closid; para.type = type;
@@ -436,15 +442,15 @@ static void show_doms(struct seq_file *s, struct resctrl_resource *r,
seq_printf(s, "%*s:", max_name_width, schema_name); list_for_each_entry(dom, &r->domains, list) { - reg_val = rr->msr_read(dom, ¶); + reg_val = rr->msr_read(r, dom, ¶);
- if (rg && reg_val == r->default_ctrl[SCHEMA_COMM] && - prev_auto_fill == true) + if (reg_val == rr->ctrl_features[SCHEMA_COMM].default_ctrl && + rg && prev_auto_fill == true) continue;
if (sep) seq_puts(s, ";"); - if (rg && reg_val == r->default_ctrl[SCHEMA_COMM]) { + if (rg && reg_val == rr->ctrl_features[SCHEMA_COMM].default_ctrl) { prev_auto_fill = true; seq_puts(s, "S"); } else { @@ -750,22 +756,24 @@ static void rdtgroup_init_mba(struct resctrl_schema *s, u32 closid) { struct resctrl_staged_config *cfg; struct resctrl_resource *r; + struct raw_resctrl_resource *rr; struct rdt_domain *d; enum resctrl_ctrl_type t;
r = s->res; if (WARN_ON(!r)) return; + rr = r->res;
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]; + cfg->new_ctrl[SCHEMA_COMM] = rr->ctrl_features[SCHEMA_COMM].default_ctrl; resctrl_cdp_map(clos, closid, CDP_BOTH, cfg->hw_closid); cfg->have_new_ctrl = true; /* Set extension ctrl default value, e.g. priority/hardlimit */ for_each_extend_ctrl_type(t) { - cfg->new_ctrl[t] = r->default_ctrl[t]; + cfg->new_ctrl[t] = rr->ctrl_features[t].default_ctrl; } } } @@ -787,6 +795,7 @@ static int rdtgroup_init_cat(struct resctrl_schema *s, u32 closid) enum resctrl_ctrl_type ctrl_type; struct rdt_domain *d; struct resctrl_resource *r; + struct raw_resctrl_resource *rr; u32 used_b = 0; u32 unused_b = 0; unsigned long tmp_cbm; @@ -794,6 +803,7 @@ static int rdtgroup_init_cat(struct resctrl_schema *s, u32 closid) r = s->res; if (WARN_ON(!r)) return -EINVAL; + rr = r->res;
list_for_each_entry(d, &s->res->domains, list) { cfg = &d->staged_cfg[conf_type]; @@ -823,7 +833,8 @@ static int rdtgroup_init_cat(struct resctrl_schema *s, u32 closid) * with MPAM capabilities. */ for_each_extend_ctrl_type(ctrl_type) { - cfg->new_ctrl[ctrl_type] = r->default_ctrl[ctrl_type]; + cfg->new_ctrl[ctrl_type] = + rr->ctrl_features[ctrl_type].default_ctrl; } }
diff --git a/arch/arm64/kernel/mpam/mpam_internal.h b/arch/arm64/kernel/mpam/mpam_internal.h index 690ed3f875e8..d74989e03993 100644 --- a/arch/arm64/kernel/mpam/mpam_internal.h +++ b/arch/arm64/kernel/mpam/mpam_internal.h @@ -19,6 +19,7 @@ extern bool rdt_mon_capable; extern struct list_head mpam_classes;
#define MAX_MBA_BW 100u +#define GRAN_MBA_BW 2u
#define MPAM_ERRCODE_NONE 0 #define MPAM_ERRCODE_PARTID_SEL_RANGE 1 diff --git a/arch/arm64/kernel/mpam/mpam_resctrl.c b/arch/arm64/kernel/mpam/mpam_resctrl.c index 029a1538c00b..fe13f3442eac 100644 --- a/arch/arm64/kernel/mpam/mpam_resctrl.c +++ b/arch/arm64/kernel/mpam/mpam_resctrl.c @@ -100,22 +100,6 @@ bool is_resctrl_cdp_enabled(void) return !!resctrl_cdp_enabled; }
-static void -resctrl_ctrl_extend_bits_set(u32 *bitmap, enum resctrl_ctrl_type type) -{ - *bitmap |= BIT(type); -} - -static void resctrl_ctrl_extend_bits_clear(u32 *bitmap) -{ - *bitmap = 0; -} - -bool resctrl_ctrl_extend_bits_match(u32 bitmap, enum resctrl_ctrl_type type) -{ - return bitmap & BIT(type); -} - static void mpam_resctrl_update_component_cfg(struct resctrl_resource *r, struct rdt_domain *d, struct sd_closid *closid); @@ -124,8 +108,10 @@ static void common_wrmsr(struct resctrl_resource *r, struct rdt_domain *d, struct msr_param *para);
-static u64 cache_rdmsr(struct rdt_domain *d, struct msr_param *para); -static u64 mbw_rdmsr(struct rdt_domain *d, struct msr_param *para); +static u64 cache_rdmsr(struct resctrl_resource *r, struct rdt_domain *d, + struct msr_param *para); +static u64 mbw_rdmsr(struct resctrl_resource *r, struct rdt_domain *d, + struct msr_param *para);
static u64 cache_rdmon(struct rdt_domain *d, void *md_priv); static u64 mbw_rdmon(struct rdt_domain *d, void *md_priv); @@ -145,6 +131,23 @@ struct raw_resctrl_resource raw_resctrl_resources_all[] = { .format_str = "%d=%0*x", .mon_read = cache_rdmon, .mon_write = common_wrmon, + .ctrl_features = { + [SCHEMA_COMM] = { + .type = SCHEMA_COMM, + .flags = SCHEMA_COMM, + .name = "comm", + .base = 16, + .evt = QOS_CAT_CPBM_EVENT_ID, + .capable = 1, + }, + [SCHEMA_PRI] = { + .type = SCHEMA_PRI, + .flags = SCHEMA_PRI, + .name = "caPrio", + .base = 10, + .evt = QOS_CAT_INTPRI_EVENT_ID, + }, + }, }, [RDT_RESOURCE_L2] = { .msr_update = common_wrmsr, @@ -153,6 +156,23 @@ struct raw_resctrl_resource raw_resctrl_resources_all[] = { .format_str = "%d=%0*x", .mon_read = cache_rdmon, .mon_write = common_wrmon, + .ctrl_features = { + [SCHEMA_COMM] = { + .type = SCHEMA_COMM, + .flags = SCHEMA_COMM, + .name = "comm", + .base = 16, + .evt = QOS_CAT_CPBM_EVENT_ID, + .capable = 1, + }, + [SCHEMA_PRI] = { + .type = SCHEMA_PRI, + .flags = SCHEMA_PRI, + .name = "caPrio", + .base = 10, + .evt = QOS_CAT_INTPRI_EVENT_ID, + }, + }, }, [RDT_RESOURCE_MC] = { .msr_update = common_wrmsr, @@ -161,6 +181,30 @@ struct raw_resctrl_resource raw_resctrl_resources_all[] = { .format_str = "%d=%0*d", .mon_read = mbw_rdmon, .mon_write = common_wrmon, + .ctrl_features = { + [SCHEMA_COMM] = { + .type = SCHEMA_COMM, + .flags = SCHEMA_COMM, + .name = "comm", + .base = 10, + .evt = QOS_MBA_MAX_EVENT_ID, + .capable = 1, + }, + [SCHEMA_PRI] = { + .type = SCHEMA_PRI, + .flags = SCHEMA_PRI, + .name = "mbPrio", + .base = 10, + .evt = QOS_MBA_INTPRI_EVENT_ID, + }, + [SCHEMA_HDL] = { + .type = SCHEMA_HDL, + .flags = SCHEMA_HDL, + .name = "mbHdl", + .base = 10, + .evt = QOS_MBA_HDL_EVENT_ID, + }, + }, }, };
@@ -183,28 +227,18 @@ parse_cache(char *buf, struct resctrl_resource *r, enum resctrl_ctrl_type type) { unsigned long data; + struct raw_resctrl_resource *rr = r->res;
if (cfg->have_new_ctrl) { rdt_last_cmd_printf("duplicate domain\n"); return -EINVAL; }
- switch (type) { - case SCHEMA_COMM: - if (kstrtoul(buf, 16, &data)) - return -EINVAL; - break; - case SCHEMA_PRI: - if (kstrtoul(buf, 10, &data)) - return -EINVAL; - break; - case SCHEMA_HDL: - if (kstrtoul(buf, 10, &data)) - return -EINVAL; - break; - default: + if (kstrtoul(buf, rr->ctrl_features[type].base, &data)) + return -EINVAL; + + if (data >= rr->ctrl_features[type].max_wd) return -EINVAL; - }
cfg->new_ctrl[type] = data; cfg->have_new_ctrl = true; @@ -212,54 +246,35 @@ parse_cache(char *buf, struct resctrl_resource *r, return 0; }
-static bool bw_validate(char *buf, unsigned long *data, - struct resctrl_resource *r) -{ - unsigned long bw; - int ret; - - ret = kstrtoul(buf, 10, &bw); - if (ret) { - rdt_last_cmd_printf("non-hex character in mask %s\n", buf); - return false; - } - - bw = bw > MAX_MBA_BW ? MAX_MBA_BW : bw; - bw = bw < r->mbw.min_bw ? r->mbw.min_bw : bw; - *data = roundup(bw, r->mbw.bw_gran); - - return true; -} - static int parse_bw(char *buf, struct resctrl_resource *r, struct resctrl_staged_config *cfg, enum resctrl_ctrl_type type) { unsigned long data; + struct raw_resctrl_resource *rr = r->res;
if (cfg->have_new_ctrl) { rdt_last_cmd_printf("duplicate domain\n"); return -EINVAL; }
- switch (type) { - case SCHEMA_COMM: - if (!bw_validate(buf, &data, r)) + switch (rr->ctrl_features[type].evt) { + case QOS_MBA_MAX_EVENT_ID: + if (kstrtoul(buf, rr->ctrl_features[type].base, &data)) return -EINVAL; + data = (data < r->mbw.min_bw) ? r->mbw.min_bw : data; + data = roundup(data, r->mbw.bw_gran); break; - case SCHEMA_PRI: - if (kstrtoul(buf, 10, &data)) - return -EINVAL; - break; - case SCHEMA_HDL: - if (kstrtoul(buf, 10, &data)) + default: + if (kstrtoul(buf, rr->ctrl_features[type].base, &data)) return -EINVAL; break; - default: - return -EINVAL; }
+ if (data >= rr->ctrl_features[type].max_wd) + return -EINVAL; + cfg->new_ctrl[type] = data; cfg->have_new_ctrl = true;
@@ -285,61 +300,43 @@ common_wrmsr(struct resctrl_resource *r, struct rdt_domain *d, mpam_component_config(dom->comp, &args); }
-static u64 cache_rdmsr(struct rdt_domain *d, struct msr_param *para) +static u64 cache_rdmsr(struct resctrl_resource *r, struct rdt_domain *d, + struct msr_param *para) { - u32 result, intpri, dspri; + u32 result; struct sync_args args; struct mpam_resctrl_dom *dom; + struct raw_resctrl_resource *rr = r->res;
args.closid = *para->closid; dom = container_of(d, struct mpam_resctrl_dom, resctrl_dom);
- switch (para->type) { - case SCHEMA_COMM: - args.eventid = QOS_CAT_CPBM_EVENT_ID; - mpam_component_get_config(dom->comp, &args, &result); - break; - case SCHEMA_PRI: - args.eventid = QOS_CAT_INTPRI_EVENT_ID; - mpam_component_get_config(dom->comp, &args, &intpri); - args.eventid = QOS_MBA_DSPRI_EVENT_ID; - mpam_component_get_config(dom->comp, &args, &dspri); - result = (intpri > dspri) ? intpri : dspri; - break; - default: - return 0; - } + args.eventid = rr->ctrl_features[para->type].evt; + mpam_component_get_config(dom->comp, &args, &result);
return result; }
-static u64 mbw_rdmsr(struct rdt_domain *d, struct msr_param *para) +static u64 mbw_rdmsr(struct resctrl_resource *r, struct rdt_domain *d, + struct msr_param *para) { - u32 result, intpri, dspri; + u32 result; struct sync_args args; struct mpam_resctrl_dom *dom; + struct raw_resctrl_resource *rr = r->res;
args.closid = *para->closid; dom = container_of(d, struct mpam_resctrl_dom, resctrl_dom);
- switch (para->type) { - case SCHEMA_COMM: - args.eventid = QOS_MBA_MAX_EVENT_ID; - mpam_component_get_config(dom->comp, &args, &result); - break; - case SCHEMA_PRI: - args.eventid = QOS_MBA_INTPRI_EVENT_ID; - mpam_component_get_config(dom->comp, &args, &intpri); - args.eventid = QOS_MBA_DSPRI_EVENT_ID; - mpam_component_get_config(dom->comp, &args, &dspri); - result = (intpri > dspri) ? intpri : dspri; - break; - case SCHEMA_HDL: - args.eventid = QOS_MBA_HDL_EVENT_ID; - mpam_component_get_config(dom->comp, &args, &result); + args.eventid = rr->ctrl_features[para->type].evt; + mpam_component_get_config(dom->comp, &args, &result); + + switch (rr->ctrl_features[para->type].evt) { + case QOS_MBA_MAX_EVENT_ID: + result = roundup(result, r->mbw.bw_gran); break; default: - return 0; + break; }
return result; @@ -1023,27 +1020,25 @@ static int cdpl2_enable(void) static void basic_ctrl_enable(void) { struct mpam_resctrl_res *res; - struct resctrl_resource *r; + struct raw_resctrl_resource *rr;
for_each_supported_resctrl_exports(res) { - r = &res->resctrl_res; + rr = res->resctrl_res.res; /* At least SCHEMA_COMM is supported */ - resctrl_ctrl_extend_bits_set(&r->ctrl_extend_bits, SCHEMA_COMM); + rr->ctrl_features[SCHEMA_COMM].enabled = true; } }
static int extend_ctrl_enable(enum resctrl_ctrl_type type) { bool match = false; - struct resctrl_resource *r; struct raw_resctrl_resource *rr; struct mpam_resctrl_res *res;
for_each_supported_resctrl_exports(res) { - r = &res->resctrl_res; - rr = r->res; - if (rr->extend_ctrls_wd[type]) { - resctrl_ctrl_extend_bits_set(&r->ctrl_extend_bits, type); + rr = res->resctrl_res.res; + if (rr->ctrl_features[type].capable) { + rr->ctrl_features[type].enabled = true; match = true; } } @@ -1056,12 +1051,13 @@ static int extend_ctrl_enable(enum resctrl_ctrl_type type)
static void extend_ctrl_disable(void) { - struct resctrl_resource *r; + struct raw_resctrl_resource *rr; struct mpam_resctrl_res *res;
for_each_supported_resctrl_exports(res) { - r = &res->resctrl_res; - resctrl_ctrl_extend_bits_clear(&r->ctrl_extend_bits); + rr = res->resctrl_res.res; + rr->ctrl_features[SCHEMA_PRI].enabled = false; + rr->ctrl_features[SCHEMA_HDL].enabled = false; } }
@@ -1843,48 +1839,32 @@ void __mpam_sched_in(void)
static void mpam_update_from_resctrl_cfg(struct mpam_resctrl_res *res, - u32 resctrl_cfg, enum resctrl_ctrl_type ctrl_type, + u32 resctrl_cfg, enum rdt_event_id evt, struct mpam_config *mpam_cfg) { - switch (ctrl_type) { - case SCHEMA_COMM: - if (res == &mpam_resctrl_exports[RDT_RESOURCE_MC]) { - u64 range; - - /* For MBA cfg is a percentage of .. */ - if (res->resctrl_mba_uses_mbw_part) { - /* .. the number of bits we can set */ - range = res->class->mbw_pbm_bits; - mpam_cfg->mbw_pbm = - (resctrl_cfg * range) / MAX_MBA_BW; - mpam_set_feature(mpam_feat_mbw_part, &mpam_cfg->valid); - } else { - /* .. the number of fractions we can represent */ - range = MBW_MAX_BWA_FRACT(res->class->bwa_wd); - mpam_cfg->mbw_max = (resctrl_cfg * range) / (MAX_MBA_BW - 1); - mpam_cfg->mbw_max = - (mpam_cfg->mbw_max > range) ? range : mpam_cfg->mbw_max; - mpam_set_feature(mpam_feat_mbw_max, &mpam_cfg->valid); - } - } else { - /* - * Nothing clever here as mpam_resctrl_pick_caches() - * capped the size at RESCTRL_MAX_CBM. - */ - mpam_cfg->cpbm = resctrl_cfg; - mpam_set_feature(mpam_feat_cpor_part, &mpam_cfg->valid); - } - break; - case SCHEMA_PRI: - mpam_cfg->dspri = resctrl_cfg; - mpam_cfg->intpri = resctrl_cfg; - mpam_set_feature(mpam_feat_dspri_part, &mpam_cfg->valid); - mpam_set_feature(mpam_feat_intpri_part, &mpam_cfg->valid); + u64 range; + + switch (evt) { + case QOS_MBA_MAX_EVENT_ID: + /* .. the number of fractions we can represent */ + range = MBW_MAX_BWA_FRACT(res->class->bwa_wd); + mpam_cfg->mbw_max = (resctrl_cfg * range) / (MAX_MBA_BW - 1); + mpam_cfg->mbw_max = + (mpam_cfg->mbw_max > range) ? range : mpam_cfg->mbw_max; + mpam_set_feature(mpam_feat_mbw_max, &mpam_cfg->valid); break; - case SCHEMA_HDL: + case QOS_MBA_HDL_EVENT_ID: mpam_cfg->hdl = resctrl_cfg; mpam_set_feature(mpam_feat_part_hdl, &mpam_cfg->valid); break; + case QOS_CAT_CPBM_EVENT_ID: + mpam_cfg->cpbm = resctrl_cfg; + mpam_set_feature(mpam_feat_cpor_part, &mpam_cfg->valid); + break; + case QOS_CAT_INTPRI_EVENT_ID: + mpam_cfg->intpri = resctrl_cfg; + mpam_set_feature(mpam_feat_intpri_part, &mpam_cfg->valid); + break; default: break; } @@ -1903,6 +1883,7 @@ mpam_resctrl_update_component_cfg(struct resctrl_resource *r, struct mpam_resctrl_dom *dom; struct mpam_resctrl_res *res; struct mpam_config *slave_mpam_cfg; + struct raw_resctrl_resource *rr = r->res; enum resctrl_ctrl_type type; u32 intpartid = closid->intpartid; u32 reqpartid = closid->reqpartid; @@ -1930,11 +1911,9 @@ mpam_resctrl_update_component_cfg(struct resctrl_resource *r, slave_mpam_cfg->valid = 0;
for_each_ctrl_type(type) { - /* - * we don't need check if we have enabled this ctrl type, because - * this ctrls also should be applied an default configuration and - * this feature type would be rechecked when configuring mpam devices. - */ + if (!rr->ctrl_features[type].enabled) + continue; + resctrl_cfg = d->ctrl_val[type][intpartid]; mpam_update_from_resctrl_cfg(res, resctrl_cfg, type, slave_mpam_cfg); @@ -1947,13 +1926,15 @@ static void mpam_reset_cfg(struct mpam_resctrl_res *res, { int i; struct resctrl_resource *r = &res->resctrl_res; + struct raw_resctrl_resource *rr = r->res; enum resctrl_ctrl_type type;
for (i = 0; i != mpam_sysprops_num_partid(); i++) { for_each_ctrl_type(type) { - mpam_update_from_resctrl_cfg(res, r->default_ctrl[type], - type, &dom->comp->cfg[i]); - d->ctrl_val[type][i] = r->default_ctrl[type]; + mpam_update_from_resctrl_cfg(res, + rr->ctrl_features[type].default_ctrl, + rr->ctrl_features[type].evt, &dom->comp->cfg[i]); + d->ctrl_val[type][i] = rr->ctrl_features[type].default_ctrl; } } } diff --git a/arch/arm64/kernel/mpam/mpam_setup.c b/arch/arm64/kernel/mpam/mpam_setup.c index ef922a796ff8..18b1e5db5c0a 100644 --- a/arch/arm64/kernel/mpam/mpam_setup.c +++ b/arch/arm64/kernel/mpam/mpam_setup.c @@ -334,13 +334,6 @@ static int mpam_resctrl_resource_init(struct mpam_resctrl_res *res) struct resctrl_resource *r = &res->resctrl_res; struct raw_resctrl_resource *rr = NULL;
- if (class && !r->default_ctrl) { - r->default_ctrl = kmalloc_array(SCHEMA_NUM_CTRL_TYPE, - sizeof(*r->default_ctrl), GFP_KERNEL); - if (!r->default_ctrl) - return -ENOMEM; - } - if (class == mpam_resctrl_exports[RDT_RESOURCE_SMMU].class) { return 0; } else if (class == mpam_resctrl_exports[RDT_RESOURCE_MC].class) { @@ -373,17 +366,32 @@ static int mpam_resctrl_resource_init(struct mpam_resctrl_res *res) r->mbw.min_bw = MAX_MBA_BW / ((1ULL << class->bwa_wd) - 1); /* the largest mbw_max is 100 */ - r->default_ctrl[SCHEMA_COMM] = 100; + rr->ctrl_features[SCHEMA_COMM].default_ctrl = MAX_MBA_BW; + rr->ctrl_features[SCHEMA_COMM].max_wd = MAX_MBA_BW + 1; + rr->ctrl_features[SCHEMA_COMM].capable = true; + } + + if (mpam_has_feature(mpam_feat_intpri_part, class->features)) { + /* + * Export internal priority setting, which represents the + * max level of control we can export to resctrl. this default + * priority is from hardware, no clever here. + */ + rr->ctrl_features[SCHEMA_PRI].max_wd = 1 << class->intpri_wd; + rr->ctrl_features[SCHEMA_PRI].default_ctrl = class->hwdef_intpri; + rr->ctrl_features[SCHEMA_PRI].capable = true; } + /* Just in case we have an excessive number of bits */ if (!r->mbw.min_bw) r->mbw.min_bw = 1;
/* - * because its linear with no offset, the granule is the same - * as the smallest value + * james said because its linear with no offset, the granule is the same + * as the smallest value. It is a little fuzzy here because a granularity + * of 1 would appear too fine to make percentage conversions. */ - r->mbw.bw_gran = r->mbw.min_bw; + r->mbw.bw_gran = GRAN_MBA_BW;
/* We will only pick a class that can monitor and control */ r->alloc_capable = true; @@ -392,8 +400,9 @@ static int mpam_resctrl_resource_init(struct mpam_resctrl_res *res) r->mon_capable = true; r->mon_enabled = true; /* Export memory bandwidth hardlimit, default active hardlimit */ - rr->extend_ctrls_wd[SCHEMA_HDL] = 2; - r->default_ctrl[SCHEMA_HDL] = 1; + rr->ctrl_features[SCHEMA_HDL].default_ctrl = 1; + rr->ctrl_features[SCHEMA_HDL].max_wd = 2; + rr->ctrl_features[SCHEMA_HDL].capable = true; } else if (class == mpam_resctrl_exports[RDT_RESOURCE_L3].class) { r->rid = RDT_RESOURCE_L3; rr = mpam_get_raw_resctrl_resource(RDT_RESOURCE_L3); @@ -402,22 +411,40 @@ static int mpam_resctrl_resource_init(struct mpam_resctrl_res *res) r->fflags = RFTYPE_RES_CACHE; r->name = "L3";
- r->cache.cbm_len = class->cpbm_wd; - r->default_ctrl[SCHEMA_COMM] = GENMASK(class->cpbm_wd - 1, 0); - /* - * Which bits are shared with other ...things... - * Unknown devices use partid-0 which uses all the bitmap - * fields. Until we configured the SMMU and GIC not to do this - * 'all the bits' is the correct answer here. - */ - r->cache.shareable_bits = r->default_ctrl[SCHEMA_COMM]; - r->cache.min_cbm_bits = 1; - if (mpam_has_feature(mpam_feat_cpor_part, class->features)) { - r->alloc_capable = true; - r->alloc_enabled = true; - rdt_alloc_capable = true; + r->cache.cbm_len = class->cpbm_wd; + rr->ctrl_features[SCHEMA_COMM].default_ctrl = GENMASK(class->cpbm_wd - 1, 0); + rr->ctrl_features[SCHEMA_COMM].max_wd = + rr->ctrl_features[SCHEMA_COMM].default_ctrl + 1; + rr->ctrl_features[SCHEMA_COMM].capable = true; + /* + * Which bits are shared with other ...things... + * Unknown devices use partid-0 which uses all the bitmap + * fields. Until we configured the SMMU and GIC not to do this + * 'all the bits' is the correct answer here. + */ + r->cache.shareable_bits = rr->ctrl_features[SCHEMA_COMM].default_ctrl; + r->cache.min_cbm_bits = 1; + } + + if (mpam_has_feature(mpam_feat_intpri_part, class->features)) { + /* + * Export internal priority setting, which represents the + * max level of control we can export to resctrl. this default + * priority is from hardware, no clever here. + */ + rr->ctrl_features[SCHEMA_PRI].max_wd = 1 << class->intpri_wd; + rr->ctrl_features[SCHEMA_PRI].default_ctrl = class->hwdef_intpri; + rr->ctrl_features[SCHEMA_PRI].capable = true; } + /* + * Only this resource is allocable can it be picked from + * mpam_resctrl_pick_caches(). So directly set following + * fields to true. + */ + r->alloc_capable = true; + r->alloc_enabled = true; + rdt_alloc_capable = true; /* * While this is a CPU-interface feature of MPAM, we only tell * resctrl about it for caches, as that seems to be how x86 @@ -435,22 +462,40 @@ static int mpam_resctrl_resource_init(struct mpam_resctrl_res *res) r->fflags = RFTYPE_RES_CACHE; r->name = "L2";
- r->cache.cbm_len = class->cpbm_wd; - r->default_ctrl[SCHEMA_COMM] = GENMASK(class->cpbm_wd - 1, 0); - /* - * Which bits are shared with other ...things... - * Unknown devices use partid-0 which uses all the bitmap - * fields. Until we configured the SMMU and GIC not to do this - * 'all the bits' is the correct answer here. - */ - r->cache.shareable_bits = r->default_ctrl[SCHEMA_COMM]; - if (mpam_has_feature(mpam_feat_cpor_part, class->features)) { - r->alloc_capable = true; - r->alloc_enabled = true; - rdt_alloc_capable = true; + r->cache.cbm_len = class->cpbm_wd; + rr->ctrl_features[SCHEMA_COMM].default_ctrl = GENMASK(class->cpbm_wd - 1, 0); + rr->ctrl_features[SCHEMA_COMM].max_wd = + rr->ctrl_features[SCHEMA_COMM].default_ctrl + 1; + rr->ctrl_features[SCHEMA_COMM].capable = true; + /* + * Which bits are shared with other ...things... + * Unknown devices use partid-0 which uses all the bitmap + * fields. Until we configured the SMMU and GIC not to do this + * 'all the bits' is the correct answer here. + */ + r->cache.shareable_bits = rr->ctrl_features[SCHEMA_COMM].default_ctrl; }
+ if (mpam_has_feature(mpam_feat_intpri_part, class->features)) { + /* + * Export internal priority setting, which represents the + * max level of control we can export to resctrl. this default + * priority is from hardware, no clever here. + */ + rr->ctrl_features[SCHEMA_PRI].max_wd = 1 << class->intpri_wd; + rr->ctrl_features[SCHEMA_PRI].default_ctrl = class->hwdef_intpri; + rr->ctrl_features[SCHEMA_PRI].capable = true; + } + /* + * Only this resource is allocable can it be picked from + * mpam_resctrl_pick_caches(). So directly set following + * fields to true. + */ + r->alloc_capable = true; + r->alloc_enabled = true; + rdt_alloc_capable = true; + /* * While this is a CPU-interface feature of MPAM, we only tell * resctrl about it for caches, as that seems to be how x86 @@ -464,17 +509,6 @@ static int mpam_resctrl_resource_init(struct mpam_resctrl_res *res) rr->num_partid = class->num_partid; rr->num_intpartid = class->num_intpartid; rr->num_pmg = class->num_pmg; - - /* - * Export priority setting, extend_ctrls_wd represents the - * max level of control we can export. this default priority - * is just from hardware, no need to define another default - * value. - */ - rr->extend_ctrls_wd[SCHEMA_PRI] = 1 << max(class->intpri_wd, - class->dspri_wd); - r->default_ctrl[SCHEMA_PRI] = max(class->hwdef_intpri, - class->hwdef_dspri); }
return 0; diff --git a/include/linux/resctrlfs.h b/include/linux/resctrlfs.h index 7f1ff6e816f5..287be52e2385 100644 --- a/include/linux/resctrlfs.h +++ b/include/linux/resctrlfs.h @@ -58,9 +58,6 @@ struct resctrl_resource {
bool cdp_capable; bool cdp_enable; - u32 *default_ctrl; - - u32 ctrl_extend_bits;
void *res; };