hulk inclusion category: feature bugzilla: https://atomgit.com/openeuler/kernel/issues/9840 ------------------ Introduce resctrl_arch_setup_res_mbm_over() and resctrl_arch_setup_res_mbm_over_exclude_cpu() to abstract MBM overflow handling setup for different architectures. This abstraction is required because: * x86 only supports MBM on L3 cache, requiring single-resource setup. * ARM MPAM supports MBM on multiple resources (L2, L3, MBA), requiring iteration over all enabled resources. Add generic helper: * resctrl_setup_dom_overflow(): Set up overflow handlers for all domains in a resource * resctrl_setup_dom_overflow_exclude_cpu(): Re-setup handlers excluding a specific CPU (used during CPU hotplug) Refactor rdt_get_tree() and resctrl_offline_cpu() to use these helpers, eliminating hardcoded L3 dependencies. Signed-off-by: Zeng Heng <zengheng4@huawei.com> --- drivers/platform/mpam/mpam_resctrl.c | 34 ++++++++++++++++++++++ fs/resctrl/rdtgroup.c | 42 ++++++++++++++++++++-------- include/linux/resctrl.h | 7 +++++ 3 files changed, 71 insertions(+), 12 deletions(-) diff --git a/drivers/platform/mpam/mpam_resctrl.c b/drivers/platform/mpam/mpam_resctrl.c index 9c1d98791e225..ad9e6b1ac7167 100644 --- a/drivers/platform/mpam/mpam_resctrl.c +++ b/drivers/platform/mpam/mpam_resctrl.c @@ -99,6 +99,40 @@ bool resctrl_arch_is_mbm_enabled(enum resctrl_res_level rid) } } +void resctrl_arch_setup_res_mbm_over(void) +{ + struct mpam_resctrl_res *res; + int i; + + for (i = 0; i < RDT_NUM_RESOURCES; i++) { + res = &mpam_resctrl_exports[i]; + + if (!res->class) + continue; + + resctrl_setup_dom_overflow(&res->resctrl_res); + } +} + +void resctrl_arch_setup_res_mbm_over_exclude_cpu(unsigned int exclude_cpu) +{ + struct mpam_resctrl_res *res; + struct rdt_domain *d; + int i; + + for (i = 0; i < RDT_NUM_RESOURCES; i++) { + res = &mpam_resctrl_exports[i]; + + if (!res->class) + continue; + + d = resctrl_get_domain_from_cpu(exclude_cpu, &res->resctrl_res); + if (d) + resctrl_setup_dom_overflow_exclude_cpu(&res->resctrl_res, + d, exclude_cpu); + } +} + bool resctrl_arch_get_cdp_enabled(enum resctrl_res_level rid) { switch (rid) { diff --git a/fs/resctrl/rdtgroup.c b/fs/resctrl/rdtgroup.c index 139ea6bc446cd..b719eded4839b 100644 --- a/fs/resctrl/rdtgroup.c +++ b/fs/resctrl/rdtgroup.c @@ -2679,12 +2679,22 @@ static void schemata_list_destroy(void) } } +void resctrl_setup_dom_overflow(struct rdt_resource *r) +{ + struct rdt_domain *d; + + if (resctrl_arch_is_mbm_enabled(r->rid) && + resctrl_arch_would_mbm_overflow()) { + list_for_each_entry(d, &r->domains, list) + mbm_setup_overflow_handler(d, MBM_OVERFLOW_INTERVAL, + RESCTRL_PICK_ANY_CPU); + } +} + static int rdt_get_tree(struct fs_context *fc) { - struct rdt_resource *l3 = resctrl_arch_get_resource(RDT_RESOURCE_L3); struct rdt_fs_context *ctx = rdt_fc2context(fc); unsigned long flags = RFTYPE_CTRL_BASE; - struct rdt_domain *dom; int ret; cpus_read_lock(); @@ -2758,11 +2768,7 @@ static int rdt_get_tree(struct fs_context *fc) if (resctrl_arch_alloc_capable() || resctrl_arch_mon_capable()) resctrl_mounted = true; - if (resctrl_arch_is_mbm_enabled(l3->rid) && resctrl_arch_would_mbm_overflow()) { - list_for_each_entry(dom, &l3->domains, list) - mbm_setup_overflow_handler(dom, MBM_OVERFLOW_INTERVAL, - RESCTRL_PICK_ANY_CPU); - } + resctrl_arch_setup_res_mbm_over(); goto out; @@ -4188,6 +4194,21 @@ static void clear_childcpus(struct rdtgroup *r, unsigned int cpu) } } +void resctrl_setup_dom_overflow_exclude_cpu(struct rdt_resource *r, + struct rdt_domain *d, + unsigned int exclude_cpu) +{ + if (!d) + return; + + if (resctrl_arch_is_mbm_enabled(r->rid) && + exclude_cpu == d->mbm_work_cpu && + resctrl_arch_would_mbm_overflow()) { + cancel_delayed_work(&d->mbm_over); + mbm_setup_overflow_handler(d, 0, exclude_cpu); + } +} + void resctrl_offline_cpu(unsigned int cpu) { struct rdt_resource *l3 = resctrl_arch_get_resource(RDT_RESOURCE_L3); @@ -4207,11 +4228,6 @@ void resctrl_offline_cpu(unsigned int cpu) d = resctrl_get_domain_from_cpu(cpu, l3); if (d) { - if (resctrl_arch_is_mbm_enabled(l3->rid) && cpu == d->mbm_work_cpu && - resctrl_arch_would_mbm_overflow()) { - cancel_delayed_work(&d->mbm_over); - mbm_setup_overflow_handler(d, 0, cpu); - } if (resctrl_arch_is_llc_occupancy_enabled() && cpu == d->cqm_work_cpu && has_busy_rmid(d)) { cancel_delayed_work(&d->cqm_limbo); @@ -4219,6 +4235,8 @@ void resctrl_offline_cpu(unsigned int cpu) } } + resctrl_arch_setup_res_mbm_over_exclude_cpu(cpu); + out_unlock: mutex_unlock(&rdtgroup_mutex); } diff --git a/include/linux/resctrl.h b/include/linux/resctrl.h index dd3c2b660b393..6fb5e7ca29a26 100644 --- a/include/linux/resctrl.h +++ b/include/linux/resctrl.h @@ -473,6 +473,13 @@ void resctrl_exit(void); int resctrl_arch_mon_resource_init(void); void mbm_config_rftype_init(const char *config); +void resctrl_setup_dom_overflow(struct rdt_resource *r); +void resctrl_setup_dom_overflow_exclude_cpu(struct rdt_resource *r, + struct rdt_domain *d, + unsigned int exclude_cpu); +void resctrl_arch_setup_res_mbm_over(void); +void resctrl_arch_setup_res_mbm_over_exclude_cpu(unsigned int exclude_cpu); + /* When supported, the architecture must implement these */ #ifdef CONFIG_RESCTRL_IOMMU int resctrl_arch_set_iommu_closid_rmid(struct iommu_group *group, u32 closid, -- 2.43.0