hulk inclusion category: feature bugzilla: https://atomgit.com/openeuler/kernel/issues/9840 ------------------ Refactor the MBM (Memory Bandwidth Monitoring) update path to allow arch-specific selection of which events to sample. Previously, mbm_update() hardcoded checks for QOS_L3_MBM_TOTAL_EVENT_ID, QOS_L3_MBM_LOCAL_EVENT_ID, and QOS_L2_MBM_CORE_OVERFLOW_EVENT_ID, coupling the generic resctrl code to x86-specific event IDs. This patch introduces resctrl_arch_mbm_update() as an arch-specific hook that decides which MBM events to update: - x86/rdt: Samples L3 MBM total and local bandwidth events, same as before. - ARM/MPAM: Samples MBA total/local or L2 core overflow events, depending on the resource type. Extracts the per-event sampling logic into a new generic helper resctrl_mbm_update_one(), which handles the allocation of monitor context, event counting, and context freeing for a single event type. Adds a 'res' pointer to struct rdt_domain so that the MPAM implementation can determine the resource type from the domain. This enables MPAM platforms to handle MBM overflow detection correctly without polluting the generic code with platform-specific event logic. Signed-off-by: Zeng Heng <zengheng4@huawei.com> --- drivers/platform/mpam/mpam_resctrl.c | 31 ++++++++++++ fs/resctrl/monitor.c | 73 ++++++++-------------------- include/linux/resctrl.h | 6 +++ 3 files changed, 58 insertions(+), 52 deletions(-) diff --git a/drivers/platform/mpam/mpam_resctrl.c b/drivers/platform/mpam/mpam_resctrl.c index a8f8f1a802eae..c279ba142ca3d 100644 --- a/drivers/platform/mpam/mpam_resctrl.c +++ b/drivers/platform/mpam/mpam_resctrl.c @@ -133,6 +133,36 @@ void resctrl_arch_setup_res_mbm_over_exclude_cpu(unsigned int exclude_cpu) } } +void resctrl_arch_mbm_update(struct rdt_domain *d, + u32 closid, u32 rmid) +{ + switch (d->res->rid) { + case RDT_RESOURCE_MBA: + if (resctrl_arch_is_mbm_total_enabled()) + resctrl_mbm_update_one(d->res, d, + QOS_L3_MBM_TOTAL_EVENT_ID, + closid, rmid); + break; + + case RDT_RESOURCE_L3: + if (resctrl_arch_is_mbm_local_enabled()) + resctrl_mbm_update_one(d->res, d, + QOS_L3_MBM_LOCAL_EVENT_ID, + closid, rmid); + break; + + case RDT_RESOURCE_L2: + if (resctrl_arch_is_mbm_core_enabled() && !d->res->invisible) + resctrl_mbm_update_one(d->res, d, + QOS_L2_MBM_CORE_OVERFLOW_EVENT_ID, + closid, rmid); + break; + + default: + break; + } +} + bool resctrl_arch_get_cdp_enabled(enum resctrl_res_level rid) { switch (rid) { @@ -1818,6 +1848,7 @@ mpam_resctrl_alloc_domain(unsigned int cpu, struct mpam_resctrl_res *res) /* TODO: this list should be sorted */ list_add_tail(&dom->resctrl_dom.list, &res->resctrl_res.domains); + dom->resctrl_dom.res = &res->resctrl_res; return dom; } diff --git a/fs/resctrl/monitor.c b/fs/resctrl/monitor.c index 516a94d833d4d..b3eb1a02ac607 100644 --- a/fs/resctrl/monitor.c +++ b/fs/resctrl/monitor.c @@ -583,8 +583,9 @@ static void update_mba_bw(struct rdtgroup *rgrp, struct rdt_domain *dom_mbm) } } -static void mbm_update(struct rdt_resource *r, struct rdt_domain *d, - u32 closid, u32 rmid) +void resctrl_mbm_update_one(struct rdt_resource *r, struct rdt_domain *d, + enum resctrl_event_id evtid, + u32 closid, u32 rmid) { struct rmid_read rr; @@ -596,56 +597,26 @@ static void mbm_update(struct rdt_resource *r, struct rdt_domain *d, * This is protected from concurrent reads from user * as both the user and we hold the global mutex. */ - if (resctrl_arch_is_mbm_total_enabled()) { - rr.evtid = QOS_L3_MBM_TOTAL_EVENT_ID; - rr.val = 0; - rr.arch_mon_ctx = resctrl_arch_mon_ctx_alloc(rr.r, rr.evtid); - if (IS_ERR(rr.arch_mon_ctx)) { - pr_warn_ratelimited("Failed to allocate monitor context: %ld", - PTR_ERR(rr.arch_mon_ctx)); - return; - } - - __mon_event_count(closid, rmid, &rr); - - resctrl_arch_mon_ctx_free(rr.r, rr.evtid, rr.arch_mon_ctx); + rr.evtid = evtid; + rr.val = 0; + rr.arch_mon_ctx = resctrl_arch_mon_ctx_alloc(rr.r, rr.evtid); + if (IS_ERR(rr.arch_mon_ctx)) { + pr_warn_ratelimited("Failed to allocate monitor context: %ld", + PTR_ERR(rr.arch_mon_ctx)); + return; } - if (resctrl_arch_is_mbm_local_enabled()) { - rr.evtid = QOS_L3_MBM_LOCAL_EVENT_ID; - rr.val = 0; - rr.arch_mon_ctx = resctrl_arch_mon_ctx_alloc(rr.r, rr.evtid); - if (IS_ERR(rr.arch_mon_ctx)) { - pr_warn_ratelimited("Failed to allocate monitor context: %ld", - PTR_ERR(rr.arch_mon_ctx)); - return; - } - __mon_event_count(closid, rmid, &rr); + __mon_event_count(closid, rmid, &rr); - /* - * Call the MBA software controller only for the - * control groups and when user has enabled - * the software controller explicitly. - */ - if (is_mba_sc(NULL)) - mbm_bw_count(closid, rmid, &rr); - - resctrl_arch_mon_ctx_free(rr.r, rr.evtid, rr.arch_mon_ctx); - } - if (resctrl_arch_is_mbm_core_enabled()) { - rr.evtid = QOS_L2_MBM_CORE_OVERFLOW_EVENT_ID; - rr.val = 0; - rr.arch_mon_ctx = resctrl_arch_mon_ctx_alloc(rr.r, rr.evtid); - if (IS_ERR(rr.arch_mon_ctx)) { - pr_warn_ratelimited("Failed to allocate monitor context: %ld", - PTR_ERR(rr.arch_mon_ctx)); - return; - } - - __mon_event_count(closid, rmid, &rr); + /* + * Call the MBA software controller only for the + * control groups and when user has enabled + * the software controller explicitly. + */ + if ((evtid == QOS_L3_MBM_LOCAL_EVENT_ID) && is_mba_sc(NULL)) + mbm_bw_count(closid, rmid, &rr); - resctrl_arch_mon_ctx_free(rr.r, rr.evtid, rr.arch_mon_ctx); - } + resctrl_arch_mon_ctx_free(rr.r, rr.evtid, rr.arch_mon_ctx); } /* @@ -701,7 +672,6 @@ void mbm_handle_overflow(struct work_struct *work) unsigned long delay = msecs_to_jiffies(MBM_OVERFLOW_INTERVAL); struct rdtgroup *prgrp, *crgrp; struct list_head *head; - struct rdt_resource *r; struct rdt_domain *d; cpus_read_lock(); @@ -714,15 +684,14 @@ void mbm_handle_overflow(struct work_struct *work) if (!resctrl_mounted || !resctrl_arch_mon_capable()) goto out_unlock; - r = resctrl_arch_get_resource(RDT_RESOURCE_L3); d = container_of(work, struct rdt_domain, mbm_over.work); list_for_each_entry(prgrp, &rdt_all_groups, rdtgroup_list) { - mbm_update(r, d, prgrp->closid, prgrp->mon.rmid); + resctrl_arch_mbm_update(d, prgrp->closid, prgrp->mon.rmid); head = &prgrp->mon.crdtgrp_list; list_for_each_entry(crgrp, head, mon.crdtgrp_list) - mbm_update(r, d, crgrp->closid, crgrp->mon.rmid); + resctrl_arch_mbm_update(d, crgrp->closid, crgrp->mon.rmid); if (is_mba_sc(NULL)) update_mba_bw(prgrp, d); diff --git a/include/linux/resctrl.h b/include/linux/resctrl.h index a9ef4cfce2a62..1b8f89a5830e0 100644 --- a/include/linux/resctrl.h +++ b/include/linux/resctrl.h @@ -126,6 +126,7 @@ struct rdt_domain { struct pseudo_lock_region *plr; struct resctrl_staged_config staged_config[CDP_NUM_TYPES]; u32 *mbps_val; + struct rdt_resource *res; /* Just for MPAM */ }; /** @@ -479,6 +480,11 @@ void resctrl_setup_dom_overflow_exclude_cpu(struct rdt_resource *r, void resctrl_arch_setup_res_mbm_over(void); void resctrl_arch_setup_res_mbm_over_exclude_cpu(unsigned int exclude_cpu); +void resctrl_mbm_update_one(struct rdt_resource *r, struct rdt_domain *d, + enum resctrl_event_id evtid, + u32 closid, u32 rmid); +void resctrl_arch_mbm_update(struct rdt_domain *d, u32 closid, u32 rmid); + /* 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