From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0B48A2D2394 for ; Sun, 2 Aug 2026 16:16:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=198.175.65.17 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785687393; cv=none; b=JckYL8gCeTjgtyyuigOIG/zSLDRJ3yyOC8GP0rU/blBxFksKZ6AM080CRcCOXo+Q7GaftowZ6j1VZ59ddBosnru3PgRX+AlqbqGi7gYCR957qbmO3UThPlZIVLyBAqVZ6nNNBlhkF1KeHefnOX/sXKAgokb455elEjqUz/zObTY= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785687393; c=relaxed/simple; bh=kNFD/0WZ+hOR8CmbPogk6xDROkIUfejdde4yvR5UYZA=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version:Content-Type; b=b4uKfIX7MblM8cJFJjuDjPzHAxgFAD8sNdblW5cLG2ThXpcdHARba6Fkz/J1BC2eLmRs2GivtB8bcJO1eHopEMmfcv566ao81+SwXeFHo9/B5311zcTNQ5i0s+8Go6mhtY4bAt0NDkYQxBKB1icoHjoog/Jxljk3kZixrm/WT2M= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com; spf=pass smtp.mailfrom=intel.com; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b=BfUT0432; arc=none smtp.client-ip=198.175.65.17 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=intel.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=intel.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=intel.com header.i=@intel.com header.b="BfUT0432" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1785687392; x=1817223392; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=kNFD/0WZ+hOR8CmbPogk6xDROkIUfejdde4yvR5UYZA=; b=BfUT0432qfEjDRn96wvpVtFleTe/jGMnVnBgkD29glJK/VfnYvGKacp0 MZ/QjIEcqpG1tQUuUqJRo0bgy8MnVACRAZmXyP//+UiefMKN61icTVQDT qHpyhyCwLi/6AWLAoD1Ck2Lvi3pqLQE/dxiQZFmUYw1uLiSLub+hQqnlA dEvO2EC/e4cI+28r7bAGPdmP0Bj/DwavYDZnfFaeXaedLp6wSNlVb0o56 xOl5lNE7pvOOgiEo1DMyeJG7hR/IWMPhoMx0G/tj843P9nFtAaurqDnzI dCQEP00458YwHXJsOuDpggr7sl99G/D8FtIOXGRjsooZP7KwQetouJeWQ Q==; X-CSE-ConnectionGUID: AFBooVvkQeyQu8RoBKTAoQ== X-CSE-MsgGUID: C7j/EXLvSOCTCHTjkmpSOQ== X-IronPort-AV: E=McAfee;i="6800,10657,11863"; a="86257927" X-IronPort-AV: E=Sophos;i="6.25,200,1779174000"; d="scan'208";a="86257927" Received: from orviesa002.jf.intel.com ([10.64.159.142]) by orvoesa109.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 02 Aug 2026 09:16:31 -0700 X-CSE-ConnectionGUID: kWyaX0K4RjSPU43T1fe9tg== X-CSE-MsgGUID: mw7HWmS1TOiEIMF+lix3pw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.25,200,1779174000"; d="scan'208";a="290950210" Received: from chenyu-dev.sh.intel.com ([10.239.62.107]) by orviesa002.jf.intel.com with ESMTP; 02 Aug 2026 09:16:29 -0700 From: Chen Yu To: Reinette Chatre , Tony Luck Cc: Ben Horgan , "James Morse" , Dave Martin , Babu Moger , Fenghua Yu , Borislav Petkov , Thomas Gleixner , "Dave Hansen" , Peter Newman , chen.yu@linux.dev, x86@kernel.org, linux-kernel@vger.kernel.org Subject: [RFC PATCH 19/31] x86/resctrl: Enable the region based events by adding them into the event Date: Mon, 3 Aug 2026 00:06:47 +0800 Message-Id: <206a64de43ae160725366161883d095d7f1cd0f3.1785680802.git.yu.c.chen@intel.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The following MBM events will be displayed under each domain: [root@ mon_data]# tree . ├── mon_L3_00 │ ├── llc_occupancy │ ├── mbm_region0_bytes │ └── mbm_region1_bytes ├── mon_L3_01 │ ├── llc_occupancy │ ├── mbm_region0_bytes │ └── mbm_region1_bytes ├── mon_L3_02 │ ├── llc_occupancy │ ├── mbm_region0_bytes │ └── mbm_region1_bytes └── mon_L3_03 ├── llc_occupancy ├── mbm_region0_bytes └── mbm_region1_bytes Note, the actual maximum number of available memory regions is provided by the MRRM table. Suppose the maximum number of available memory regions exposed by MRRM is 2; then each domain can access at most 2 regions. Region-aware MBM counters live in MMIO rather than in the QM_CTR MSR, so resctrl_arch_reset_rmid() must read the initial counter value through erdt_mon_read() instead of __rmid_read_phys(). Add a "first" parameter to tell erdt_read_region_mbm() which kind of read this is: when set, only record the raw counter value in am->prev_mon_val so that later reads can compute a delta from it, without accumulating that absolute value into am->chunks as if it had been consumed. Signed-off-by: Chen Yu --- arch/x86/kernel/cpu/resctrl/core.c | 8 +++++ arch/x86/kernel/cpu/resctrl/erdt.c | 48 +++++++++++++++++++++++--- arch/x86/kernel/cpu/resctrl/internal.h | 4 ++- arch/x86/kernel/cpu/resctrl/monitor.c | 14 ++++++-- fs/resctrl/monitor.c | 4 +++ include/linux/resctrl_types.h | 2 ++ 6 files changed, 71 insertions(+), 9 deletions(-) diff --git a/arch/x86/kernel/cpu/resctrl/core.c b/arch/x86/kernel/cpu/resctrl/core.c index a7322f0ebaea..1827e3ea5fee 100644 --- a/arch/x86/kernel/cpu/resctrl/core.c +++ b/arch/x86/kernel/cpu/resctrl/core.c @@ -1081,6 +1081,13 @@ static __init bool get_rdt_mon_resources(void) resctrl_enable_mon_event(QOS_L3_OCCUP_EVENT_ID, false, 0, NULL); ret = true; } + + if (erdt_enable_mon()) { + ret = true; + + goto done; + } + if (rdt_cpu_has(X86_FEATURE_CQM_MBM_TOTAL)) { resctrl_enable_mon_event(QOS_L3_MBM_TOTAL_EVENT_ID, false, 0, NULL); ret = true; @@ -1092,6 +1099,7 @@ static __init bool get_rdt_mon_resources(void) if (rdt_cpu_has(X86_FEATURE_ABMC)) ret = true; +done: if (!ret) return false; diff --git a/arch/x86/kernel/cpu/resctrl/erdt.c b/arch/x86/kernel/cpu/resctrl/erdt.c index 35217f48b3d9..d16cd6af6648 100644 --- a/arch/x86/kernel/cpu/resctrl/erdt.c +++ b/arch/x86/kernel/cpu/resctrl/erdt.c @@ -49,9 +49,30 @@ bool erdt_support(int flag) if (flag == X86_FEATURE_CQM_OCCUP_LLC) return valid_subtbl_mask & BIT(ACPI_ERDT_TYPE_CMRC); + if (flag == X86_FEATURE_CQM_MBM_TOTAL) + return valid_subtbl_mask & BIT(ACPI_ERDT_TYPE_MMRC); + return false; } +bool erdt_enable_mon(void) +{ + int i, max_regions; + + if (!erdt_cpu_has(X86_FEATURE_CQM_MBM_TOTAL)) + return false; + + max_regions = acpi_mrrm_max_mem_region(); + for_each_rmbm_event_id(i) { + if (!max_regions--) + break; + + resctrl_enable_mon_event(i, true, 0, NULL); + } + + return true; +} + int erdt_get_max_rmid(void) { return erdt_max_rmid; @@ -130,9 +151,9 @@ static u64 apply_correction_factor(u64 val, u32 factor) static int erdt_read_region_mbm(struct rdt_domain_hdr *hdr, const struct erdt_domain_info *d, int rmid, - int eventid, u64 *val) + int eventid, u64 *val, bool first) { - int region_idx = eventid - QOS_L3_MBM_R0_EVENT_ID; + int region_idx = RMBM_STATE_IDX(eventid); int corr_factor_len, corr_factor = 0; struct rdt_hw_l3_mon_domain *hw_dom; u64 mbm_rmid_count = 0, chunks = 0; @@ -163,6 +184,23 @@ static int erdt_read_region_mbm(struct rdt_domain_hdr *hdr, (mbm_rmid_count & UNAVAILABLE_COUNTER)) return -EINVAL; + am = get_arch_mbm_state(hw_dom, rmid, eventid); + + /* + * The first read only records the initial, non-zero count value so + * that later reads can compute a delta from it. Nothing is reported + * to the caller, and the software state must not accumulate the + * absolute counter value as if it had been consumed. + */ + if (first) { + if (am) + am->prev_mon_val = mbm_rmid_count; + + *val = 0; + + return 0; + } + corr_factor_len = mmrc->corr_factor_list_len; if (corr_factor_len) { /* @@ -181,7 +219,6 @@ static int erdt_read_region_mbm(struct rdt_domain_hdr *hdr, return -EINVAL; } - am = get_arch_mbm_state(hw_dom, rmid, eventid); if (am) { am->chunks += mbm_overflow_count(am->prev_mon_val, mbm_rmid_count, mmrc->counter_width); @@ -195,7 +232,8 @@ static int erdt_read_region_mbm(struct rdt_domain_hdr *hdr, return 0; } -int erdt_mon_read(struct rdt_domain_hdr *hdr, enum resctrl_event_id evtid, u32 rmid, u64 *val) +int erdt_mon_read(struct rdt_domain_hdr *hdr, enum resctrl_event_id evtid, u32 rmid, + u64 *val, bool first) { struct rdt_hw_l3_mon_domain *hw_dom; const struct erdt_domain_info *d; @@ -209,7 +247,7 @@ int erdt_mon_read(struct rdt_domain_hdr *hdr, enum resctrl_event_id evtid, u32 r return erdt_read_l3_occupancy(d, rmid, val); if (rmbm_event(evtid)) - return erdt_read_region_mbm(hdr, d, rmid, evtid, val); + return erdt_read_region_mbm(hdr, d, rmid, evtid, val, first); return -EIO; } diff --git a/arch/x86/kernel/cpu/resctrl/internal.h b/arch/x86/kernel/cpu/resctrl/internal.h index b665b19b6f8b..c48e8d4a62d5 100644 --- a/arch/x86/kernel/cpu/resctrl/internal.h +++ b/arch/x86/kernel/cpu/resctrl/internal.h @@ -315,8 +315,10 @@ static inline bool intel_handle_aet_option(bool force_off, char *tok) { return f bool erdt_support(int flag); bool erdt_cpu_has(int flag); +bool erdt_enable_mon(void); int erdt_get_max_rmid(void); -int erdt_mon_read(struct rdt_domain_hdr *hdr, enum resctrl_event_id evtid, u32 rmid, u64 *val); +int erdt_mon_read(struct rdt_domain_hdr *hdr, enum resctrl_event_id evtid, u32 rmid, + u64 *val, bool first); int erdt_init(void); void erdt_exit(void); diff --git a/arch/x86/kernel/cpu/resctrl/monitor.c b/arch/x86/kernel/cpu/resctrl/monitor.c index c60d3d55a96c..21dd33eaafe9 100644 --- a/arch/x86/kernel/cpu/resctrl/monitor.c +++ b/arch/x86/kernel/cpu/resctrl/monitor.c @@ -179,14 +179,19 @@ void resctrl_arch_reset_rmid(struct rdt_resource *r, struct rdt_l3_mon_domain *d int cpu = cpumask_any(&d->hdr.cpu_mask); struct arch_mbm_state *am; u32 prmid; + u64 tmp; am = get_arch_mbm_state(hw_dom, rmid, eventid); if (am) { memset(am, 0, sizeof(*am)); - prmid = logical_rmid_to_physical_rmid(cpu, rmid); /* Record any initial, non-zero count value. */ - __rmid_read_phys(prmid, eventid, &am->prev_mon_val); + if (rmbm_event(eventid) && erdt_cpu_has(X86_FEATURE_CQM_MBM_TOTAL)) { + erdt_mon_read(&d->hdr, eventid, rmid, &tmp, true); + } else { + prmid = logical_rmid_to_physical_rmid(cpu, rmid); + __rmid_read_phys(prmid, eventid, &am->prev_mon_val); + } } } @@ -280,7 +285,10 @@ int resctrl_arch_rmid_read(struct rdt_resource *r, struct rdt_domain_hdr *hdr, case RDT_RESOURCE_L3: if (eventid == QOS_L3_OCCUP_EVENT_ID && erdt_cpu_has(X86_FEATURE_CQM_OCCUP_LLC)) - return erdt_mon_read(hdr, eventid, rmid, val); + return erdt_mon_read(hdr, eventid, rmid, val, false); + + if (rmbm_event(eventid) && erdt_cpu_has(X86_FEATURE_CQM_MBM_TOTAL)) + return erdt_mon_read(hdr, eventid, rmid, val, false); return arch_l3_read_event(hdr, rmid, eventid, val, r); case RDT_RESOURCE_PERF_PKG: diff --git a/fs/resctrl/monitor.c b/fs/resctrl/monitor.c index aadac544576b..0a5a38b8ffda 100644 --- a/fs/resctrl/monitor.c +++ b/fs/resctrl/monitor.c @@ -1031,6 +1031,10 @@ struct mon_evt mon_event_all[QOS_NUM_EVENTS] = { MON_EVENT(PMT_EVENT_AUTO_C6_RES, "c6_res", RDT_RESOURCE_PERF_PKG, false), MON_EVENT(PMT_EVENT_UNHALTED_REF_CYCLES, "unhalted_ref_cycles", RDT_RESOURCE_PERF_PKG, false), MON_EVENT(PMT_EVENT_UOPS_RETIRED, "uops_retired", RDT_RESOURCE_PERF_PKG, false), + MON_EVENT(QOS_L3_MBM_R0_EVENT_ID, "mbm_region0_bytes", RDT_RESOURCE_L3, false), + MON_EVENT(QOS_L3_MBM_R1_EVENT_ID, "mbm_region1_bytes", RDT_RESOURCE_L3, false), + MON_EVENT(QOS_L3_MBM_R2_EVENT_ID, "mbm_region2_bytes", RDT_RESOURCE_L3, false), + MON_EVENT(QOS_L3_MBM_R3_EVENT_ID, "mbm_region3_bytes", RDT_RESOURCE_L3, false), }; bool resctrl_enable_mon_event(enum resctrl_event_id eventid, bool any_cpu, diff --git a/include/linux/resctrl_types.h b/include/linux/resctrl_types.h index ee8fc7df22f9..95945dd71472 100644 --- a/include/linux/resctrl_types.h +++ b/include/linux/resctrl_types.h @@ -82,6 +82,8 @@ static inline bool rmbm_event(unsigned int e) return (e >= QOS_L3_MBM_R0_EVENT_ID) && (e <= QOS_L3_MBM_R3_EVENT_ID); } +#define RMBM_STATE_IDX(evt) ((evt) - QOS_L3_MBM_R0_EVENT_ID) + #define QOS_NUM_L3_MBM_EVENTS (QOS_L3_MBM_R3_EVENT_ID - QOS_L3_MBM_TOTAL_EVENT_ID + 1) #define MBM_STATE_IDX(evt) ((evt) - QOS_L3_MBM_TOTAL_EVENT_ID) -- 2.43.0