[Linux-stm32] Patch "minmax: clamp more efficiently by avoiding extra comparison" has been added to the 5.10-stable tree

gregkh at linuxfoundation.org gregkh at linuxfoundation.org
Fri Oct 17 13:48:29 UTC 2025


This is a note to let you know that I've just added the patch titled

    minmax: clamp more efficiently by avoiding extra comparison

to the 5.10-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     minmax-clamp-more-efficiently-by-avoiding-extra-comparison.patch
and it can be found in the queue-5.10 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable at vger.kernel.org> know about it.


>From prvs=378230090=farbere at amazon.com Fri Oct 17 11:07:07 2025
From: Eliav Farber <farbere at amazon.com>
Date: Fri, 17 Oct 2025 09:04:56 +0000
Subject: minmax: clamp more efficiently by avoiding extra comparison
To: <gregkh at linuxfoundation.org>, <stable at vger.kernel.org>, <linux at armlinux.org.uk>, <jdike at addtoit.com>, <richard at nod.at>, <anton.ivanov at cambridgegreys.com>, <dave.hansen at linux.intel.com>, <luto at kernel.org>, <peterz at infradead.org>, <tglx at linutronix.de>, <mingo at redhat.com>, <bp at alien8.de>, <x86 at kernel.org>, <hpa at zytor.com>, <tony.luck at intel.com>, <qiuxu.zhuo at intel.com>, <mchehab at kernel.org>, <james.morse at arm.com>, <rric at kernel.org>, <harry.wentland at amd.com>, <sunpeng.li at amd.com>, <alexander.deucher at amd.com>, <christian.koenig at amd.com>, <airlied at linux.ie>, <daniel at ffwll.ch>, <evan.quan at amd.com>, <james.qian.wang at arm.com>, <liviu.dudau at arm.com>, <mihail.atanassov at arm.com>, <brian.starkey at arm.com>, <maarten.lankhorst at linux.intel.com>, <mripard at kernel.org>, <tzimmermann at suse.de>, <robdclark at gmail.com>, <sean at poorly.run>, <jdelvare at suse.com>, <linux at roeck-us.net>, <fery at cypress.com>, <dmitry.torokhov at gmail.com>, <agk at redhat.com>, <snitzer at redhat.com>, <dm-devel at redhat.com>, <rajur at chelsio
 .com>, <davem at davemloft.net>, <kuba at kernel.org>, <peppe.cavallaro at st.com>, <alexandre.torgue at st.com>, <joabreu at synopsys.com>, <mcoquelin.stm32 at gmail.com>, <malattia at linux.it>, <hdegoede at redhat.com>, <mgross at linux.intel.com>, <intel-linux-scu at intel.com>, <artur.paszkiewicz at intel.com>, <jejb at linux.ibm.com>, <martin.petersen at oracle.com>, <sakari.ailus at linux.intel.com>, <clm at fb.com>, <josef at toxicpanda.com>, <dsterba at suse.com>, <xiang at kernel.org>, <chao at kernel.org>, <jack at suse.com>, <tytso at mit.edu>, <adilger.kernel at dilger.ca>, <dushistov at mail.ru>, <luc.vanoostenryck at gmail.com>, <rostedt at goodmis.org>, <pmladek at suse.com>, <sergey.senozhatsky at gmail.com>, <andriy.shevchenko at linux.intel.com>, <linux at rasmusvillemoes.dk>, <minchan at kernel.org>, <ngupta at vflare.org>, <akpm at linux-foundation.org>, <kuznet at ms2.inr.ac.ru>, <yoshfuji at linux-ipv6.org>, <pablo at netfilter.org>, <kadlec at netfilter.org>, <fw at strlen.de>, <jmaloy at redhat.com>, <ying.xue at windriver.com>, <willy at infradead.org>, <farbere at amazon.com>,
  <sashal at kernel.org>, <ruanjinjie at huawei.com>, <David.Laight at ACULAB.COM>, <herve.codina at bootlin.com>, <Jason at zx2c4.com>, <keescook at chromium.org>, <kbusch at kernel.org>, <nathan at kernel.org>, <bvanassche at acm.org>, <ndesaulniers at google.com>, <linux-arm-kernel at lists.infradead.org>, <linux-kernel at vger.kernel.org>, <linux-um at lists.infradead.org>, <linux-edac at vger.kernel.org>, <amd-gfx at lists.freedesktop.org>, <dri-devel at lists.freedesktop.org>, <linux-arm-msm at vger.kernel.org>, <freedreno at lists.freedesktop.org>, <linux-hwmon at vger.kernel.org>, <linux-input at vger.kernel.org>, <linux-media at vger.kernel.org>, <netdev at vger.kernel.org>, <linux-stm32 at st-md-mailman.stormreply.com>, <platform-driver-x86 at vger.kernel.org>, <linux-scsi at vger.kernel.org>, <linux-staging at lists.linux.dev>, <linux-btrfs at vger.kernel.org>, <linux-erofs at lists.ozlabs.org>, <linux-ext4 at vger.kernel.org>, <linux-sparse at vger.kernel.org>, <linux-mm at kvack.org>, <netfilter-devel at vger.kernel.org>, <coreteam at netfilter.org>, <tipc-discussion@
 lists.sourceforge.net>
