From nobody Thu Apr 2 09:29:22 2026 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 59C703AEF30; Fri, 13 Mar 2026 14:49:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773413349; cv=none; b=W9ASUi7BZH5eLieWbVerW2lACJ5H5FcCVjjUqVThuedZgQvK4CGNttFxWqksia7/No0sLo19a0vwnmi8bIStgr1o1ZAsByBNt949GX00X9iciUAedXyLu6vJ1E+5l30krS7vWCB/WrBg2l/4ZgXhQ7giaIx2NF12NjJpJWNKjnQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773413349; c=relaxed/simple; bh=gpqBTAqz7vjhgumdrg3bwYr/Der/Agg1Fl1kU+LxOK8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=q3Ckt5pALeQyWIBaaR+4Zs0gHGmGebwDBzJ1pSvSlrDUalLgNR3Pc6NUeWhWdcY1Clx5hCyS0stNMGBqAs4x4eQACsW63se1a5GCuqd2E179p+n85/rFVRB3sEyCPNOQDTEe9qp+lb2sU6YdSGMY0Il/usJmjeLISHzpeyX2izU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id D374425DC; Fri, 13 Mar 2026 07:49:01 -0700 (PDT) Received: from e134344.cambridge.arm.com (e134344.arm.com [10.1.196.46]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 134313F7BD; Fri, 13 Mar 2026 07:49:03 -0700 (PDT) From: Ben Horgan To: ben.horgan@arm.com Cc: amitsinght@marvell.com, baisheng.gao@unisoc.com, baolin.wang@linux.alibaba.com, carl@os.amperecomputing.com, dave.martin@arm.com, david@kernel.org, dfustini@baylibre.com, fenghuay@nvidia.com, gshan@redhat.com, james.morse@arm.com, jonathan.cameron@huawei.com, kobak@nvidia.com, lcherian@marvell.com, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, peternewman@google.com, punit.agrawal@oss.qualcomm.com, quic_jiles@quicinc.com, reinette.chatre@intel.com, rohit.mathew@arm.com, scott@os.amperecomputing.com, sdonthineni@nvidia.com, tan.shaopeng@fujitsu.com, xhao@linux.alibaba.com, catalin.marinas@arm.com, will@kernel.org, corbet@lwn.net, maz@kernel.org, oupton@kernel.org, joey.gouly@arm.com, suzuki.poulose@arm.com, kvmarm@lists.linux.dev, zengheng4@huawei.com, linux-doc@vger.kernel.org, Shaopeng Tan Subject: [PATCH v6 37/40] arm_mpam: Add workaround for T241-MPAM-4 Date: Fri, 13 Mar 2026 14:46:14 +0000 Message-ID: <20260313144617.3420416-38-ben.horgan@arm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260313144617.3420416-1-ben.horgan@arm.com> References: <20260313144617.3420416-1-ben.horgan@arm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Shanker Donthineni In the T241 implementation of memory-bandwidth partitioning, in the absence of contention for bandwidth, the minimum bandwidth setting can affect the amount of achieved bandwidth. Specifically, the achieved bandwidth in the absence of contention can settle to any value between the values of MPAMCFG_MBW_MIN and MPAMCFG_MBW_MAX. Also, if MPAMCFG_MBW_MIN is set zero (below 0.78125%), once a core enters a throttled state, it will never leave that state. The first issue is not a concern if the MPAM software allows to program MPAMCFG_MBW_MIN through the sysfs interface. This patch ensures program MBW_MIN=3D1 (0.78125%) whenever MPAMCFG_MBW_MIN=3D0 is programmed. In the scenario where the resctrl doesn't support the MBW_MIN interface via sysfs, to achieve bandwidth closer to MBW_MAX in the absence of contention, software should configure a relatively narrow gap between MBW_MIN and MBW_MAX. The recommendation is to use a 5% gap to mitigate the problem. Clear the feature MBW_MIN feature from the class to ensure we don't accidentally change behaviour when resctrl adds support for a MBW_MIN interface. Tested-by: Gavin Shan Tested-by: Shaopeng Tan Reviewed-by: Zeng Heng Reviewed-by: Shaopeng Tan Reviewed-by: Fenghua Yu Signed-off-by: Shanker Donthineni Signed-off-by: James Morse Signed-off-by: Ben Horgan Reviewed-by: Gavin Shan --- [ morse: Added as second quirk, adapted to use the new intermediate values in mpam_extend_config() ] Changes since rfc: MPAM_IIDR_NVIDIA_T421 -> MPAM_IIDR_NVIDIA_T241 Handling when reset_mbw_min is set Changes since v3: Move the 5% gap policy back here Clear mbw_min feature in class Changes since v5: Calculate min from max when resetting --- Documentation/arch/arm64/silicon-errata.rst | 2 + drivers/resctrl/mpam_devices.c | 55 +++++++++++++++++++-- drivers/resctrl/mpam_internal.h | 1 + 3 files changed, 55 insertions(+), 3 deletions(-) diff --git a/Documentation/arch/arm64/silicon-errata.rst b/Documentation/ar= ch/arm64/silicon-errata.rst index a65620f98e3a..a4b246655e37 100644 --- a/Documentation/arch/arm64/silicon-errata.rst +++ b/Documentation/arch/arm64/silicon-errata.rst @@ -249,6 +249,8 @@ stable kernels. +----------------+-----------------+-----------------+--------------------= ---------+ | NVIDIA | T241 MPAM | T241-MPAM-1 | N/A = | +----------------+-----------------+-----------------+--------------------= ---------+ +| NVIDIA | T241 MPAM | T241-MPAM-4 | N/A = | ++----------------+-----------------+-----------------+--------------------= ---------+ +----------------+-----------------+-----------------+--------------------= ---------+ | Freescale/NXP | LS2080A/LS1043A | A-008585 | FSL_ERRATUM_A008585= | +----------------+-----------------+-----------------+--------------------= ---------+ diff --git a/drivers/resctrl/mpam_devices.c b/drivers/resctrl/mpam_devices.c index b1753498f07f..f13537ec7ab5 100644 --- a/drivers/resctrl/mpam_devices.c +++ b/drivers/resctrl/mpam_devices.c @@ -679,6 +679,12 @@ static const struct mpam_quirk mpam_quirks[] =3D { .iidr_mask =3D MPAM_IIDR_MATCH_ONE, .workaround =3D T241_SCRUB_SHADOW_REGS, }, + { + /* NVIDIA t241 erratum T241-MPAM-4 */ + .iidr =3D MPAM_IIDR_NVIDIA_T241, + .iidr_mask =3D MPAM_IIDR_MATCH_ONE, + .workaround =3D T241_FORCE_MBW_MIN_TO_ONE, + }, { NULL } /* Sentinel */ }; =20 @@ -1464,6 +1470,37 @@ static void mpam_quirk_post_config_change(struct mpa= m_msc_ris *ris, u16 partid, mpam_apply_t241_erratum(ris, partid); } =20 +static u16 mpam_wa_t241_force_mbw_min_to_one(struct mpam_props *props) +{ + u16 max_hw_value, min_hw_granule, res0_bits; + + res0_bits =3D 16 - props->bwa_wd; + max_hw_value =3D ((1 << props->bwa_wd) - 1) << res0_bits; + min_hw_granule =3D ~max_hw_value; + + return min_hw_granule + 1; +} + +static u16 mpam_wa_t241_calc_min_from_max(struct mpam_props *props, + struct mpam_config *cfg) +{ + u16 val =3D 0; + u16 max; + u16 delta =3D ((5 * MPAMCFG_MBW_MAX_MAX) / 100) - 1; + + if (mpam_has_feature(mpam_feat_mbw_max, cfg)) { + max =3D cfg->mbw_max; + } else { + /* Resetting. Hence, use the ris specific default. */ + max =3D GENMASK(15, 16 - props->bwa_wd); + } + + if (max > delta) + val =3D max - delta; + + return val; +} + /* Called via IPI. Call while holding an SRCU reference */ static void mpam_reprogram_ris_partid(struct mpam_msc_ris *ris, u16 partid, struct mpam_config *cfg) @@ -1504,9 +1541,18 @@ static void mpam_reprogram_ris_partid(struct mpam_ms= c_ris *ris, u16 partid, mpam_write_partsel_reg(msc, MBW_PBM, cfg->mbw_pbm); } =20 - if (mpam_has_feature(mpam_feat_mbw_min, rprops) && - mpam_has_feature(mpam_feat_mbw_min, cfg)) - mpam_write_partsel_reg(msc, MBW_MIN, 0); + if (mpam_has_feature(mpam_feat_mbw_min, rprops)) { + u16 val =3D 0; + + if (mpam_has_quirk(T241_FORCE_MBW_MIN_TO_ONE, msc)) { + u16 min =3D mpam_wa_t241_force_mbw_min_to_one(rprops); + + val =3D mpam_wa_t241_calc_min_from_max(rprops, cfg); + val =3D max(val, min); + } + + mpam_write_partsel_reg(msc, MBW_MIN, val); + } =20 if (mpam_has_feature(mpam_feat_mbw_max, rprops)) { if (mpam_has_feature(mpam_feat_mbw_max, cfg)) @@ -2288,6 +2334,9 @@ static void mpam_enable_merge_class_features(struct m= pam_component *comp) =20 list_for_each_entry(vmsc, &comp->vmsc, comp_list) __class_props_mismatch(class, vmsc); + + if (mpam_has_quirk(T241_FORCE_MBW_MIN_TO_ONE, class)) + mpam_clear_feature(mpam_feat_mbw_min, &class->props); } =20 /* diff --git a/drivers/resctrl/mpam_internal.h b/drivers/resctrl/mpam_interna= l.h index e38954a735d8..010f4e16a637 100644 --- a/drivers/resctrl/mpam_internal.h +++ b/drivers/resctrl/mpam_internal.h @@ -224,6 +224,7 @@ struct mpam_props { /* Workaround bits for msc->quirks */ enum mpam_device_quirks { T241_SCRUB_SHADOW_REGS, + T241_FORCE_MBW_MIN_TO_ONE, MPAM_QUIRK_LAST }; =20 --=20 2.43.0