From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.15]) (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 75797482D4 for ; Sun, 2 Aug 2026 16:16:24 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=192.198.163.15 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785687386; cv=none; b=G8nKDm08I+MmB5qpqkYr1bbZSZXgqNMdbzT7Pmr28fkD/FcMpHrIV2HBVyKB7i+uEmtXC+z5Z5gsGj9QGTCyZyjPWl0ZAaVgWp+4vfZvkFNGnVP3Q8wJWN+7f/s7LitQo23NoNXelC/CK++BJnNYot+CuuzBavUy76M7VLWcNOc= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1785687386; c=relaxed/simple; bh=mLUDy9g9Db7f+0HYyYgWuBW9Y5CKU9v3nhyzBbqixCs=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=G3iBTp5xJmo+yCYPRDfjjgaF+vgvZhkcFaPr+fSVIH80eJmU3Bqf14gqpxZmphuehS/eeUuaK4+MfrRHqQsbqEDJkDe+WcKNqAmgIEeE2QkqHYJO+1wmXQCeI85VNic4G+iXg35/iwZMzHxGJBZmadI0KDfUVb4wckeUH38PxPs= 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=luT5quda; arc=none smtp.client-ip=192.198.163.15 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="luT5quda" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1785687385; x=1817223385; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=mLUDy9g9Db7f+0HYyYgWuBW9Y5CKU9v3nhyzBbqixCs=; b=luT5qudakHV3cHJyQQJGLpdsMagPztawJ+N7b70m2o0PCtinTPRjkqsm 7nBLVdSurtmUCHYSLLxfvNEWbU+Dd3c/JzAoGBSYA5SCQWJouojRNHmuW 77iG0JCYgwps8y3g56cUu9LqbjH1ix1gL/SnFWmsHo0Q9Ek0IeUr3j0kP 0sKZvwl1f7ycVG/CcRqE08wJOZERc82FmW3cWFB5WvVkMhzonMQna7YIU BfKM+F+vRUEnHRbHXnD9UkDAY8xiYxU/zkfCby6EHHc8v6aB4soV9JjcC WGqoAfx6eO8jlOmr4fMpy8qaKIngo1VTAEdNUEJQ0mqG8z+UD5nwGuUXf Q==; X-CSE-ConnectionGUID: UJyWq5NqRlOX8zvRcYhStw== X-CSE-MsgGUID: bTzcZToYRPGUjmNTbUwd4Q== X-IronPort-AV: E=McAfee;i="6800,10657,11863"; a="86361372" X-IronPort-AV: E=Sophos;i="6.25,200,1779174000"; d="scan'208";a="86361372" Received: from orviesa003.jf.intel.com ([10.64.159.143]) by fmvoesa109.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 02 Aug 2026 09:16:24 -0700 X-CSE-ConnectionGUID: gBLdnOhNS+C2DqqD4AhEhA== X-CSE-MsgGUID: GDrNYdt/SUO/HmETwUwaUg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.25,200,1779174000"; d="scan'208";a="264484336" Received: from chenyu-dev.sh.intel.com ([10.239.62.107]) by orviesa003.jf.intel.com with ESMTP; 02 Aug 2026 09:16:20 -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 18/31] x86/resctrl: Introduce memory region based MBM read callback on MMIO space Date: Mon, 3 Aug 2026 00:06:38 +0800 Message-Id: <4852deb430e4fc8879a7b15e7abe07265b664d21.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-Transfer-Encoding: 8bit Enhance erdt_mon_read() to support region-based memory bandwidth reads, and implement the low-level MMIO-based region-aware erdt_read_region_mbm() to deal with region-aware MBM. Signed-off-by: Chen Yu --- arch/x86/kernel/cpu/resctrl/erdt.c | 102 +++++++++++++++++++++++++ arch/x86/kernel/cpu/resctrl/internal.h | 4 + arch/x86/kernel/cpu/resctrl/monitor.c | 8 +- include/linux/resctrl_types.h | 5 ++ 4 files changed, 115 insertions(+), 4 deletions(-) diff --git a/arch/x86/kernel/cpu/resctrl/erdt.c b/arch/x86/kernel/cpu/resctrl/erdt.c index a14de9eb8b88..35217f48b3d9 100644 --- a/arch/x86/kernel/cpu/resctrl/erdt.c +++ b/arch/x86/kernel/cpu/resctrl/erdt.c @@ -30,6 +30,8 @@ static bool erdt_enabled; /* Set in a monitoring counter when it holds no valid data to report. */ #define UNAVAILABLE_COUNTER BIT_ULL(63) #define CMRC_FLAG_UNAVAILABLE_BIT BIT(0) +#define MMRC_FLAG_UNAVAILABLE_BIT BIT(0) +#define FIXPOINT_LOW_BITS 16 /* Bitmask of valid sub-tables found in the first RMDD, used to ensure all RMDDs match. */ static u32 valid_subtbl_mask; @@ -96,6 +98,103 @@ static int erdt_read_l3_occupancy(const struct erdt_domain_info *d, u32 rmid, u6 return 0; } +static void __iomem *mmrc_index_function_1(const struct erdt_domain_info *d, + struct acpi_erdt_mmrc *mmrc, + int rmid, int region_idx) +{ + u64 blk_rmid, blk_offset; + void __iomem *vaddr; + + /* + * Block_to_locate_RMID# = floor((RMID# % 32) / 8) x 4 x 4096B; + * Offset_within_this_Block = (floor(((RMID#/32)x8)+RMID#%8) x + * 8B)+(Region# x 2048B); + * MMIO_ADDRESS_for_RMID#_Region# = + * MBM Register Block Base Address + Block_to_locate_RMID# + + * Offset_within_this_Block; + */ + blk_rmid = ((rmid % 32) / 8) * 4 * 4096; + blk_offset = ((rmid / 32) * 8 + (rmid % 8)) * 8 + region_idx * 2048; + vaddr = d->base[ERDT_MMIO_MMRC_BASE] + blk_rmid + blk_offset; + + return vaddr; +} + +static u64 apply_correction_factor(u64 val, u32 factor) +{ + if (!factor) + return val; + + return ((val * factor) >> FIXPOINT_LOW_BITS); +} + +static int erdt_read_region_mbm(struct rdt_domain_hdr *hdr, + const struct erdt_domain_info *d, int rmid, + int eventid, u64 *val) +{ + int region_idx = eventid - QOS_L3_MBM_R0_EVENT_ID; + int corr_factor_len, corr_factor = 0; + struct rdt_hw_l3_mon_domain *hw_dom; + u64 mbm_rmid_count = 0, chunks = 0; + struct acpi_erdt_mmrc *mmrc = NULL; + struct rdt_l3_mon_domain *mon_dom; + struct arch_mbm_state *am; + void __iomem *vaddr; + + mmrc = d->mmrc; + if (!mmrc) + return -EIO; + + if (!domain_header_is_valid(hdr, RESCTRL_MON_DOMAIN, RDT_RESOURCE_L3)) + return -EIO; + + mon_dom = container_of(hdr, struct rdt_l3_mon_domain, hdr); + hw_dom = resctrl_to_arch_mon_dom(mon_dom); + + vaddr = mmrc_index_function_1(d, mmrc, rmid, region_idx); + mbm_rmid_count = readq(vaddr); + + /* + * Bit 63 only reports whether the data is unavailable on domains that + * advertise support for it. Where it is not supported the bit is part + * of the counter and must not be interpreted as a status flag. + */ + if ((mmrc->flags & MMRC_FLAG_UNAVAILABLE_BIT) && + (mbm_rmid_count & UNAVAILABLE_COUNTER)) + return -EINVAL; + + corr_factor_len = mmrc->corr_factor_list_len; + if (corr_factor_len) { + /* + * 0: Do not apply a correction factor to + * the MBM values. + * 1: Apply a single correction factor. + * Max RMID+1: Apply the indicated indexed + * correction factor to the corresponding + * RMID value for MBM counter. + */ + if (corr_factor_len == 1) + corr_factor = mmrc->corr_factor_list[0]; + else if (rmid < corr_factor_len) + corr_factor = mmrc->corr_factor_list[rmid]; + else + 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); + + chunks = apply_correction_factor(am->chunks, corr_factor); + am->prev_mon_val = mbm_rmid_count; + } + + *val = chunks * mmrc->up_scale; + + return 0; +} + int erdt_mon_read(struct rdt_domain_hdr *hdr, enum resctrl_event_id evtid, u32 rmid, u64 *val) { struct rdt_hw_l3_mon_domain *hw_dom; @@ -109,6 +208,9 @@ int erdt_mon_read(struct rdt_domain_hdr *hdr, enum resctrl_event_id evtid, u32 r if (evtid == QOS_L3_OCCUP_EVENT_ID) return erdt_read_l3_occupancy(d, rmid, val); + if (rmbm_event(evtid)) + return erdt_read_region_mbm(hdr, d, rmid, evtid, val); + return -EIO; } diff --git a/arch/x86/kernel/cpu/resctrl/internal.h b/arch/x86/kernel/cpu/resctrl/internal.h index c337c4336789..b665b19b6f8b 100644 --- a/arch/x86/kernel/cpu/resctrl/internal.h +++ b/arch/x86/kernel/cpu/resctrl/internal.h @@ -320,4 +320,8 @@ int erdt_mon_read(struct rdt_domain_hdr *hdr, enum resctrl_event_id evtid, u32 r int erdt_init(void); void erdt_exit(void); +u64 mbm_overflow_count(u64 prev_val, u64 cur_val, unsigned int width); +struct arch_mbm_state *get_arch_mbm_state(struct rdt_hw_l3_mon_domain *hw_dom, + u32 rmid, + enum resctrl_event_id eventid); #endif /* _ASM_X86_RESCTRL_INTERNAL_H */ diff --git a/arch/x86/kernel/cpu/resctrl/monitor.c b/arch/x86/kernel/cpu/resctrl/monitor.c index ac5353fd0efd..c60d3d55a96c 100644 --- a/arch/x86/kernel/cpu/resctrl/monitor.c +++ b/arch/x86/kernel/cpu/resctrl/monitor.c @@ -157,9 +157,9 @@ static int __rmid_read_phys(u32 prmid, enum resctrl_event_id eventid, u64 *val) return 0; } -static struct arch_mbm_state *get_arch_mbm_state(struct rdt_hw_l3_mon_domain *hw_dom, - u32 rmid, - enum resctrl_event_id eventid) +struct arch_mbm_state *get_arch_mbm_state(struct rdt_hw_l3_mon_domain *hw_dom, + u32 rmid, + enum resctrl_event_id eventid) { struct arch_mbm_state *state; @@ -209,7 +209,7 @@ void resctrl_arch_reset_rmid_all(struct rdt_resource *r, struct rdt_l3_mon_domai } } -static u64 mbm_overflow_count(u64 prev_val, u64 cur_val, unsigned int width) +u64 mbm_overflow_count(u64 prev_val, u64 cur_val, unsigned int width) { u64 shift = 64 - width, chunks; diff --git a/include/linux/resctrl_types.h b/include/linux/resctrl_types.h index 41dc1dff8c16..ee8fc7df22f9 100644 --- a/include/linux/resctrl_types.h +++ b/include/linux/resctrl_types.h @@ -77,6 +77,11 @@ enum resctrl_event_id { QOS_NUM_EVENTS, }; +static inline bool rmbm_event(unsigned int e) +{ + return (e >= QOS_L3_MBM_R0_EVENT_ID) && (e <= QOS_L3_MBM_R3_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