From: Wang ShaoBo bobo.shaobowang@huawei.com
hulk inclusion category: feature bugzilla: 34278 CVE: NA
-------------------------------------------------
Reading/Writing registers directly for getting or putting configuration is not friendly with expansion and legibility, multiple types of schemata ctrls is supported, of which value should be converted to a proper value based on specific definition and range in corresponding register according to MPAM spec, Using event id instead to indicate which type configuration we want to get looks easier for us.
Besides, different hook-events have different setting bound such as bwa_wd for adaptive range conversion when writing configuration, this can be associated with specific event for conversion.
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 | 2 +- arch/arm64/include/asm/mpam_resource.h | 17 +++--- arch/arm64/include/asm/resctrl.h | 5 ++ arch/arm64/kernel/mpam/mpam_ctrlmon.c | 2 +- arch/arm64/kernel/mpam/mpam_device.c | 50 +++++++++++++++-- arch/arm64/kernel/mpam/mpam_internal.h | 2 - arch/arm64/kernel/mpam/mpam_resctrl.c | 78 ++++++-------------------- 7 files changed, 75 insertions(+), 81 deletions(-)
diff --git a/arch/arm64/include/asm/mpam.h b/arch/arm64/include/asm/mpam.h index 2e327ee2f560..7dd34caa8a86 100644 --- a/arch/arm64/include/asm/mpam.h +++ b/arch/arm64/include/asm/mpam.h @@ -323,7 +323,7 @@ struct raw_resctrl_resource {
int data_width; const char *format_str; - int (*parse_ctrlval)(char *buf, struct raw_resctrl_resource *r, + int (*parse_ctrlval)(char *buf, struct resctrl_resource *r, struct resctrl_staged_config *cfg, enum resctrl_ctrl_type ctrl_type);
diff --git a/arch/arm64/include/asm/mpam_resource.h b/arch/arm64/include/asm/mpam_resource.h index d7d9549be668..72cc9029946f 100644 --- a/arch/arm64/include/asm/mpam_resource.h +++ b/arch/arm64/include/asm/mpam_resource.h @@ -69,18 +69,17 @@ #define CPBM_WD_MASK 0xFFFF #define CPBM_MASK 0x7FFF
-#define BWA_WD 6 /* hard code for P680 */ -#define MBW_MAX_MASK 0xFC00 -#define MBW_MAX_HARDLIM BIT(31) +#define MBW_MAX_HARDLIM BIT(31) +#define MBW_PROP_HARDLIM BIT(31) +#define MBW_MAX_MASK GENMASK(15, 0) #define MBW_MAX_BWA_FRACT(w) GENMASK(w - 1, 0) -#define MBW_MAX_SET(v) (MBW_MAX_HARDLIM|((v) << (16 - BWA_WD))) -#define MBW_MAX_GET(v) (((v) & MBW_MAX_MASK) >> (16 - BWA_WD)) -#define MBW_MAX_SET_HDL(r) (r | MBW_MAX_HARDLIM) -#define MBW_MAX_GET_HDL(r) (r & MBW_MAX_HARDLIM) +#define MBW_MAX_SET(v, w) (v << (16 - w)) /* MPAMCFG_MBW_PROP */ -#define MBW_PROP_HARDLIM BIT(31) -#define MBW_PROP_SET_HDL(r) (r | MBW_PROP_HARDLIM) +#define MBW_PROP_SET_HDL(r) (r | MBW_PROP_HARDLIM) /* MPAMCFG_MBW_MAX */ +#define MBW_MAX_SET_HDL(r) (r | MBW_MAX_HARDLIM) +#define MBW_MAX_GET_HDL(r) ((r & MBW_MAX_HARDLIM) >> 31) +#define MBW_MAX_GET(v, w) (((v) & MBW_MAX_MASK) >> (16 - w))
#define MSMON_MATCH_PMG BIT(17) #define MSMON_MATCH_PARTID BIT(16) diff --git a/arch/arm64/include/asm/resctrl.h b/arch/arm64/include/asm/resctrl.h index 0c1f2cef0c36..37e750029fbc 100644 --- a/arch/arm64/include/asm/resctrl.h +++ b/arch/arm64/include/asm/resctrl.h @@ -22,6 +22,11 @@ enum rdt_event_id { QOS_L3_MBM_TOTAL_EVENT_ID = 0x02, QOS_L3_MBM_LOCAL_EVENT_ID = 0x03,
+ QOS_CAT_CPBM_EVENT_ID = 0x04, + QOS_CAT_PRI_EVENT_ID = 0x05, + QOS_MBA_MAX_EVENT_ID = 0x06, + QOS_MBA_PRI_EVENT_ID = 0x07, + QOS_MBA_HDL_EVENT_ID = 0x08, /* Must be the last */ RESCTRL_NUM_EVENT_IDS, }; diff --git a/arch/arm64/kernel/mpam/mpam_ctrlmon.c b/arch/arm64/kernel/mpam/mpam_ctrlmon.c index ce8cf3623ad5..019cb57e5c46 100644 --- a/arch/arm64/kernel/mpam/mpam_ctrlmon.c +++ b/arch/arm64/kernel/mpam/mpam_ctrlmon.c @@ -273,7 +273,7 @@ parse_line(char *line, struct resctrl_resource *r, list_for_each_entry(d, &r->domains, list) { if (d->id == dom_id) { resctrl_cdp_map(clos, closid, conf_type, hw_closid); - if (rr->parse_ctrlval(dom, rr, + if (rr->parse_ctrlval(dom, r, &d->staged_cfg[conf_type], ctrl_type)) return -EINVAL; d->staged_cfg[conf_type].hw_closid = hw_closid; diff --git a/arch/arm64/kernel/mpam/mpam_device.c b/arch/arm64/kernel/mpam/mpam_device.c index 6cc939e173f9..1202a5795e97 100644 --- a/arch/arm64/kernel/mpam/mpam_device.c +++ b/arch/arm64/kernel/mpam/mpam_device.c @@ -753,7 +753,7 @@ static void mpam_reset_device_config(struct mpam_component *comp, mpam_reset_device_bitmap(dev, MPAMCFG_MBW_PBM, dev->mbw_pbm_bits); if (mpam_has_feature(mpam_feat_mbw_max, dev->features)) { - mbw_max = MBW_MAX_SET(MBW_MAX_BWA_FRACT(dev->bwa_wd)); + mbw_max = MBW_MAX_SET(MBW_MAX_BWA_FRACT(dev->bwa_wd), dev->bwa_wd); mbw_max = MBW_MAX_SET_HDL(mbw_max); mpam_write_reg(dev, MPAMCFG_MBW_MAX, mbw_max); } @@ -1187,7 +1187,7 @@ mpam_device_config(struct mpam_device *dev, struct sd_closid *closid,
if (mpam_has_feature(mpam_feat_mbw_max, dev->features)) { if (cfg && mpam_has_feature(mpam_feat_mbw_max, cfg->valid)) { - mbw_max = MBW_MAX_SET(cfg->mbw_max); + mbw_max = MBW_MAX_SET(cfg->mbw_max, dev->bwa_wd); if (!mpam_has_feature(mpam_feat_part_hdl, cfg->valid) || (mpam_has_feature(mpam_feat_part_hdl, cfg->valid) && cfg->hdl)) mbw_max = MBW_MAX_SET_HDL(mbw_max); @@ -1392,14 +1392,15 @@ static void mpam_component_read_mpamcfg(void *_ctx) struct mpam_device_sync *ctx = (struct mpam_device_sync *)_ctx; struct mpam_component *comp = ctx->comp; struct sync_args *args = ctx->args; - u64 val; - u16 reg; + u64 val = 0; u32 partid, intpartid; + u32 dspri = 0; + u32 intpri = 0; + u64 range;
if (!args) return;
- reg = args->reg;
partid = args->closid.reqpartid; intpartid = args->closid.intpartid; @@ -1417,7 +1418,44 @@ static void mpam_component_read_mpamcfg(void *_ctx)
mpam_write_reg(dev, MPAMCFG_PART_SEL, partid); wmb(); - val = mpam_read_reg(dev, reg); + + switch (args->eventid) { + case QOS_CAT_CPBM_EVENT_ID: + if (!mpam_has_feature(mpam_feat_cpor_part, dev->features)) + break; + val = mpam_read_reg(dev, MPAMCFG_CPBM); + break; + case QOS_MBA_MAX_EVENT_ID: + if (!mpam_has_feature(mpam_feat_mbw_max, dev->features)) + break; + val = mpam_read_reg(dev, MPAMCFG_MBW_MAX); + range = MBW_MAX_BWA_FRACT(dev->bwa_wd); + val = MBW_MAX_GET(val, dev->bwa_wd) * (MAX_MBA_BW - 1) / range; + break; + case QOS_MBA_HDL_EVENT_ID: + if (!mpam_has_feature(mpam_feat_mbw_max, dev->features)) + break; + val = mpam_read_reg(dev, MPAMCFG_MBW_MAX); + val = MBW_MAX_GET_HDL(val); + break; + case QOS_CAT_PRI_EVENT_ID: + case QOS_MBA_PRI_EVENT_ID: + if (mpam_has_feature(mpam_feat_intpri_part, dev->features)) + intpri = MPAMCFG_INTPRI_GET(val); + if (mpam_has_feature(mpam_feat_dspri_part, dev->features)) + dspri = MPAMCFG_DSPRI_GET(val); + if (!mpam_has_feature(mpam_feat_intpri_part_0_low, + dev->features)) + intpri = GENMASK(dev->intpri_wd - 1, 0) & ~intpri; + if (!mpam_has_feature(mpam_feat_dspri_part_0_low, + dev->features)) + dspri = GENMASK(dev->intpri_wd - 1, 0) & ~dspri; + val = (dspri > intpri) ? dspri : intpri; + break; + default: + break; + } + atomic64_add(val, &ctx->cfg_value); spin_unlock_irqrestore(&dev->lock, flags);
diff --git a/arch/arm64/kernel/mpam/mpam_internal.h b/arch/arm64/kernel/mpam/mpam_internal.h index cc35dfc73449..0ca58712a8ca 100644 --- a/arch/arm64/kernel/mpam/mpam_internal.h +++ b/arch/arm64/kernel/mpam/mpam_internal.h @@ -41,8 +41,6 @@ struct sync_args { u32 mon; bool match_pmg; enum rdt_event_id eventid; - /*for reading msr*/ - u16 reg; };
struct mpam_device_sync { diff --git a/arch/arm64/kernel/mpam/mpam_resctrl.c b/arch/arm64/kernel/mpam/mpam_resctrl.c index 75399887c1ff..7c519d93c1bb 100644 --- a/arch/arm64/kernel/mpam/mpam_resctrl.c +++ b/arch/arm64/kernel/mpam/mpam_resctrl.c @@ -142,9 +142,9 @@ static u64 mbw_rdmon(struct rdt_domain *d, void *md_priv);
static int common_wrmon(struct rdt_domain *d, void *md_priv);
-static int parse_cache(char *buf, struct raw_resctrl_resource *r, +static int parse_cache(char *buf, struct resctrl_resource *r, struct resctrl_staged_config *cfg, enum resctrl_ctrl_type ctrl_type); -static int parse_bw(char *buf, struct raw_resctrl_resource *r, +static int parse_bw(char *buf, struct resctrl_resource *r, struct resctrl_staged_config *cfg, enum resctrl_ctrl_type ctrl_type);
struct raw_resctrl_resource raw_resctrl_resources_all[] = { @@ -188,7 +188,7 @@ mpam_get_raw_resctrl_resource(enum resctrl_resource_level level) * resource type. */ static int -parse_cache(char *buf, struct raw_resctrl_resource *r, +parse_cache(char *buf, struct resctrl_resource *r, struct resctrl_staged_config *cfg, enum resctrl_ctrl_type type) { @@ -222,32 +222,8 @@ parse_cache(char *buf, struct raw_resctrl_resource *r, return 0; }
-/* define bw_min as 5 percentage, that are 5% ~ 100% which cresponding masks: */ -static u32 bw_max_mask[20] = { - 3, /* 3/64: 5% */ - 6, /* 6/64: 10% */ - 10, /* 10/64: 15% */ - 13, /* 13/64: 20% */ - 16, /* 16/64: 25% */ - 19, /* ... */ - 22, - 26, - 29, - 32, - 35, - 38, - 42, - 45, - 48, - 51, - 54, - 58, - 61, - 63 /* 100% */ -}; - static bool bw_validate(char *buf, unsigned long *data, - struct raw_resctrl_resource *r) + struct resctrl_resource *r) { unsigned long bw; int ret; @@ -258,15 +234,15 @@ static bool bw_validate(char *buf, unsigned long *data, return false; }
- bw = bw < 5 ? 5 : bw; - bw = bw > 100 ? 100 : bw; - *data = roundup(bw, 5); + 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 raw_resctrl_resource *r, +parse_bw(char *buf, struct resctrl_resource *r, struct resctrl_staged_config *cfg, enum resctrl_ctrl_type type) { @@ -329,10 +305,10 @@ static u64 cache_rdmsr(struct rdt_domain *d, struct msr_param *para)
switch (para->type) { case SCHEMA_COMM: - args.reg = MPAMCFG_CPBM; + args.eventid = QOS_CAT_CPBM_EVENT_ID; break; case SCHEMA_PRI: - args.reg = MPAMCFG_PRI; + args.eventid = QOS_CAT_PRI_EVENT_ID; default: return 0; } @@ -340,14 +316,6 @@ static u64 cache_rdmsr(struct rdt_domain *d, struct msr_param *para) dom = container_of(d, struct mpam_resctrl_dom, resctrl_dom); mpam_component_get_config(dom->comp, &args, &result);
- switch (para->type) { - case SCHEMA_PRI: - result = MPAMCFG_PRI_GET(result); - break; - default: - break; - } - return result; }
@@ -365,13 +333,13 @@ static u64 mbw_rdmsr(struct rdt_domain *d, struct msr_param *para) */ switch (para->type) { case SCHEMA_COMM: - args.reg = MPAMCFG_MBW_MAX; + args.eventid = QOS_MBA_MAX_EVENT_ID; break; case SCHEMA_HDL: - args.reg = MPAMCFG_MBW_MAX; + args.eventid = QOS_MBA_HDL_EVENT_ID; break; case SCHEMA_PRI: - args.reg = MPAMCFG_PRI; + args.eventid = QOS_MBA_PRI_EVENT_ID; break; default: return 0; @@ -380,20 +348,6 @@ static u64 mbw_rdmsr(struct rdt_domain *d, struct msr_param *para) dom = container_of(d, struct mpam_resctrl_dom, resctrl_dom); mpam_component_get_config(dom->comp, &args, &result);
- switch (para->type) { - case SCHEMA_COMM: - result = roundup((MBW_MAX_GET(result) * 100) / 64, 5); - break; - case SCHEMA_PRI: - result = MPAMCFG_PRI_GET(result); - break; - case SCHEMA_HDL: - result = MBW_MAX_GET_HDL(result); - break; - default: - break; - } - return result; }
@@ -1568,10 +1522,10 @@ mpam_update_from_resctrl_cfg(struct mpam_resctrl_res *res, 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 = - bw_max_mask[(resctrl_cfg / 5 - 1) % - ARRAY_SIZE(bw_max_mask)]; - + (mpam_cfg->mbw_max > range) ? range : mpam_cfg->mbw_max; mpam_set_feature(mpam_feat_mbw_max, &mpam_cfg->valid); } } else {