From nobody Wed Dec 17 15:31:12 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 1D7F91A00F7; Tue, 16 Jul 2024 17:52:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721152336; cv=none; b=hqj5oyY0euBzbp344MEjoQ8bokZTvuFEn4iVJ8qoN89Uy76ZkVbhx1F8rfxJ3rD4/0z2ny89QXMMOMzjGSsgA6CPIRxGMRZzuFE+Mm/lxGwGC+oEvCSvBIYYZp4sfYnrULnbNoMb/5wRIuoeqKM0L7sayY1fJrwukKhzwKV5Lrk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721152336; c=relaxed/simple; bh=p3+cbQrtzD34rlMr4M+1CIjAqE6/GqsWTPXFKfSsxdw=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=AmLrLJsN/rZP1vTvfwK8p0+NuMcsQiePj8rtGGFcpSEoMSnRnqEAVfeXfP9nAPsE/Xqf6s+gBkAsnKIgXcSXkHZIh4Kbfbzuo2mAGVVekTAb5sfVG+vKF3Bk4iDbjdsKSHuX3RLdbv4nUurkHHbxecvvXihLiwY7rJoL8kMsxVw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=f9Vv6KTD; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="f9Vv6KTD" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 18C51C4AF0E; Tue, 16 Jul 2024 17:52:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1721152335; bh=p3+cbQrtzD34rlMr4M+1CIjAqE6/GqsWTPXFKfSsxdw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=f9Vv6KTDxu3pDLw4K2EcYpGjkhIiBszgq2OH3QC80jHrVIJEUMwUlvaF2nkbTXAu6 mrO3qaKhy80SadeBCLzPl7/Eqm/stbRfEsTP872cBCQST9bwU5pctzX5K7S6wzB45d TRCDZ2nVHz7KOl/mN7rFeedAhY8PP4rt3WXYVXfY/4/Zj6RB9u1wo2X4OCzbVG+U1B YjMEumNQzOjYRPpV5WrS5q7MLA8K0RsoFf4TbFaRWVGk1f46DctrzIHzqpPA+4jvfh OwZTbAg5YjvrRryyvbZaLZzOaxnffIjDviWzqcW3JDUuUunSpXeTrIumbP4BAVporC e2DieOl2H6ytQ== From: SeongJae Park To: stable@vger.kernel.org, gregkh@linuxfoundation.org Cc: "Jason A. Donenfeld" , linux-kernel@vger.kernel.org, Andy Shevchenko , Kees Cook , Andrew Morton , SeongJae Park Subject: [PATCH 6.1.y 1/7] minmax: sanity check constant bounds when clamping Date: Tue, 16 Jul 2024 10:51:59 -0700 Message-Id: <20240716175205.51280-2-sj@kernel.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240716175205.51280-1-sj@kernel.org> References: <20240716175205.51280-1-sj@kernel.org> 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: "Jason A. Donenfeld" commit 5efcecd9a3b18078d3398b359a84c83f549e22cf upstream. The clamp family of functions only makes sense if hi>=3Dlo. If hi and lo are compile-time constants, then raise a build error. Doing so has already caught buggy code. This also introduces the infrastructure to improve the clamping function in subsequent commits. [akpm@linux-foundation.org: coding-style cleanups] [akpm@linux-foundation.org: s@&&\@&& \@] Link: https://lkml.kernel.org/r/20220926133435.1333846-1-Jason@zx2c4.com Signed-off-by: Jason A. Donenfeld Reviewed-by: Andy Shevchenko Cc: Kees Cook Signed-off-by: Andrew Morton (cherry picked from commit 5efcecd9a3b18078d3398b359a84c83f549e22cf) Signed-off-by: SeongJae Park --- include/linux/minmax.h | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/include/linux/minmax.h b/include/linux/minmax.h index 1aea34b8f19b..8b092c66c5aa 100644 --- a/include/linux/minmax.h +++ b/include/linux/minmax.h @@ -37,6 +37,28 @@ __cmp(x, y, op), \ __cmp_once(x, y, __UNIQUE_ID(__x), __UNIQUE_ID(__y), op)) =20 +#define __clamp(val, lo, hi) \ + __cmp(__cmp(val, lo, >), hi, <) + +#define __clamp_once(val, lo, hi, unique_val, unique_lo, unique_hi) ({ \ + typeof(val) unique_val =3D (val); \ + typeof(lo) unique_lo =3D (lo); \ + typeof(hi) unique_hi =3D (hi); \ + __clamp(unique_val, unique_lo, unique_hi); }) + +#define __clamp_input_check(lo, hi) \ + (BUILD_BUG_ON_ZERO(__builtin_choose_expr( \ + __is_constexpr((lo) > (hi)), (lo) > (hi), false))) + +#define __careful_clamp(val, lo, hi) ({ \ + __clamp_input_check(lo, hi) + \ + __builtin_choose_expr(__typecheck(val, lo) && __typecheck(val, hi) && \ + __typecheck(hi, lo) && __is_constexpr(val) && \ + __is_constexpr(lo) && __is_constexpr(hi), \ + __clamp(val, lo, hi), \ + __clamp_once(val, lo, hi, __UNIQUE_ID(__val), \ + __UNIQUE_ID(__lo), __UNIQUE_ID(__hi))); }) + /** * min - return minimum of two values of the same or compatible types * @x: first value @@ -103,7 +125,7 @@ * This macro does strict typechecking of @lo/@hi to make sure they are of= the * same type as @val. See the unnecessary pointer comparisons. */ -#define clamp(val, lo, hi) min((typeof(val))max(val, lo), hi) +#define clamp(val, lo, hi) __careful_clamp(val, lo, hi) =20 /* * ..and if you can't take the strict @@ -138,7 +160,7 @@ * This macro does no typechecking and uses temporary variables of type * @type to make all the comparisons. */ -#define clamp_t(type, val, lo, hi) min_t(type, max_t(type, val, lo), hi) +#define clamp_t(type, val, lo, hi) __careful_clamp((type)(val), (type)(lo)= , (type)(hi)) =20 /** * clamp_val - return a value clamped to a given range using val's type --=20 2.39.2 From nobody Wed Dec 17 15:31:12 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 D1B6A1A01BA; Tue, 16 Jul 2024 17:52:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721152336; cv=none; b=d97F1ziW2yfHi6zGpI9Dug9ED0NGlScIq3z9pL7v26d/j2vgxiz57+fMN3zRdXvWBQamjpa713QH9pFXbYue2dZ4eQ2FX8TgO+PLM0Aoo9IUu0YxHFDa4IAjrbfWKNji4bDLS6IRdUdQzHKYScW6ZpPEBueKrLebuOHAUC1qH4o= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721152336; c=relaxed/simple; bh=aThZ+zEPJT8k/go9mqoqA2XrygvL1lG02piMFP8v6xI=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=RxuLFTcxtGApWFaMlxuH26xT+6Y8gF0c0sPELuJc7JlcHEWffBUp1qJhyCrdQF1nymMjUI22njkriMhCHkIXQVIBlRTheIdysCHXfiRo6Jozh5vOmeawn95umr4sgroxKAKC9nHCF+DBGs5NWNMaSluXuwsR/NzV5/4z0Gm/U8I= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Z2YK3HVQ; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="Z2YK3HVQ" Received: by smtp.kernel.org (Postfix) with ESMTPSA id DCA50C4AF0F; Tue, 16 Jul 2024 17:52:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1721152336; bh=aThZ+zEPJT8k/go9mqoqA2XrygvL1lG02piMFP8v6xI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Z2YK3HVQ8ZlIDBNw7z9ATdtjdqMn3ZNPDs4F8BAoC1IfkGTYqZa7cRKQjlh3sKRF2 Ws1zaQafugyi0++ntVxWhsYBR8n1pNsktdy2YB3n0d0IldeT+be8nm0U2TR4DUoc7U 2+qt2Gi0/ML4X53fkel0UCwCexJcdyir1/6Qbw6+oMWKp5pJHMPNOWxTjwiVIJeB6d vO8oHX7Vd7u2D7BS6BJehzmYv66whHXgE/Hlojz6H3bmMnOLE7zWDd7DYByBrQDHwI K2gprFHdChBHUPxjssqkO2HnHhN5ayT8jFcK3HsueZR8cecte8WTlYGXPGRPeSXPx5 wi/5ayJURbDMA== From: SeongJae Park To: stable@vger.kernel.org, gregkh@linuxfoundation.org Cc: "Jason A. Donenfeld" , linux-kernel@vger.kernel.org, Andy Shevchenko , Kees Cook , Andrew Morton , SeongJae Park Subject: [PATCH 6.1.y 2/7] minmax: clamp more efficiently by avoiding extra comparison Date: Tue, 16 Jul 2024 10:52:00 -0700 Message-Id: <20240716175205.51280-3-sj@kernel.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240716175205.51280-1-sj@kernel.org> References: <20240716175205.51280-1-sj@kernel.org> 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: "Jason A. Donenfeld" commit 2122e2a4efc2cd139474079e11939b6e07adfacd upstream. Currently the clamp algorithm does: if (val > hi) val =3D hi; if (val < lo) val =3D lo; But since hi > lo by definition, this can be made more efficient with: if (val > hi) val =3D hi; else if (val < lo) val =3D lo; So fix up the clamp and clamp_t functions to do this, adding the same argument checking as for min and min_t. For simple cases, code generation on x86_64 and aarch64 stay about the same: before: cmp edi, edx mov eax, esi cmova edi, edx cmp edi, esi cmovnb eax, edi ret after: cmp edi, esi mov eax, edx cmovnb esi, edi cmp edi, edx cmovb eax, esi ret before: cmp w0, w2 csel w8, w0, w2, lo cmp w8, w1 csel w0, w8, w1, hi ret after: cmp w0, w1 csel w8, w0, w1, hi cmp w0, w2 csel w0, w8, w2, lo ret On MIPS64, however, code generation improves, by removing arithmetic in the second branch: before: sltu $3,$6,$4 bne $3,$0,.L2 move $2,$6 move $2,$4 .L2: sltu $3,$2,$5 bnel $3,$0,.L7 move $2,$5 .L7: jr $31 nop after: sltu $3,$4,$6 beq $3,$0,.L13 move $2,$6 sltu $3,$4,$5 bne $3,$0,.L12 move $2,$4 .L13: jr $31 nop .L12: jr $31 move $2,$5 For more complex cases with surrounding code, the effects are a bit more complicated. For example, consider this simplified version of timestamp_truncate() from fs/inode.c on x86_64: struct timespec64 timestamp_truncate(struct timespec64 t, struct inode = *inode) { struct super_block *sb =3D inode->i_sb; unsigned int gran =3D sb->s_time_gran; t.tv_sec =3D clamp(t.tv_sec, sb->s_time_min, sb->s_time_max); if (t.tv_sec =3D=3D sb->s_time_max || t.tv_sec =3D=3D sb->s_time_mi= n) t.tv_nsec =3D 0; return t; } before: mov r8, rdx mov rdx, rsi mov rcx, QWORD PTR [r8] mov rax, QWORD PTR [rcx+8] mov rcx, QWORD PTR [rcx+16] cmp rax, rdi mov r8, rcx cmovge rdi, rax cmp rdi, rcx cmovle r8, rdi cmp rax, r8 je .L4 cmp rdi, rcx jge .L4 mov rax, r8 ret .L4: xor edx, edx mov rax, r8 ret after: mov rax, QWORD PTR [rdx] mov rdx, QWORD PTR [rax+8] mov rax, QWORD PTR [rax+16] cmp rax, rdi jg .L6 mov r8, rax xor edx, edx .L2: mov rax, r8 ret .L6: cmp rdx, rdi mov r8, rdi cmovge r8, rdx cmp rax, r8 je .L4 xor eax, eax cmp rdx, rdi cmovl rax, rsi mov rdx, rax mov rax, r8 ret .L4: xor edx, edx jmp .L2 In this case, we actually gain a branch, unfortunately, because the compiler's replacement axioms no longer as cleanly apply. So all and all, this change is a bit of a mixed bag. Link: https://lkml.kernel.org/r/20220926133435.1333846-2-Jason@zx2c4.com Signed-off-by: Jason A. Donenfeld Cc: Andy Shevchenko Cc: Kees Cook Signed-off-by: Andrew Morton (cherry picked from commit 2122e2a4efc2cd139474079e11939b6e07adfacd) Signed-off-by: SeongJae Park --- include/linux/minmax.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/minmax.h b/include/linux/minmax.h index 8b092c66c5aa..abdeae409dad 100644 --- a/include/linux/minmax.h +++ b/include/linux/minmax.h @@ -38,7 +38,7 @@ __cmp_once(x, y, __UNIQUE_ID(__x), __UNIQUE_ID(__y), op)) =20 #define __clamp(val, lo, hi) \ - __cmp(__cmp(val, lo, >), hi, <) + ((val) >=3D (hi) ? (hi) : ((val) <=3D (lo) ? (lo) : (val))) =20 #define __clamp_once(val, lo, hi, unique_val, unique_lo, unique_hi) ({ \ typeof(val) unique_val =3D (val); \ --=20 2.39.2 From nobody Wed Dec 17 15:31:12 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 606FE1A01D5; Tue, 16 Jul 2024 17:52:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721152337; cv=none; b=RP2Ifog/7TZlZCYG0czb4YxTSELEIT92ouiNO/xedHSnviCA792GIuwK2uYSMd0FMf1idPoF7rpnAtT90QlYlBmKYgN0nLd6xLKkHqhFX5d7g3mo5D4z5CJtnxZYe9oJJfwNERrBDo7kII3iPr9tuc9rWZb38r7lQ/C80s1Dcq0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721152337; c=relaxed/simple; bh=DfS+ZGQlpkyRoXAydI0Q0HXfxyiuVuX7x3ZtcbMPeEY=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=NDMSSX3yRlB2H/r7H6L+d/QuBHIB706Fk3gVOec4OZaY2DkDimPf05/VzAWnCFwYEzleXXZaNA3O80tx0JX+Gv7jHFj1Q5wD5HHGJD6qraqIDNHJawnxhgxYWBhX2hkAvhCIbv3l9BGcojikzRQVcKRsTQElxvc4kCi37PhcLSc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=A/R2kCYZ; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="A/R2kCYZ" Received: by smtp.kernel.org (Postfix) with ESMTPSA id AC2DFC4AF13; Tue, 16 Jul 2024 17:52:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1721152337; bh=DfS+ZGQlpkyRoXAydI0Q0HXfxyiuVuX7x3ZtcbMPeEY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=A/R2kCYZUjl48aS27/ayNifpOMy28BVb23DLwHZGfNdfaq7AeZA8cyrnV4G8yYsw3 TAGMYKmMZ7dmDy/plp2S3SGUnGgy4wHJl8SqIFm56el1SaFo4Wr467q9loG1UNQg/K 19GlQAztgI+OTXys1Tdgr9JrMUgk6L7HgkPsE/EouYsew7phd15oUFgYJ3Fh4E2jhz Oufwfw0al99fPKmia5Lnk/q4cr40sR/vDzwHcUXxKOuVMVxVCZ0YIItJ5aqPK1LM7j rygcOfngoiA7zmrZa4z921Gsc1RIiUzmT1Fs+PQNyuyEP+CXM7AMKc/TUQm4hFcTNX MDJs/8Z/FPI4A== From: SeongJae Park To: stable@vger.kernel.org, gregkh@linuxfoundation.org Cc: Andy Shevchenko , linux-kernel@vger.kernel.org, Herve Codina , Rasmus Villemoes , Andrew Morton , SeongJae Park Subject: [PATCH 6.1.y 3/7] minmax: fix header inclusions Date: Tue, 16 Jul 2024 10:52:01 -0700 Message-Id: <20240716175205.51280-4-sj@kernel.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240716175205.51280-1-sj@kernel.org> References: <20240716175205.51280-1-sj@kernel.org> 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: Andy Shevchenko commit f6e9d38f8eb00ac8b52e6d15f6aa9bcecacb081b upstream. BUILD_BUG_ON*() macros are defined in build_bug.h. Include it. Replace compiler_types.h by compiler.h, which provides the former, to have a definition of the __UNIQUE_ID(). Link: https://lkml.kernel.org/r/20230912092355.79280-1-andriy.shevchenko@li= nux.intel.com Signed-off-by: Andy Shevchenko Reviewed-by: Herve Codina Cc: Rasmus Villemoes Signed-off-by: Andrew Morton (cherry picked from commit f6e9d38f8eb00ac8b52e6d15f6aa9bcecacb081b) Signed-off-by: SeongJae Park [Fix a conflict due to absence of compiler_types.h include] --- include/linux/minmax.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/linux/minmax.h b/include/linux/minmax.h index abdeae409dad..e8e9642809e0 100644 --- a/include/linux/minmax.h +++ b/include/linux/minmax.h @@ -2,6 +2,8 @@ #ifndef _LINUX_MINMAX_H #define _LINUX_MINMAX_H =20 +#include +#include #include =20 /* --=20 2.39.2 From nobody Wed Dec 17 15:31:12 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 B3A0D1A08A3; Tue, 16 Jul 2024 17:52:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721152338; cv=none; b=Rob1HkZw7LumLyTIQh1Xd/5EDfx0+zuOq7V6NvraA9blpCsIUvr0ZwoM0E0sYiFOmqbu11SaLlpTARvnYJWBK7xiC2+54cNuIyClv+qihvxR/4MGw1wqRdKSY0+byzp1ckReXHF0Hy9EyQ2uC22uSdN6Q4ljp1kDQqRAFa3wDUQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721152338; c=relaxed/simple; bh=G7wLAJvUm7VMiE14Qqoyq66ELgz7AVWyGzvBzNL41RQ=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=cfArmHsL2YTdY4BwOGhJTqRn2z72A3sg1ipocia3KzJcXs4AqDlwmzNFRkq/OpveGL9PLil7saoUVdMiDWQuCpm4RaKgRcXuaZLcPwuRiyjtcgzAGMdpG7KjhFQCEfnFB3r08VnxCGeGLDu5Mvr7b3+ZFvL5NcSIPnUW1qXjJpc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=ecX4Aaz/; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="ecX4Aaz/" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 6EA67C4AF0D; Tue, 16 Jul 2024 17:52:17 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1721152338; bh=G7wLAJvUm7VMiE14Qqoyq66ELgz7AVWyGzvBzNL41RQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ecX4Aaz/tPre631RXbuX9gcfRwlnwxZ5ITNV30nvFX90HPj/XszpFxqLi2a5auN84 QXs7tvnrFkN4z3WEASWdASkKIiQRJUln8ZimYg6LQv7b8ds8P8TtJ617zFlU/Y1036 /Pgl+godDfCyDqpRwS006LV0thWO5h8l4EZ1e+U/zYXY/V0e0n1sPH8vjtt510dE71 lh1wCvm7WV4Wr+DVK9iwqQGehlMM4TZfkCIZ9ZkhL7pIdaNoyHt40KfAgxhGK4ajOR CsaKST6gX906h6fIfqrE+RIkBVNqjgfBArix2W1Kzc5b69XMDOtwWPiKciwPq0cbkb +T2TWDkUwpuag== From: SeongJae Park To: stable@vger.kernel.org, gregkh@linuxfoundation.org Cc: David Laight , linux-kernel@vger.kernel.org, David Laight , Andy Shevchenko , Christoph Hellwig , "Jason A . Donenfeld" , Linus Torvalds , Matthew Wilcox , Andrew Morton , SeongJae Park Subject: [PATCH 6.1.y 4/7] minmax: allow min()/max()/clamp() if the arguments have the same signedness. Date: Tue, 16 Jul 2024 10:52:02 -0700 Message-Id: <20240716175205.51280-5-sj@kernel.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240716175205.51280-1-sj@kernel.org> References: <20240716175205.51280-1-sj@kernel.org> 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: David Laight commit d03eba99f5bf7cbc6e2fdde3b6fa36954ad58e09 upstream. The type-check in min()/max() is there to stop unexpected results if a negative value gets converted to a large unsigned value. However it also rejects 'unsigned int' v 'unsigned long' compares which are common and never problematc. Replace the 'same type' check with a 'same signedness' check. The new test isn't itself a compile time error, so use static_assert() to report the error and give a meaningful error message. Due to the way builtin_choose_expr() works detecting the error in the 'non-constant' side (where static_assert() can be used) also detects errors when the arguments are constant. Link: https://lkml.kernel.org/r/fe7e6c542e094bfca655abcd323c1c98@AcuMS.acul= ab.com Signed-off-by: David Laight Cc: Andy Shevchenko Cc: Christoph Hellwig Cc: Jason A. Donenfeld Cc: Linus Torvalds Cc: Matthew Wilcox (Oracle) Signed-off-by: Andrew Morton (cherry picked from commit d03eba99f5bf7cbc6e2fdde3b6fa36954ad58e09) Signed-off-by: SeongJae Park --- include/linux/minmax.h | 60 ++++++++++++++++++++++-------------------- 1 file changed, 32 insertions(+), 28 deletions(-) diff --git a/include/linux/minmax.h b/include/linux/minmax.h index e8e9642809e0..501fab582d68 100644 --- a/include/linux/minmax.h +++ b/include/linux/minmax.h @@ -11,9 +11,8 @@ * * - avoid multiple evaluations of the arguments (so side-effects like * "x++" happen only once) when non-constant. - * - perform strict type-checking (to generate warnings instead of - * nasty runtime surprises). See the "unnecessary" pointer comparison - * in __typecheck(). + * - perform signed v unsigned type-checking (to generate compile + * errors instead of nasty runtime surprises). * - retain result as a constant expressions when called with only * constant expressions (to avoid tripping VLA warnings in stack * allocation usage). @@ -21,23 +20,30 @@ #define __typecheck(x, y) \ (!!(sizeof((typeof(x) *)1 =3D=3D (typeof(y) *)1))) =20 -#define __no_side_effects(x, y) \ - (__is_constexpr(x) && __is_constexpr(y)) +/* is_signed_type() isn't a constexpr for pointer types */ +#define __is_signed(x) \ + __builtin_choose_expr(__is_constexpr(is_signed_type(typeof(x))), \ + is_signed_type(typeof(x)), 0) =20 -#define __safe_cmp(x, y) \ - (__typecheck(x, y) && __no_side_effects(x, y)) +#define __types_ok(x, y) \ + (__is_signed(x) =3D=3D __is_signed(y)) =20 -#define __cmp(x, y, op) ((x) op (y) ? (x) : (y)) +#define __cmp_op_min < +#define __cmp_op_max > =20 -#define __cmp_once(x, y, unique_x, unique_y, op) ({ \ +#define __cmp(op, x, y) ((x) __cmp_op_##op (y) ? (x) : (y)) + +#define __cmp_once(op, x, y, unique_x, unique_y) ({ \ typeof(x) unique_x =3D (x); \ typeof(y) unique_y =3D (y); \ - __cmp(unique_x, unique_y, op); }) + static_assert(__types_ok(x, y), \ + #op "(" #x ", " #y ") signedness error, fix types or consider u" #op "(= ) before " #op "_t()"); \ + __cmp(op, unique_x, unique_y); }) =20 -#define __careful_cmp(x, y, op) \ - __builtin_choose_expr(__safe_cmp(x, y), \ - __cmp(x, y, op), \ - __cmp_once(x, y, __UNIQUE_ID(__x), __UNIQUE_ID(__y), op)) +#define __careful_cmp(op, x, y) \ + __builtin_choose_expr(__is_constexpr((x) - (y)), \ + __cmp(op, x, y), \ + __cmp_once(op, x, y, __UNIQUE_ID(__x), __UNIQUE_ID(__y))) =20 #define __clamp(val, lo, hi) \ ((val) >=3D (hi) ? (hi) : ((val) <=3D (lo) ? (lo) : (val))) @@ -46,17 +52,15 @@ typeof(val) unique_val =3D (val); \ typeof(lo) unique_lo =3D (lo); \ typeof(hi) unique_hi =3D (hi); \ + static_assert(__builtin_choose_expr(__is_constexpr((lo) > (hi)), \ + (lo) <=3D (hi), true), \ + "clamp() low limit " #lo " greater than high limit " #hi); \ + static_assert(__types_ok(val, lo), "clamp() 'lo' signedness error"); \ + static_assert(__types_ok(val, hi), "clamp() 'hi' signedness error"); \ __clamp(unique_val, unique_lo, unique_hi); }) =20 -#define __clamp_input_check(lo, hi) \ - (BUILD_BUG_ON_ZERO(__builtin_choose_expr( \ - __is_constexpr((lo) > (hi)), (lo) > (hi), false))) - #define __careful_clamp(val, lo, hi) ({ \ - __clamp_input_check(lo, hi) + \ - __builtin_choose_expr(__typecheck(val, lo) && __typecheck(val, hi) && \ - __typecheck(hi, lo) && __is_constexpr(val) && \ - __is_constexpr(lo) && __is_constexpr(hi), \ + __builtin_choose_expr(__is_constexpr((val) - (lo) + (hi)), \ __clamp(val, lo, hi), \ __clamp_once(val, lo, hi, __UNIQUE_ID(__val), \ __UNIQUE_ID(__lo), __UNIQUE_ID(__hi))); }) @@ -66,14 +70,14 @@ * @x: first value * @y: second value */ -#define min(x, y) __careful_cmp(x, y, <) +#define min(x, y) __careful_cmp(min, x, y) =20 /** * max - return maximum of two values of the same or compatible types * @x: first value * @y: second value */ -#define max(x, y) __careful_cmp(x, y, >) +#define max(x, y) __careful_cmp(max, x, y) =20 /** * umin - return minimum of two non-negative values @@ -82,7 +86,7 @@ * @y: second value */ #define umin(x, y) \ - __careful_cmp((x) + 0u + 0ul + 0ull, (y) + 0u + 0ul + 0ull, <) + __careful_cmp(min, (x) + 0u + 0ul + 0ull, (y) + 0u + 0ul + 0ull) =20 /** * umax - return maximum of two non-negative values @@ -90,7 +94,7 @@ * @y: second value */ #define umax(x, y) \ - __careful_cmp((x) + 0u + 0ul + 0ull, (y) + 0u + 0ul + 0ull, >) + __careful_cmp(max, (x) + 0u + 0ul + 0ull, (y) + 0u + 0ul + 0ull) =20 /** * min3 - return minimum of three values @@ -142,7 +146,7 @@ * @x: first value * @y: second value */ -#define min_t(type, x, y) __careful_cmp((type)(x), (type)(y), <) +#define min_t(type, x, y) __careful_cmp(min, (type)(x), (type)(y)) =20 /** * max_t - return maximum of two values, using the specified type @@ -150,7 +154,7 @@ * @x: first value * @y: second value */ -#define max_t(type, x, y) __careful_cmp((type)(x), (type)(y), >) +#define max_t(type, x, y) __careful_cmp(max, (type)(x), (type)(y)) =20 /** * clamp_t - return a value clamped to a given range using a given type --=20 2.39.2 From nobody Wed Dec 17 15:31:12 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 5B23C1A08C2; Tue, 16 Jul 2024 17:52:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721152339; cv=none; b=AMFBtjhNSCyzpb5DXFLjJvxbJXfrU+QzkHIXKKpQxzLEfcTiEn0EOPvsvSBYdkIhIFTjGmVDDCr/AO/C96aGvhz5YsQUJAm8xjQoZEWJFnuVQ3OQJoT/AD4+m7r5A/Zdm85NzvsCbXL5pYReXTc9xOvG613K0dd55Sjb+PDNQgg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721152339; c=relaxed/simple; bh=nUuPHoyJXLPZI9hsORkcW/G6LJ7x+O14qehpn3HYZSg=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=AIO3/kM0mjvVwQNLiYKUkLfWhLBYaPfXkbqWpCpJNp6NVY/HW0m/7I1o4ujxgE1fBEixsYbcPaKwhQNW3ahTtXtXZ4q6kzZplSptIGUESybpuJWP7cJnboWDFyzh10RvswGSTV0wjf9mAe5TaMHoIK81QMFaJl5tN4SixIHv7Jg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=iCYoCP7V; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="iCYoCP7V" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 7074DC4AF0B; Tue, 16 Jul 2024 17:52:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1721152339; bh=nUuPHoyJXLPZI9hsORkcW/G6LJ7x+O14qehpn3HYZSg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=iCYoCP7V8bNsuBerBjAWlaLEtu5E4OoKmWKvCP3oD1nzjDgPO5kqb5Um1L3FrdZvF h52Zl3GQiNRC7E2KzuyvsyUzxAPxwnOVAcKdioVQlvshlgwrcYLJgOclvqLAPWeiNJ P6xZGblQ0IBjgvXXiM+7gnu+65S0bAw7wEH27mJ+bJdA9pIXhl7K2X55CLGRCEXIoJ jyAFJM1siYHKhHEcmw3qE+iOi9OjtGJZnKuSH3LaVfFiEf74fuNpuaROhPbDFASzd6 RKD71VC0WN6dCZ05+iT137DxXwAka9mDRKeDFpj0cFjk5Ytlg/0sWJCB0NDDWb9Iqu AxGPGoBS2kGnQ== From: SeongJae Park To: stable@vger.kernel.org, gregkh@linuxfoundation.org Cc: David Laight , linux-kernel@vger.kernel.org, David Laight , Andy Shevchenko , Christoph Hellwig , "Jason A . Donenfeld" , Linus Torvalds , Matthew Wilcox , Andrew Morton , SeongJae Park Subject: [PATCH 6.1.y 5/7] minmax: allow comparisons of 'int' against 'unsigned char/short' Date: Tue, 16 Jul 2024 10:52:03 -0700 Message-Id: <20240716175205.51280-6-sj@kernel.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240716175205.51280-1-sj@kernel.org> References: <20240716175205.51280-1-sj@kernel.org> 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: David Laight commit 4ead534fba42fc4fd41163297528d2aa731cd121 upstream. Since 'unsigned char/short' get promoted to 'signed int' it is safe to compare them against an 'int' value. Link: https://lkml.kernel.org/r/8732ef5f809c47c28a7be47c938b28d4@AcuMS.acul= ab.com Signed-off-by: David Laight Cc: Andy Shevchenko Cc: Christoph Hellwig Cc: Jason A. Donenfeld Cc: Linus Torvalds Cc: Matthew Wilcox (Oracle) Signed-off-by: Andrew Morton (cherry picked from commit 4ead534fba42fc4fd41163297528d2aa731cd121) Signed-off-by: SeongJae Park --- include/linux/minmax.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/include/linux/minmax.h b/include/linux/minmax.h index 501fab582d68..f76b7145fc11 100644 --- a/include/linux/minmax.h +++ b/include/linux/minmax.h @@ -25,8 +25,9 @@ __builtin_choose_expr(__is_constexpr(is_signed_type(typeof(x))), \ is_signed_type(typeof(x)), 0) =20 -#define __types_ok(x, y) \ - (__is_signed(x) =3D=3D __is_signed(y)) +#define __types_ok(x, y) \ + (__is_signed(x) =3D=3D __is_signed(y) || \ + __is_signed((x) + 0) =3D=3D __is_signed((y) + 0)) =20 #define __cmp_op_min < #define __cmp_op_max > --=20 2.39.2 From nobody Wed Dec 17 15:31:12 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 59D111A0AFC; Tue, 16 Jul 2024 17:52:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721152341; cv=none; b=de8bqREW+4oFNXDLhm+1nex4+a9NtYsI2rL4rSqfqhTVHfziBkMCaGoQrJG6YtaO5NJlOAuQlZm7F2diBtzhLxbJYBkTd2P6GFKeNrxkiqsSA/5SPanW+ILctSxEl/KC16QRvT4khA+tddZ1rouGUft06w3gVd10ycr/LopOSlQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721152341; c=relaxed/simple; bh=ndvNxnnobdXY1qRGFjwKkxZc5JAWm9Mq+lzm6iZ2oDw=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=oaoZ+HxuKJT/E41MMoFlqh8w+YWjsQy28LW54naWAhV9WS2lWDA5GuK4qVwzLUvaeDbKfWnj7i/MgcAbxNS8fZRGV3xwmefAm8xXy0D8HWliMiUU7VFtAn4ee3inLkhyE0HozRu5xoEkN35YuSTdJ/wnyIwRulasLrP6J+B12pU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Ur+K61lD; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="Ur+K61lD" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 6FDCEC4AF1B; Tue, 16 Jul 2024 17:52:19 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1721152340; bh=ndvNxnnobdXY1qRGFjwKkxZc5JAWm9Mq+lzm6iZ2oDw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Ur+K61lDl9kfpg0+3u6I5cYlH9yb9rBbDVzEr33elkgMxW34dgVJff++2P1tnmH8V plOeoA40ruoLq6IQNiOUUmXeytIUlg/vIlYY/d0ve72RtKXCeeMulsVHRNO+qJNM0K a3pT31EpKU+IrcDuSvawXvTG2FICa3zrRZE2mEE9BGgsOWmOjWSrjGH3F3thGqF2tq Ug/I7EAeooNc+/Lo7xYHySRrAgYXrJ38rLrxBMSVWCKr5DhXF373aKPLACCTlwU+bu nfxwEE5PaOsrkLm+aCGB/h0fxuNWJoPMwXzCyb4IFjEf3/SHr8kDiPmGeoOSc+HhnT W+fjOdcoi+HlA== From: SeongJae Park To: stable@vger.kernel.org, gregkh@linuxfoundation.org Cc: David Laight , linux-kernel@vger.kernel.org, David Laight , Andy Shevchenko , Christoph Hellwig , "Jason A . Donenfeld" , Linus Torvalds , Matthew Wilcox , Andrew Morton , SeongJae Park Subject: [PATCH 6.1.y 6/7] minmax: relax check to allow comparison between unsigned arguments and signed constants Date: Tue, 16 Jul 2024 10:52:04 -0700 Message-Id: <20240716175205.51280-7-sj@kernel.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240716175205.51280-1-sj@kernel.org> References: <20240716175205.51280-1-sj@kernel.org> 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: David Laight commit 867046cc7027703f60a46339ffde91a1970f2901 upstream. Allow (for example) min(unsigned_var, 20). The opposite min(signed_var, 20u) is still errored. Since a comparison between signed and unsigned never makes the unsigned value negative it is only necessary to adjust the __types_ok() test. Link: https://lkml.kernel.org/r/633b64e2f39e46bb8234809c5595b8c7@AcuMS.acul= ab.com Signed-off-by: David Laight Cc: Andy Shevchenko Cc: Christoph Hellwig Cc: Jason A. Donenfeld Cc: Linus Torvalds Cc: Matthew Wilcox (Oracle) Signed-off-by: Andrew Morton (cherry picked from commit 867046cc7027703f60a46339ffde91a1970f2901) Signed-off-by: SeongJae Park --- include/linux/minmax.h | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/include/linux/minmax.h b/include/linux/minmax.h index f76b7145fc11..dd52969698f7 100644 --- a/include/linux/minmax.h +++ b/include/linux/minmax.h @@ -9,13 +9,18 @@ /* * min()/max()/clamp() macros must accomplish three things: * - * - avoid multiple evaluations of the arguments (so side-effects like + * - Avoid multiple evaluations of the arguments (so side-effects like * "x++" happen only once) when non-constant. - * - perform signed v unsigned type-checking (to generate compile - * errors instead of nasty runtime surprises). - * - retain result as a constant expressions when called with only + * - Retain result as a constant expressions when called with only * constant expressions (to avoid tripping VLA warnings in stack * allocation usage). + * - Perform signed v unsigned type-checking (to generate compile + * errors instead of nasty runtime surprises). + * - Unsigned char/short are always promoted to signed int and can be + * compared against signed or unsigned arguments. + * - Unsigned arguments can be compared against non-negative signed consta= nts. + * - Comparison of a signed argument against an unsigned constant fails + * even if the constant is below __INT_MAX__ and could be cast to int. */ #define __typecheck(x, y) \ (!!(sizeof((typeof(x) *)1 =3D=3D (typeof(y) *)1))) @@ -25,9 +30,14 @@ __builtin_choose_expr(__is_constexpr(is_signed_type(typeof(x))), \ is_signed_type(typeof(x)), 0) =20 -#define __types_ok(x, y) \ - (__is_signed(x) =3D=3D __is_signed(y) || \ - __is_signed((x) + 0) =3D=3D __is_signed((y) + 0)) +/* True for a non-negative signed int constant */ +#define __is_noneg_int(x) \ + (__builtin_choose_expr(__is_constexpr(x) && __is_signed(x), x, -1) >=3D 0) + +#define __types_ok(x, y) \ + (__is_signed(x) =3D=3D __is_signed(y) || \ + __is_signed((x) + 0) =3D=3D __is_signed((y) + 0) || \ + __is_noneg_int(x) || __is_noneg_int(y)) =20 #define __cmp_op_min < #define __cmp_op_max > --=20 2.39.2 From nobody Wed Dec 17 15:31:13 2025 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 59CBF1A0AFB; Tue, 16 Jul 2024 17:52:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721152341; cv=none; b=a3/eXAqK4WSRNQ2PE6a9q9MtDx2dWV5crkr/fP/MLz9KvH6bwH5ym/Fx0wggtjsik0pLFRRaKgG4/lamZRl0xmE6/1FWHaG26OkI2xm6wgkRQvBu6lP+SHtEcztkMQe4XQtXEJDhh7o67bAVeWuDmYmu+wkAPyNRvFom+SrQWKY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1721152341; c=relaxed/simple; bh=T/pNo+yJuvE1fTBndW2I+PGWWQSfcSQHEgmL3hp/wPM=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=IJiSbT6Gd6jXUPu5/NwGkA8qNe8gNjECqg6cMpjHmJVW5RQdDk8IMjCe8LKWQlBke3WTm6VegJKNuzmUwT0O/7XTZxfOeVDhOJdjq5ZxT3UayGwM46yb62hyTdd08JBL7Nrmh/5uSh7Z9peNutrB7EjPWCJO1MNpKu1PlLB38lk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=QJ5HFnrA; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="QJ5HFnrA" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 6FFEAC4AF0D; Tue, 16 Jul 2024 17:52:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1721152340; bh=T/pNo+yJuvE1fTBndW2I+PGWWQSfcSQHEgmL3hp/wPM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=QJ5HFnrA0gGqZLuEPeEMN1mg0jqaTM9UDLRevr0HupKNYdGfGxKDjFNarBVKFdQwQ e9gWRGiwBUzViaku+L9z1QoGNXBFu0xxwBvLWEqvxy659vuNIFJkesFvVhZb/gmDA1 DtVcN0V4mlwXWuTzJs9Ds0lpaSumxhEIZrL8TivBWgkzvrrZtRgGr60m/TEuROCmUj LCPNzOK+6pnJ/ORW6Z12e6u8Bjh6POkH4TYu1LwcWFdRlnMiOU+EJRWd+nz1qKKYJQ Sm/9+SnNFATTz0WNRcFk2GP6CUkYETY46eEDeijaaTAFXQztYjJvYpviBpFHBL/rwu jJxqBsRex9eHA== From: SeongJae Park To: stable@vger.kernel.org, gregkh@linuxfoundation.org Cc: SeongJae Park , Andrew Morton , damon@lists.linux.dev, linux-mm@kvack.org, linux-kernel@vger.kernel.org Subject: [PATCH 6.1.y 7/7] mm/damon/core: merge regions aggressively when max_nr_regions is unmet Date: Tue, 16 Jul 2024 10:52:05 -0700 Message-Id: <20240716175205.51280-8-sj@kernel.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20240716175205.51280-1-sj@kernel.org> References: <20240716175205.51280-1-sj@kernel.org> 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" commit 310d6c15e9104c99d5d9d0ff8e5383a79da7d5e6 upstream. DAMON keeps the number of regions under max_nr_regions by skipping regions split operations when doing so can make the number higher than the limit. It works well for preventing violation of the limit. But, if somehow the violation happens, it cannot recovery well depending on the situation. In detail, if the real number of regions having different access pattern is higher than the limit, the mechanism cannot reduce the number below the limit. In such a case, the system could suffer from high monitoring overhead of DAMON. The violation can actually happen. For an example, the user could reduce max_nr_regions while DAMON is running, to be lower than the current number of regions. Fix the problem by repeating the merge operations with increasing aggressiveness in kdamond_merge_regions() for the case, until the limit is met. [sj@kernel.org: increase regions merge aggressiveness while respecting min_= nr_regions] Link: https://lkml.kernel.org/r/20240626164753.46270-1-sj@kernel.org [sj@kernel.org: ensure max threshold attempt for max_nr_regions violation] Link: https://lkml.kernel.org/r/20240627163153.75969-1-sj@kernel.org Link: https://lkml.kernel.org/r/20240624175814.89611-1-sj@kernel.org Fixes: b9a6ac4e4ede ("mm/damon: adaptively adjust regions") Signed-off-by: SeongJae Park Cc: [5.15+] Signed-off-by: Andrew Morton (cherry picked from commit 310d6c15e9104c99d5d9d0ff8e5383a79da7d5e6) --- mm/damon/core.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/mm/damon/core.c b/mm/damon/core.c index 5db9bec8ae67..ab5c351b276c 100644 --- a/mm/damon/core.c +++ b/mm/damon/core.c @@ -921,14 +921,31 @@ static void damon_merge_regions_of(struct damon_targe= t *t, unsigned int thres, * access frequencies are similar. This is for minimizing the monitoring * overhead under the dynamically changeable access pattern. If a merge w= as * unnecessarily made, later 'kdamond_split_regions()' will revert it. + * + * The total number of regions could be higher than the user-defined limit, + * max_nr_regions for some cases. For example, the user can update + * max_nr_regions to a number that lower than the current number of regions + * while DAMON is running. For such a case, repeat merging until the limi= t is + * met while increasing @threshold up to possible maximum level. */ static void kdamond_merge_regions(struct damon_ctx *c, unsigned int thresh= old, unsigned long sz_limit) { struct damon_target *t; + unsigned int nr_regions; + unsigned int max_thres; =20 - damon_for_each_target(t, c) - damon_merge_regions_of(t, threshold, sz_limit); + max_thres =3D c->attrs.aggr_interval / + (c->attrs.sample_interval ? c->attrs.sample_interval : 1); + do { + nr_regions =3D 0; + damon_for_each_target(t, c) { + damon_merge_regions_of(t, threshold, sz_limit); + nr_regions +=3D damon_nr_regions(t); + } + threshold =3D max(1, threshold * 2); + } while (nr_regions > c->attrs.max_nr_regions && + threshold / 2 < max_thres); } =20 /* --=20 2.39.2