Message ID | 20230815152712.1760046-10-amitsinght@marvell.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | ARM: MPAM: add support for priority partitioning control | expand |
Hi, Amit, On 8/15/23 08:27, Amit Singh Tomar wrote: > Currently, Users can pass the configurations for CPBM, and MBA through > schemata file. For instance, CPBM can be passed using: > > echo L3:0=ffff > schemata > > This change allows, users to pass a new configuration for downstream > priority along with CPBM. For instance, dspri value of "0xa" can be > passed as: > > echo L3:0=ffff,a > schemata > > Signed-off-by: Amit Singh Tomar <amitsinght@marvell.com> > --- > fs/resctrl/ctrlmondata.c | 92 ++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 92 insertions(+) > > diff --git a/fs/resctrl/ctrlmondata.c b/fs/resctrl/ctrlmondata.c > index ffeb68270968..b444adee2002 100644 > --- a/fs/resctrl/ctrlmondata.c > +++ b/fs/resctrl/ctrlmondata.c > @@ -30,6 +30,74 @@ typedef int (ctrlval_parser_t)(struct rdt_parse_data *data, > struct resctrl_schema *s, > struct rdt_domain *d); > > +static bool dspri_validate(char *buf, unsigned long *data, struct rdt_resource *r) > +{ > + > + char *dup_buf, *dspri_token; > + unsigned long dspri_val; > + bool success = true; > + int ret; > + > + dup_buf = kstrdup(buf, GFP_KERNEL); > + if (!dup_buf) { > + rdt_last_cmd_printf("Failed to allocate buffer %s\n", > + __func__); > + success = false; > + goto out; > + } > + > + strsep(&dup_buf, ","); > + if (!dup_buf) { > + rdt_last_cmd_printf("Unable to find priority value token %s\n", > + __func__); > + success = false; > + goto out; > + } > + > + dspri_token = strsep(&dup_buf, ","); > + ret = kstrtoul(dspri_token, 16, &dspri_val); > + if (ret) { > + rdt_last_cmd_printf("Non-hex character in the mask %s\n", buf); > + success = false; > + goto out; > + } > + > + if (dspri_val > r->dspri_default_ctrl) { > + rdt_last_cmd_printf("dspri value %ld out of range [%d-%d]\n", dspri_val, > + 0, r->dspri_default_ctrl); > + success = false; > + goto out; > + } > + > + *data = dspri_val; > + > +out: > + kfree(dup_buf); > + return success; > +} > + > +static int parse_dspri(struct rdt_parse_data *data, struct resctrl_schema *s, > + struct rdt_domain *d) > +{ > + struct resctrl_staged_config *cfg; > + struct rdt_resource *r = s->res; > + unsigned long pri_val; > + > + cfg = &d->staged_config[s->conf_type]; > + if (cfg->have_new_ctrl) { > + rdt_last_cmd_printf("Duplicate domain %d\n", d->id); > + return -EINVAL; > + } > + > + if (!dspri_validate(data->buf, &pri_val, r)) > + return -EINVAL; > + > + cfg->new_ctrl = pri_val; > + cfg->have_new_ctrl = true; > + > + return 0; > +} > + > /* > * Check whether MBA bandwidth percentage value is correct. The value is > * checked against the minimum and max bandwidth values specified by the > @@ -293,6 +361,8 @@ static int rdtgroup_parse_resource(char *resname, char *tok, > ssize_t rdtgroup_schemata_write(struct kernfs_open_file *of, > char *buf, size_t nbytes, loff_t off) > { > + char *dup_buf = kstrdup(buf, GFP_KERNEL); > + struct rdt_parse_data data; > struct resctrl_schema *s; > struct rdtgroup *rdtgrp; > struct rdt_domain *dom; > @@ -354,10 +424,32 @@ ssize_t rdtgroup_schemata_write(struct kernfs_open_file *of, > if (is_mba_sc(r)) > continue; > > + if (r->priority_cap) > + r->dspri_store = false; > + > if (!strcmp(resname, s->name)) { > ret = resctrl_arch_update_domains(r, rdtgrp->closid); > if (ret) > goto out; > + > + if (r->priority_cap) { > + r->dspri_store = true; > + list_for_each_entry(dom, &r->domains, list) { > + ctrlval_parser_t *parse_ctrlval = &parse_dspri; > + char *dom_data = NULL; > + > + dom_data = strsep(&dup_buf, ";"); > + dom_data = strim(dom_data); > + data.buf = dom_data; > + data.rdtgrp = rdtgrp; > + if (parse_ctrlval(&data, s, dom)) Can this parse be called within parse_line()? So parsing and validation are before real write. If any parsing error, no write. Otherwise, partial write or roll back may happen. > + return -EINVAL; > + } > + > + ret = resctrl_arch_update_domains(r, rdtgrp->closid); > + if (ret) > + goto out; r->dspri_store = false here? > + } > } > } > Thanks. -Fenghua
Hi, Amit, On 8/15/23 08:27, Amit Singh Tomar wrote: > Currently, Users can pass the configurations for CPBM, and MBA through > schemata file. For instance, CPBM can be passed using: > > echo L3:0=ffff > schemata > > This change allows, users to pass a new configuration for downstream > priority along with CPBM. For instance, dspri value of "0xa" can be > passed as: > > echo L3:0=ffff,a > schemata > > Signed-off-by: Amit Singh Tomar <amitsinght@marvell.com> > --- > fs/resctrl/ctrlmondata.c | 92 ++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 92 insertions(+) > > diff --git a/fs/resctrl/ctrlmondata.c b/fs/resctrl/ctrlmondata.c > index ffeb68270968..b444adee2002 100644 > --- a/fs/resctrl/ctrlmondata.c > +++ b/fs/resctrl/ctrlmondata.c > @@ -30,6 +30,74 @@ typedef int (ctrlval_parser_t)(struct rdt_parse_data *data, > struct resctrl_schema *s, > struct rdt_domain *d); > > +static bool dspri_validate(char *buf, unsigned long *data, struct rdt_resource *r) > +{ > + > + char *dup_buf, *dspri_token; > + unsigned long dspri_val; > + bool success = true; > + int ret; > + > + dup_buf = kstrdup(buf, GFP_KERNEL); > + if (!dup_buf) { > + rdt_last_cmd_printf("Failed to allocate buffer %s\n", > + __func__); > + success = false; > + goto out; > + } > + > + strsep(&dup_buf, ","); > + if (!dup_buf) { > + rdt_last_cmd_printf("Unable to find priority value token %s\n", > + __func__); > + success = false; > + goto out; > + } > + > + dspri_token = strsep(&dup_buf, ","); > + ret = kstrtoul(dspri_token, 16, &dspri_val); > + if (ret) { > + rdt_last_cmd_printf("Non-hex character in the mask %s\n", buf); > + success = false; > + goto out; > + } > + > + if (dspri_val > r->dspri_default_ctrl) { > + rdt_last_cmd_printf("dspri value %ld out of range [%d-%d]\n", dspri_val, > + 0, r->dspri_default_ctrl); > + success = false; > + goto out; > + } > + > + *data = dspri_val; > + > +out: > + kfree(dup_buf); > + return success; > +} > + > +static int parse_dspri(struct rdt_parse_data *data, struct resctrl_schema *s, > + struct rdt_domain *d) > +{ > + struct resctrl_staged_config *cfg; > + struct rdt_resource *r = s->res; > + unsigned long pri_val; > + > + cfg = &d->staged_config[s->conf_type]; > + if (cfg->have_new_ctrl) { > + rdt_last_cmd_printf("Duplicate domain %d\n", d->id); > + return -EINVAL; > + } > + > + if (!dspri_validate(data->buf, &pri_val, r)) > + return -EINVAL; > + > + cfg->new_ctrl = pri_val; > + cfg->have_new_ctrl = true; > + > + return 0; > +} > + > /* > * Check whether MBA bandwidth percentage value is correct. The value is > * checked against the minimum and max bandwidth values specified by the > @@ -293,6 +361,8 @@ static int rdtgroup_parse_resource(char *resname, char *tok, > ssize_t rdtgroup_schemata_write(struct kernfs_open_file *of, > char *buf, size_t nbytes, loff_t off) > { > + char *dup_buf = kstrdup(buf, GFP_KERNEL); kstrdup() may fail. Need to check NULL for failure. dup_buf needs to be freed. I don't see it's freed. > + struct rdt_parse_data data; > struct resctrl_schema *s; > struct rdtgroup *rdtgrp; > struct rdt_domain *dom; > @@ -354,10 +424,32 @@ ssize_t rdtgroup_schemata_write(struct kernfs_open_file *of, > if (is_mba_sc(r)) > continue; > > + if (r->priority_cap) > + r->dspri_store = false; > + > if (!strcmp(resname, s->name)) { > ret = resctrl_arch_update_domains(r, rdtgrp->closid); > if (ret) > goto out; > + > + if (r->priority_cap) { > + r->dspri_store = true; > + list_for_each_entry(dom, &r->domains, list) { > + ctrlval_parser_t *parse_ctrlval = &parse_dspri; > + char *dom_data = NULL; > + > + dom_data = strsep(&dup_buf, ";"); > + dom_data = strim(dom_data); > + data.buf = dom_data; > + data.rdtgrp = rdtgrp; > + if (parse_ctrlval(&data, s, dom)) > + return -EINVAL; > + } > + > + ret = resctrl_arch_update_domains(r, rdtgrp->closid); > + if (ret) > + goto out; > + } > } > } > Thanks. -Fenghua
diff --git a/fs/resctrl/ctrlmondata.c b/fs/resctrl/ctrlmondata.c index ffeb68270968..b444adee2002 100644 --- a/fs/resctrl/ctrlmondata.c +++ b/fs/resctrl/ctrlmondata.c @@ -30,6 +30,74 @@ typedef int (ctrlval_parser_t)(struct rdt_parse_data *data, struct resctrl_schema *s, struct rdt_domain *d); +static bool dspri_validate(char *buf, unsigned long *data, struct rdt_resource *r) +{ + + char *dup_buf, *dspri_token; + unsigned long dspri_val; + bool success = true; + int ret; + + dup_buf = kstrdup(buf, GFP_KERNEL); + if (!dup_buf) { + rdt_last_cmd_printf("Failed to allocate buffer %s\n", + __func__); + success = false; + goto out; + } + + strsep(&dup_buf, ","); + if (!dup_buf) { + rdt_last_cmd_printf("Unable to find priority value token %s\n", + __func__); + success = false; + goto out; + } + + dspri_token = strsep(&dup_buf, ","); + ret = kstrtoul(dspri_token, 16, &dspri_val); + if (ret) { + rdt_last_cmd_printf("Non-hex character in the mask %s\n", buf); + success = false; + goto out; + } + + if (dspri_val > r->dspri_default_ctrl) { + rdt_last_cmd_printf("dspri value %ld out of range [%d-%d]\n", dspri_val, + 0, r->dspri_default_ctrl); + success = false; + goto out; + } + + *data = dspri_val; + +out: + kfree(dup_buf); + return success; +} + +static int parse_dspri(struct rdt_parse_data *data, struct resctrl_schema *s, + struct rdt_domain *d) +{ + struct resctrl_staged_config *cfg; + struct rdt_resource *r = s->res; + unsigned long pri_val; + + cfg = &d->staged_config[s->conf_type]; + if (cfg->have_new_ctrl) { + rdt_last_cmd_printf("Duplicate domain %d\n", d->id); + return -EINVAL; + } + + if (!dspri_validate(data->buf, &pri_val, r)) + return -EINVAL; + + cfg->new_ctrl = pri_val; + cfg->have_new_ctrl = true; + + return 0; +} + /* * Check whether MBA bandwidth percentage value is correct. The value is * checked against the minimum and max bandwidth values specified by the @@ -293,6 +361,8 @@ static int rdtgroup_parse_resource(char *resname, char *tok, ssize_t rdtgroup_schemata_write(struct kernfs_open_file *of, char *buf, size_t nbytes, loff_t off) { + char *dup_buf = kstrdup(buf, GFP_KERNEL); + struct rdt_parse_data data; struct resctrl_schema *s; struct rdtgroup *rdtgrp; struct rdt_domain *dom; @@ -354,10 +424,32 @@ ssize_t rdtgroup_schemata_write(struct kernfs_open_file *of, if (is_mba_sc(r)) continue; + if (r->priority_cap) + r->dspri_store = false; + if (!strcmp(resname, s->name)) { ret = resctrl_arch_update_domains(r, rdtgrp->closid); if (ret) goto out; + + if (r->priority_cap) { + r->dspri_store = true; + list_for_each_entry(dom, &r->domains, list) { + ctrlval_parser_t *parse_ctrlval = &parse_dspri; + char *dom_data = NULL; + + dom_data = strsep(&dup_buf, ";"); + dom_data = strim(dom_data); + data.buf = dom_data; + data.rdtgrp = rdtgrp; + if (parse_ctrlval(&data, s, dom)) + return -EINVAL; + } + + ret = resctrl_arch_update_domains(r, rdtgrp->closid); + if (ret) + goto out; + } } }
Currently, Users can pass the configurations for CPBM, and MBA through schemata file. For instance, CPBM can be passed using: echo L3:0=ffff > schemata This change allows, users to pass a new configuration for downstream priority along with CPBM. For instance, dspri value of "0xa" can be passed as: echo L3:0=ffff,a > schemata Signed-off-by: Amit Singh Tomar <amitsinght@marvell.com> --- fs/resctrl/ctrlmondata.c | 92 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+)