hulk inclusion category: feature bugzilla: https://atomgit.com/openeuler/kernel/issues/9840 ------------------ L2 monitors are typically fewer than available RMIDs. To avoid false overflow detections, only perform MBM overflow checking for RMIDs that are currently being monitored by a physical monitor. Introduce mpam_skip_check_l2_overflow() to verify if the current monitoring configuration (partid-pmg pair) matches the saved state in mbwu_state. Skip overflow handling when no match is found, indicating the RMID is not actively monitored on this component. Add a new event type QOS_L2_MBM_CORE_OVERFLOW_EVENT_ID to distinguish overflow checking from regular MBM reads, allowing the skip logic to be applied only where needed. Signed-off-by: Zeng Heng <zengheng4@huawei.com> --- drivers/platform/mpam/mpam_devices.c | 3 ++ drivers/platform/mpam/mpam_resctrl.c | 42 ++++++++++++++++++++++++++++ fs/resctrl/monitor.c | 2 +- include/linux/resctrl_types.h | 1 + 4 files changed, 47 insertions(+), 1 deletion(-) diff --git a/drivers/platform/mpam/mpam_devices.c b/drivers/platform/mpam/mpam_devices.c index 60ab22fed7fde..d6e29f4fd710d 100644 --- a/drivers/platform/mpam/mpam_devices.c +++ b/drivers/platform/mpam/mpam_devices.c @@ -1086,6 +1086,9 @@ static void __ris_msmon_read(void *arg) if (mbwu_state) { reset_on_next_read = mbwu_state->reset_on_next_read; mbwu_state->reset_on_next_read = false; + + mbwu_state->cfg.partid = ctx->partid; + mbwu_state->cfg.pmg = ctx->pmg; } mbwu_overflow = read_msmon_mbwu_is_overflow(msc); diff --git a/drivers/platform/mpam/mpam_resctrl.c b/drivers/platform/mpam/mpam_resctrl.c index ad9e6b1ac7167..93d7d14753237 100644 --- a/drivers/platform/mpam/mpam_resctrl.c +++ b/drivers/platform/mpam/mpam_resctrl.c @@ -493,6 +493,42 @@ static enum mon_filter_options resctrl_evt_config_to_mpam(u32 local_evt_cfg) } } +/* + * Check whether to skip L2 MBM overflow checking for a given component. + * + * The number of L2 monitors is less than the number of RMIDs, so we only + * check MBM overflow for RMIDs currently being monitored by the monitor. + * When handling QOS_L2_MBM_CORE_OVERFLOW_EVENT_ID, we verify if the current + * monitoring configuration (partid/pmg) matches the previously saved one in + * mbwu_state. If they match, it means this RMID is still being monitored + * and we should proceed with overflow check. Otherwise, skip it. + * + * Returns: + * false - Don't skip, proceed with overflow check (partid/pmg match) + * true - Skip overflow check (no matching configuration found) + */ +static bool mpam_skip_check_l2_overflow(struct mpam_component *comp, + struct mon_cfg *cfg) +{ + bool ret; + unsigned long flags; + struct mpam_msc_ris *ris; + struct msmon_mbwu_state *mbwu_state; + + ris = list_first_or_null_rcu(&comp->ris, struct mpam_msc_ris, comp_list); + if (!ris) + return true; + + mbwu_state = &ris->mbwu_state[cfg->mon]; + + spin_lock_irqsave(&ris->msc->mon_sel_lock, flags); + ret = (mbwu_state->cfg.partid != cfg->partid || + mbwu_state->cfg.pmg != cfg->pmg); + spin_unlock_irqrestore(&ris->msc->mon_sel_lock, flags); + + return ret; +} + int resctrl_arch_rmid_read(struct rdt_resource *r, struct rdt_domain *d, u32 closid, u32 rmid, enum resctrl_event_id eventid, u64 *val, void *arch_mon_ctx) @@ -539,6 +575,12 @@ int resctrl_arch_rmid_read(struct rdt_resource *r, struct rdt_domain *d, cfg.partid = rmid2reqpartid(rmid); cfg.mon = cfg.partid % num_mon; + + if (eventid == QOS_L2_MBM_CORE_OVERFLOW_EVENT_ID) { + if (mpam_skip_check_l2_overflow(dom->comp, &cfg)) + return 0; + } + err = mpam_msmon_read(dom->comp, &cfg, type, val); if (err) return err; diff --git a/fs/resctrl/monitor.c b/fs/resctrl/monitor.c index e5eb971ee39da..516a94d833d4d 100644 --- a/fs/resctrl/monitor.c +++ b/fs/resctrl/monitor.c @@ -633,7 +633,7 @@ static void mbm_update(struct rdt_resource *r, struct rdt_domain *d, 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_EVENT_ID; + 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)) { diff --git a/include/linux/resctrl_types.h b/include/linux/resctrl_types.h index eaea801a85523..debba6674578c 100644 --- a/include/linux/resctrl_types.h +++ b/include/linux/resctrl_types.h @@ -120,6 +120,7 @@ enum resctrl_event_id { QOS_L2_OCCUP_EVENT_ID, QOS_L2_MBM_CORE_EVENT_ID, + QOS_L2_MBM_CORE_OVERFLOW_EVENT_ID, }; #endif /* CONFIG_X86_CPU_RESCTRL */ -- 2.43.0