hulk inclusion category: feature bugzilla: https://atomgit.com/openeuler/kernel/issues/8420 ------------------ Signed-off-by: Zeng Heng <zengheng4@huawei.com> --- drivers/platform/mpam/mpam_devices.c | 13 ++- drivers/platform/mpam/mpam_internal.h | 2 +- drivers/platform/mpam/mpam_resctrl.c | 143 +++++++++++++++++++++----- fs/resctrl/monitor.c | 18 +++- include/linux/resctrl.h | 18 ++++ 5 files changed, 160 insertions(+), 34 deletions(-) diff --git a/drivers/platform/mpam/mpam_devices.c b/drivers/platform/mpam/mpam_devices.c index 0d4e83001ae6..4d05803192be 100644 --- a/drivers/platform/mpam/mpam_devices.c +++ b/drivers/platform/mpam/mpam_devices.c @@ -2580,18 +2580,17 @@ static int __write_config(void *arg) { int closid_num = resctrl_arch_get_num_closid(NULL); struct mpam_write_config_arg *c = arg; - u32 reqpartid, req_idx; + u32 reqpartid; /* This partid should be in the range of intPARTIDs */ WARN_ON_ONCE(c->partid >= closid_num); /* Synchronize the configuration to each sub-monitoring group. */ - for (req_idx = 0; req_idx < get_num_reqpartid_per_closid(); - req_idx++) { - reqpartid = req_idx * closid_num + c->partid; - - mpam_reprogram_ris_partid(c->ris, reqpartid, - &c->comp->cfg[c->partid]); + for (reqpartid = closid_num; + reqpartid < get_num_reqpartid(); reqpartid++) { + if (req2intpartid(reqpartid) == c->partid) + mpam_reprogram_ris_partid(c->ris, reqpartid, + &c->comp->cfg[c->partid]); } return 0; diff --git a/drivers/platform/mpam/mpam_internal.h b/drivers/platform/mpam/mpam_internal.h index 11564ee44025..3e9f150e358a 100644 --- a/drivers/platform/mpam/mpam_internal.h +++ b/drivers/platform/mpam/mpam_internal.h @@ -595,6 +595,6 @@ bool mpam_cpbm_hisi_check_invalid(struct rdt_resource *r, unsigned long val); int mpam_resctrl_prepare_offline(void); u32 req2intpartid(u32 reqpartid); -u32 get_num_reqpartid_per_closid(void); +u32 get_num_reqpartid(void); #endif /* MPAM_INTERNAL_H */ diff --git a/drivers/platform/mpam/mpam_resctrl.c b/drivers/platform/mpam/mpam_resctrl.c index 3b53eccda018..e277934e8138 100644 --- a/drivers/platform/mpam/mpam_resctrl.c +++ b/drivers/platform/mpam/mpam_resctrl.c @@ -151,16 +151,11 @@ u32 resctrl_arch_get_num_closid(struct rdt_resource *ignored) return mpam_intpartid_max + 1; } -static u32 get_num_reqpartid(void) +u32 get_num_reqpartid(void) { return mpam_partid_max + 1; } -u32 get_num_reqpartid_per_closid(void) -{ - return get_num_reqpartid() / resctrl_arch_get_num_closid(NULL); -} - u32 resctrl_arch_system_num_rmid_idx(void) { u8 closid_shift = fls(mpam_pmg_max); @@ -186,12 +181,28 @@ static u32 rmid2pmg(u32 rmid) return rmid & pmg_mask; } +static u32 req_pmg2rmid(u32 reqpartid, u32 pmg) +{ + u8 pmg_shift = fls(mpam_pmg_max); + u32 pmg_mask = ~(~0 << pmg_shift); + + return (reqpartid << pmg_shift) | (pmg & pmg_mask); +} + +static u32 *reqpartid_map; + u32 req2intpartid(u32 reqpartid) { - u8 intpartid_shift = fls(mpam_intpartid_max); - u32 intpartid_mask = ~(~0 << intpartid_shift); + WARN_ON_ONCE(reqpartid >= get_num_reqpartid()); - return reqpartid & intpartid_mask; + /* + * Directly return intPartid in case that mpam_reset_ris() access + * NULL pointer. + */ + if (reqpartid < resctrl_arch_get_num_closid(NULL)) + return reqpartid; + + return reqpartid_map[reqpartid]; } /* @@ -1202,6 +1213,78 @@ static int mpam_resctrl_resource_init(struct mpam_resctrl_res *res) return 0; } +static int reqpartid_init(void) +{ + int req_num, idx; + + req_num = get_num_reqpartid(); + reqpartid_map = kcalloc(req_num, sizeof(u32), GFP_KERNEL); + if (!reqpartid_map) + return -ENOMEM; + + for (idx = 0; idx < req_num; idx++) { + if (idx < resctrl_arch_get_num_closid(NULL)) + reqpartid_map[idx] = idx; + else + /* dummy intPartid */ + reqpartid_map[idx] = U32_MAX; + } + + return 0; +} + +void reqpartid_exit(void) +{ + kfree(reqpartid_map); +} + +void update_rmid_entries_for_reqpartid(u32 reqpartid) +{ + int pmg; + + for (pmg = 0; pmg <= mpam_pmg_max; pmg++) + update_rmid_entry(reqpartid_map[reqpartid], + req_pmg2rmid(reqpartid, pmg)); +} + +int resctrl_arch_expand_rmid(u32 intpartid) +{ + int i; + + for (i = resctrl_arch_get_num_closid(NULL); + i < get_num_reqpartid(); i++) { + if (reqpartid_map[i] == U32_MAX) { + reqpartid_map[i] = intpartid; + update_rmid_entries_for_reqpartid(i); + return i; + } + } + + return -ENOSPC; +} + +void resctrl_arch_shrink_rmid(u32 closid, u32 rmid) +{ + int pmg; + int reqpartid = rmid2reqpartid(rmid); + + if (reqpartid < resctrl_arch_get_num_closid(NULL)) + return; + + WARN_ON_ONCE(closid != req2intpartid(reqpartid)); + + for (pmg = 0; pmg <= mpam_pmg_max; pmg++) { + if (rmid_is_occupied(reqpartid_map[reqpartid], + req_pmg2rmid(reqpartid, pmg))) + break; + } + + if (pmg > mpam_pmg_max) { + reqpartid_map[reqpartid] = U32_MAX; + update_rmid_entries_for_reqpartid(reqpartid); + } +} + int mpam_resctrl_setup(void) { int err = 0; @@ -1233,24 +1316,35 @@ int mpam_resctrl_setup(void) } cpus_read_unlock(); - if (!err && !exposed_alloc_capable && !exposed_mon_capable) - err = -EOPNOTSUPP; - - if (!err) { - if (!is_power_of_2(mpam_pmg_max + 1)) { - /* - * If not all the partid*pmg values are valid indexes, - * resctrl may allocate pmg that don't exist. This - * should cause an error interrupt. - */ - pr_warn("Number of PMG is not a power of 2! resctrl may misbehave"); - } + if (err) + return err; + + if (!exposed_alloc_capable && !exposed_mon_capable) + return -EOPNOTSUPP; - err = resctrl_init(); - if (!err) - WRITE_ONCE(resctrl_enabled, true); + err = reqpartid_init(); + if (err) + return err; + + if (!is_power_of_2(mpam_pmg_max + 1)) { + /* + * If not all the partid*pmg values are valid indexes, + * resctrl may allocate pmg that don't exist. This + * should cause an error interrupt. + */ + pr_warn("Number of PMG is not a power of 2! resctrl may misbehave"); } + err = resctrl_init(); + if (err) + goto err; + + WRITE_ONCE(resctrl_enabled, true); + + return 0; + +err: + reqpartid_exit(); return err; } @@ -1261,6 +1355,7 @@ void mpam_resctrl_exit(void) WRITE_ONCE(resctrl_enabled, false); resctrl_exit(); + reqpartid_exit(); } u32 resctrl_arch_get_config(struct rdt_resource *r, struct rdt_domain *d, diff --git a/fs/resctrl/monitor.c b/fs/resctrl/monitor.c index b651b37e7e65..034d426d24e4 100644 --- a/fs/resctrl/monitor.c +++ b/fs/resctrl/monitor.c @@ -265,7 +265,7 @@ int alloc_rmid(u32 closid) if (IS_ERR(entry)) return PTR_ERR(entry); - list_del(&entry->list); + list_del_init(&entry->list); return entry->rmid; } @@ -324,6 +324,13 @@ void free_rmid(u32 closid, u32 rmid) list_add_tail(&entry->list, &rmid_free_lru); } +bool rmid_is_occupied(u32 closid, u32 rmid) +{ + u32 idx = resctrl_arch_rmid_idx_encode(closid, rmid); + + return list_empty(&rmid_ptrs[idx].list); +} + static struct mbm_state *get_mbm_state(struct rdt_domain *d, u32 closid, u32 rmid, enum resctrl_event_id evtid) { @@ -733,6 +740,13 @@ void mbm_setup_overflow_handler(struct rdt_domain *dom, unsigned long delay_ms, schedule_delayed_work_on(cpu, &dom->mbm_over, delay); } +void update_rmid_entry(u32 closid, u32 rmid) +{ + u32 idx = resctrl_arch_rmid_idx_encode(closid, rmid); + + rmid_ptrs[idx].closid = closid; +} + static int dom_data_init(struct rdt_resource *r) { u32 idx_limit = resctrl_arch_system_num_rmid_idx(); @@ -780,7 +794,7 @@ static int dom_data_init(struct rdt_resource *r) idx = resctrl_arch_rmid_idx_encode(RESCTRL_RESERVED_CLOSID, RESCTRL_RESERVED_RMID); entry = __rmid_entry(idx); - list_del(&entry->list); + list_del_init(&entry->list); out_unlock: mutex_unlock(&rdtgroup_mutex); diff --git a/include/linux/resctrl.h b/include/linux/resctrl.h index 958b1f39d016..4597bc0987e6 100644 --- a/include/linux/resctrl.h +++ b/include/linux/resctrl.h @@ -438,6 +438,24 @@ void resctrl_arch_reset_rmid_all(struct rdt_resource *r, struct rdt_domain *d); extern unsigned int resctrl_rmid_realloc_threshold; extern unsigned int resctrl_rmid_realloc_limit; +/** + * rmid_is_occupied() - Check whether the specified rmid has been allocated + * and is in use. + * @closid: Specify the closid that matches the rmid. + * @rmid: Specify the rmid entry to check status. + * + * Return: + * True if the specified rmid is still in use. + */ +bool rmid_is_occupied(u32 closid, u32 rmid); + +/** + * update_rmid_entry() - Update rmid entry content. + * @closid: Specify the closid that matches the rmid. + * @rmid: Specify the rmid entry to update content. + */ +void update_rmid_entry(u32 closid, u32 rmid); + extern bool resctrl_mounted; int resctrl_init(void); -- 2.25.1