Message-ID: <20251017090519.46992-5-farbere at amazon.com>

From: "Jason A. Donenfeld" <Jason at zx2c4.com>

[ Upstream commit 2122e2a4efc2cd139474079e11939b6e07adfacd ]

Currently the clamp algorithm does:

    if (val > hi)
        val = hi;
    if (val < lo)
        val = lo;

But since hi > lo by definition, this can be made more efficient with:

    if (val > hi)
        val = hi;
    else if (val < lo)
        val = 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 = inode->i_sb;
        unsigned int gran = sb->s_time_gran;

        t.tv_sec = clamp(t.tv_sec, sb->s_time_min, sb->s_time_max);
        if (t.tv_sec == sb->s_time_max || t.tv_sec == sb->s_time_min)
            t.tv_nsec = 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 <Jason at zx2c4.com>
Cc: Andy Shevchenko <andriy.shevchenko at linux.intel.com>
Cc: Kees Cook <keescook at chromium.org>
Signed-off-by: Andrew Morton <akpm at linux-foundation.org>
Signed-off-by: Eliav Farber <farbere at amazon.com>
Signed-off-by: Greg Kroah-Hartman <gregkh at linuxfoundation.org>
---
 include/linux/minmax.h |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- 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))
 
 #define __clamp(val, lo, hi)	\
-	__cmp(__cmp(val, lo, >), hi, <)
+	((val) >= (hi) ? (hi) : ((val) <= (lo) ? (lo) : (val)))
 
 #define __clamp_once(val, lo, hi, unique_val, unique_lo, unique_hi) ({	\
 		typeof(val) unique_val = (val);				\


Patches currently in stable-queue which might be from farbere at amazon.com are

queue-5.10/minmax-allow-comparisons-of-int-against-unsigned-char-short.patch
queue-5.10/minmax-add-a-few-more-min_t-max_t-users.patch
queue-5.10/minmax-improve-macro-expansion-and-type-checking.patch
queue-5.10/minmax-fix-indentation-of-__cmp_once-and-__clamp_once.patch
queue-5.10/minmax.h-simplify-the-variants-of-clamp.patch
queue-5.10/minmax-add-in_range-macro.patch
queue-5.10/minmax.h-move-all-the-clamp-definitions-after-the-min-max-ones.patch
queue-5.10/minmax-allow-min-max-clamp-if-the-arguments-have-the-same-signedness.patch
queue-5.10/minmax-don-t-use-max-in-situations-that-want-a-c-constant-expression.patch
queue-5.10/minmax.h-remove-some-defines-that-are-only-expanded-once.patch
queue-5.10/minmax.h-use-build_bug_on_msg-for-the-lo-hi-test-in-clamp.patch
queue-5.10/minmax-simplify-min-max-clamp-implementation.patch
queue-5.10/minmax-deduplicate-__unconst_integer_typeof.patch
queue-5.10/minmax-simplify-and-clarify-min_t-max_t-implementation.patch
queue-5.10/minmax.h-add-whitespace-around-operators-and-after-commas.patch
queue-5.10/minmax-sanity-check-constant-bounds-when-clamping.patch
queue-5.10/minmax-avoid-overly-complicated-constant-expressions-in-vm-code.patch
queue-5.10/minmax-make-generic-min-and-max-macros-available-everywhere.patch
queue-5.10/minmax-fix-up-min3-and-max3-too.patch
queue-5.10/minmax.h-reduce-the-define-expansion-of-min-max-and-clamp.patch
queue-5.10/minmax-fix-header-inclusions.patch
queue-5.10/minmax-introduce-min-max-_array.patch
queue-5.10/btrfs-remove-duplicated-in_range-macro.patch
queue-5.10/overflow-tracing-define-the-is_signed_type-macro-once.patch
queue-5.10/minmax-relax-check-to-allow-comparison-between-unsigned-arguments-and-signed-constants.patch
queue-5.10/minmax-clamp-more-efficiently-by-avoiding-extra-comparison.patch
queue-5.10/minmax.h-update-some-comments.patch



More information about the Linux-stm32 mailing list