From 37c71b96ff37b6a069569841b1baa51be72299b2 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 17 Oct 2025 15:48:27 +0200 Subject: [PATCH] 5.10-stable patches added patches: btrfs-remove-duplicated-in_range-macro.patch minmax-add-a-few-more-min_t-max_t-users.patch minmax-add-in_range-macro.patch minmax-allow-comparisons-of-int-against-unsigned-char-short.patch minmax-allow-min-max-clamp-if-the-arguments-have-the-same-signedness.patch minmax-avoid-overly-complicated-constant-expressions-in-vm-code.patch minmax-clamp-more-efficiently-by-avoiding-extra-comparison.patch minmax-deduplicate-__unconst_integer_typeof.patch minmax-don-t-use-max-in-situations-that-want-a-c-constant-expression.patch minmax-fix-header-inclusions.patch minmax-fix-indentation-of-__cmp_once-and-__clamp_once.patch minmax-fix-up-min3-and-max3-too.patch minmax-improve-macro-expansion-and-type-checking.patch minmax-introduce-min-max-_array.patch minmax-make-generic-min-and-max-macros-available-everywhere.patch minmax-relax-check-to-allow-comparison-between-unsigned-arguments-and-signed-constants.patch minmax-sanity-check-constant-bounds-when-clamping.patch minmax-simplify-and-clarify-min_t-max_t-implementation.patch minmax-simplify-min-max-clamp-implementation.patch minmax.h-add-whitespace-around-operators-and-after-commas.patch minmax.h-move-all-the-clamp-definitions-after-the-min-max-ones.patch minmax.h-reduce-the-define-expansion-of-min-max-and-clamp.patch minmax.h-remove-some-defines-that-are-only-expanded-once.patch minmax.h-simplify-the-variants-of-clamp.patch minmax.h-update-some-comments.patch minmax.h-use-build_bug_on_msg-for-the-lo-hi-test-in-clamp.patch overflow-tracing-define-the-is_signed_type-macro-once.patch --- ...rfs-remove-duplicated-in_range-macro.patch | 70 +++ ...max-add-a-few-more-min_t-max_t-users.patch | 154 +++++++ queue-5.10/minmax-add-in_range-macro.patch | 432 ++++++++++++++++++ ...s-of-int-against-unsigned-char-short.patch | 43 ++ ...e-arguments-have-the-same-signedness.patch | 174 +++++++ ...ated-constant-expressions-in-vm-code.patch | 66 +++ ...ciently-by-avoiding-extra-comparison.patch | 184 ++++++++ ...deduplicate-__unconst_integer_typeof.patch | 79 ++++ ...ns-that-want-a-c-constant-expression.patch | 84 ++++ queue-5.10/minmax-fix-header-inclusions.patch | 39 ++ ...ation-of-__cmp_once-and-__clamp_once.patch | 74 +++ .../minmax-fix-up-min3-and-max3-too.patch | 79 ++++ ...ve-macro-expansion-and-type-checking.patch | 202 ++++++++ .../minmax-introduce-min-max-_array.patch | 99 ++++ ...-and-max-macros-available-everywhere.patch | 342 ++++++++++++++ ...igned-arguments-and-signed-constants.patch | 76 +++ ...-check-constant-bounds-when-clamping.patch | 78 ++++ ...d-clarify-min_t-max_t-implementation.patch | 76 +++ ...implify-min-max-clamp-implementation.patch | 140 ++++++ ...ce-around-operators-and-after-commas.patch | 118 +++++ ...p-definitions-after-the-min-max-ones.patch | 186 ++++++++ ...efine-expansion-of-min-max-and-clamp.patch | 100 ++++ ...-defines-that-are-only-expanded-once.patch | 82 ++++ ...max.h-simplify-the-variants-of-clamp.patch | 97 ++++ .../minmax.h-update-some-comments.patch | 128 ++++++ ...g_on_msg-for-the-lo-hi-test-in-clamp.patch | 47 ++ ...define-the-is_signed_type-macro-once.patch | 87 ++++ queue-5.10/series | 27 ++ 28 files changed, 3363 insertions(+) create mode 100644 queue-5.10/btrfs-remove-duplicated-in_range-macro.patch create mode 100644 queue-5.10/minmax-add-a-few-more-min_t-max_t-users.patch create mode 100644 queue-5.10/minmax-add-in_range-macro.patch create mode 100644 queue-5.10/minmax-allow-comparisons-of-int-against-unsigned-char-short.patch create mode 100644 queue-5.10/minmax-allow-min-max-clamp-if-the-arguments-have-the-same-signedness.patch create mode 100644 queue-5.10/minmax-avoid-overly-complicated-constant-expressions-in-vm-code.patch create mode 100644 queue-5.10/minmax-clamp-more-efficiently-by-avoiding-extra-comparison.patch create mode 100644 queue-5.10/minmax-deduplicate-__unconst_integer_typeof.patch create mode 100644 queue-5.10/minmax-don-t-use-max-in-situations-that-want-a-c-constant-expression.patch create mode 100644 queue-5.10/minmax-fix-header-inclusions.patch create mode 100644 queue-5.10/minmax-fix-indentation-of-__cmp_once-and-__clamp_once.patch create mode 100644 queue-5.10/minmax-fix-up-min3-and-max3-too.patch create mode 100644 queue-5.10/minmax-improve-macro-expansion-and-type-checking.patch create mode 100644 queue-5.10/minmax-introduce-min-max-_array.patch create mode 100644 queue-5.10/minmax-make-generic-min-and-max-macros-available-everywhere.patch create mode 100644 queue-5.10/minmax-relax-check-to-allow-comparison-between-unsigned-arguments-and-signed-constants.patch create mode 100644 queue-5.10/minmax-sanity-check-constant-bounds-when-clamping.patch create mode 100644 queue-5.10/minmax-simplify-and-clarify-min_t-max_t-implementation.patch create mode 100644 queue-5.10/minmax-simplify-min-max-clamp-implementation.patch create mode 100644 queue-5.10/minmax.h-add-whitespace-around-operators-and-after-commas.patch create mode 100644 queue-5.10/minmax.h-move-all-the-clamp-definitions-after-the-min-max-ones.patch create mode 100644 queue-5.10/minmax.h-reduce-the-define-expansion-of-min-max-and-clamp.patch create mode 100644 queue-5.10/minmax.h-remove-some-defines-that-are-only-expanded-once.patch create mode 100644 queue-5.10/minmax.h-simplify-the-variants-of-clamp.patch create mode 100644 queue-5.10/minmax.h-update-some-comments.patch create mode 100644 queue-5.10/minmax.h-use-build_bug_on_msg-for-the-lo-hi-test-in-clamp.patch create mode 100644 queue-5.10/overflow-tracing-define-the-is_signed_type-macro-once.patch diff --git a/queue-5.10/btrfs-remove-duplicated-in_range-macro.patch b/queue-5.10/btrfs-remove-duplicated-in_range-macro.patch new file mode 100644 index 0000000000..af2b42ea9a --- /dev/null +++ b/queue-5.10/btrfs-remove-duplicated-in_range-macro.patch @@ -0,0 +1,70 @@ +From stable+bounces-186267-greg=kroah.com@vger.kernel.org Fri Oct 17 11:08:02 2025 +From: Eliav Farber +Date: Fri, 17 Oct 2025 09:04:54 +0000 +Subject: btrfs: remove duplicated in_range() macro +To: , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , +Cc: Johannes Thumshirn +Message-ID: <20251017090519.46992-3-farbere@amazon.com> + +From: Johannes Thumshirn + +[ Upstream commit cea628008fc8c6c9c7b53902f6659e040f33c790 ] + +The in_range() macro is defined twice in btrfs' source, once in ctree.h +and once in misc.h. + +Remove the definition in ctree.h and include misc.h in the files depending +on it. + +Signed-off-by: Johannes Thumshirn +Signed-off-by: David Sterba +Signed-off-by: Eliav Farber +Signed-off-by: Greg Kroah-Hartman +--- + fs/btrfs/ctree.h | 2 -- + fs/btrfs/extent_io.c | 1 + + fs/btrfs/file-item.c | 1 + + fs/btrfs/raid56.c | 1 + + 4 files changed, 3 insertions(+), 2 deletions(-) + +--- a/fs/btrfs/ctree.h ++++ b/fs/btrfs/ctree.h +@@ -3597,8 +3597,6 @@ static inline int btrfs_defrag_cancelled + return signal_pending(current); + } + +-#define in_range(b, first, len) ((b) >= (first) && (b) < (first) + (len)) +- + /* Sanity test specific functions */ + #ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS + void btrfs_test_destroy_inode(struct inode *inode); +--- a/fs/btrfs/extent_io.c ++++ b/fs/btrfs/extent_io.c +@@ -13,6 +13,7 @@ + #include + #include + #include ++#include "misc.h" + #include "extent_io.h" + #include "extent-io-tree.h" + #include "extent_map.h" +--- a/fs/btrfs/file-item.c ++++ b/fs/btrfs/file-item.c +@@ -9,6 +9,7 @@ + #include + #include + #include ++#include "misc.h" + #include "ctree.h" + #include "disk-io.h" + #include "transaction.h" +--- a/fs/btrfs/raid56.c ++++ b/fs/btrfs/raid56.c +@@ -13,6 +13,7 @@ + #include + #include + #include ++#include "misc.h" + #include "ctree.h" + #include "disk-io.h" + #include "volumes.h" diff --git a/queue-5.10/minmax-add-a-few-more-min_t-max_t-users.patch b/queue-5.10/minmax-add-a-few-more-min_t-max_t-users.patch new file mode 100644 index 0000000000..65473cfb70 --- /dev/null +++ b/queue-5.10/minmax-add-a-few-more-min_t-max_t-users.patch @@ -0,0 +1,154 @@ +From prvs=378230090=farbere@amazon.com Fri Oct 17 11:10:08 2025 +From: Eliav Farber +Date: Fri, 17 Oct 2025 09:05:06 +0000 +Subject: minmax: add a few more MIN_T/MAX_T users +To: , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , +Cc: Linus Torvalds , David Laight , Lorenzo Stoakes +Message-ID: <20251017090519.46992-15-farbere@amazon.com> + +From: Linus Torvalds + +[ Upstream commit 4477b39c32fdc03363affef4b11d48391e6dc9ff ] + +Commit 3a7e02c040b1 ("minmax: avoid overly complicated constant +expressions in VM code") added the simpler MIN_T/MAX_T macros in order +to avoid some excessive expansion from the rather complicated regular +min/max macros. + +The complexity of those macros stems from two issues: + + (a) trying to use them in situations that require a C constant + expression (in static initializers and for array sizes) + + (b) the type sanity checking + +and MIN_T/MAX_T avoids both of these issues. + +Now, in the whole (long) discussion about all this, it was pointed out +that the whole type sanity checking is entirely unnecessary for +min_t/max_t which get a fixed type that the comparison is done in. + +But that still leaves min_t/max_t unnecessarily complicated due to +worries about the C constant expression case. + +However, it turns out that there really aren't very many cases that use +min_t/max_t for this, and we can just force-convert those. + +This does exactly that. + +Which in turn will then allow for much simpler implementations of +min_t()/max_t(). All the usual "macros in all upper case will evaluate +the arguments multiple times" rules apply. + +We should do all the same things for the regular min/max() vs MIN/MAX() +cases, but that has the added complexity of various drivers defining +their own local versions of MIN/MAX, so that needs another level of +fixes first. + +Link: https://lore.kernel.org/all/b47fad1d0cf8449886ad148f8c013dae@AcuMS.aculab.com/ +Cc: David Laight +Cc: Lorenzo Stoakes +Signed-off-by: Linus Torvalds +Signed-off-by: Eliav Farber +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/mm/pgtable.c | 2 +- + drivers/edac/sb_edac.c | 4 ++-- + drivers/gpu/drm/drm_color_mgmt.c | 2 +- + drivers/md/dm-integrity.c | 2 +- + drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 2 +- + fs/erofs/zdata.h | 2 +- + net/ipv4/proc.c | 2 +- + net/ipv6/proc.c | 2 +- + 8 files changed, 9 insertions(+), 9 deletions(-) + +--- a/arch/x86/mm/pgtable.c ++++ b/arch/x86/mm/pgtable.c +@@ -107,7 +107,7 @@ static inline void pgd_list_del(pgd_t *p + #define UNSHARED_PTRS_PER_PGD \ + (SHARED_KERNEL_PMD ? KERNEL_PGD_BOUNDARY : PTRS_PER_PGD) + #define MAX_UNSHARED_PTRS_PER_PGD \ +- max_t(size_t, KERNEL_PGD_BOUNDARY, PTRS_PER_PGD) ++ MAX_T(size_t, KERNEL_PGD_BOUNDARY, PTRS_PER_PGD) + + + static void pgd_set_mm(pgd_t *pgd, struct mm_struct *mm) +--- a/drivers/edac/sb_edac.c ++++ b/drivers/edac/sb_edac.c +@@ -109,8 +109,8 @@ static const u32 knl_interleave_list[] = + 0x104, 0x10c, 0x114, 0x11c, /* 20-23 */ + }; + #define MAX_INTERLEAVE \ +- (max_t(unsigned int, ARRAY_SIZE(sbridge_interleave_list), \ +- max_t(unsigned int, ARRAY_SIZE(ibridge_interleave_list), \ ++ (MAX_T(unsigned int, ARRAY_SIZE(sbridge_interleave_list), \ ++ MAX_T(unsigned int, ARRAY_SIZE(ibridge_interleave_list), \ + ARRAY_SIZE(knl_interleave_list)))) + + struct interleave_pkg { +--- a/drivers/gpu/drm/drm_color_mgmt.c ++++ b/drivers/gpu/drm/drm_color_mgmt.c +@@ -421,7 +421,7 @@ int drm_plane_create_color_properties(st + { + struct drm_device *dev = plane->dev; + struct drm_property *prop; +- struct drm_prop_enum_list enum_list[max_t(int, DRM_COLOR_ENCODING_MAX, ++ struct drm_prop_enum_list enum_list[MAX_T(int, DRM_COLOR_ENCODING_MAX, + DRM_COLOR_RANGE_MAX)]; + int i, len; + +--- a/drivers/md/dm-integrity.c ++++ b/drivers/md/dm-integrity.c +@@ -2431,7 +2431,7 @@ static void do_journal_write(struct dm_i + unlikely(from_replay) && + #endif + ic->internal_hash) { +- char test_tag[max_t(size_t, HASH_MAX_DIGESTSIZE, MAX_TAG_SIZE)]; ++ char test_tag[MAX_T(size_t, HASH_MAX_DIGESTSIZE, MAX_TAG_SIZE)]; + + integrity_sector_checksum(ic, sec + ((l - j) << ic->sb->log2_sectors_per_block), + (char *)access_journal_data(ic, i, l), test_tag); +--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c ++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +@@ -2267,7 +2267,7 @@ static void stmmac_dma_interrupt(struct + u32 channels_to_check = tx_channel_count > rx_channel_count ? + tx_channel_count : rx_channel_count; + u32 chan; +- int status[max_t(u32, MTL_MAX_TX_QUEUES, MTL_MAX_RX_QUEUES)]; ++ int status[MAX_T(u32, MTL_MAX_TX_QUEUES, MTL_MAX_RX_QUEUES)]; + + /* Make sure we never check beyond our status buffer. */ + if (WARN_ON_ONCE(channels_to_check > ARRAY_SIZE(status))) +--- a/fs/erofs/zdata.h ++++ b/fs/erofs/zdata.h +@@ -182,7 +182,7 @@ static inline void z_erofs_onlinepage_en + } + + #define Z_EROFS_VMAP_ONSTACK_PAGES \ +- min_t(unsigned int, THREAD_SIZE / 8 / sizeof(struct page *), 96U) ++ MIN_T(unsigned int, THREAD_SIZE / 8 / sizeof(struct page *), 96U) + #define Z_EROFS_VMAP_GLOBAL_PAGES 2048 + + #endif +--- a/net/ipv4/proc.c ++++ b/net/ipv4/proc.c +@@ -43,7 +43,7 @@ + #include + #include + +-#define TCPUDP_MIB_MAX max_t(u32, UDP_MIB_MAX, TCP_MIB_MAX) ++#define TCPUDP_MIB_MAX MAX_T(u32, UDP_MIB_MAX, TCP_MIB_MAX) + + /* + * Report socket allocation statistics [mea@utu.fi] +--- a/net/ipv6/proc.c ++++ b/net/ipv6/proc.c +@@ -27,7 +27,7 @@ + #include + + #define MAX4(a, b, c, d) \ +- max_t(u32, max_t(u32, a, b), max_t(u32, c, d)) ++ MAX_T(u32, MAX_T(u32, a, b), MAX_T(u32, c, d)) + #define SNMP_MIB_MAX MAX4(UDP_MIB_MAX, TCP_MIB_MAX, \ + IPSTATS_MIB_MAX, ICMP_MIB_MAX) + diff --git a/queue-5.10/minmax-add-in_range-macro.patch b/queue-5.10/minmax-add-in_range-macro.patch new file mode 100644 index 0000000000..ddb975aa30 --- /dev/null +++ b/queue-5.10/minmax-add-in_range-macro.patch @@ -0,0 +1,432 @@ +From prvs=378230090=farbere@amazon.com Fri Oct 17 11:07:27 2025 +From: Eliav Farber +Date: Fri, 17 Oct 2025 09:04:57 +0000 +Subject: minmax: add in_range() macro +To: , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , +Message-ID: <20251017090519.46992-6-farbere@amazon.com> + +From: "Matthew Wilcox (Oracle)" + +[ Upstream commit f9bff0e31881d03badf191d3b0005839391f5f2b ] + +Patch series "New page table range API", v6. + +This patchset changes the API used by the MM to set up page table entries. +The four APIs are: + + set_ptes(mm, addr, ptep, pte, nr) + update_mmu_cache_range(vma, addr, ptep, nr) + flush_dcache_folio(folio) + flush_icache_pages(vma, page, nr) + +flush_dcache_folio() isn't technically new, but no architecture +implemented it, so I've done that for them. The old APIs remain around +but are mostly implemented by calling the new interfaces. + +The new APIs are based around setting up N page table entries at once. +The N entries belong to the same PMD, the same folio and the same VMA, so +ptep++ is a legitimate operation, and locking is taken care of for you. +Some architectures can do a better job of it than just a loop, but I have +hesitated to make too deep a change to architectures I don't understand +well. + +One thing I have changed in every architecture is that PG_arch_1 is now a +per-folio bit instead of a per-page bit when used for dcache clean/dirty +tracking. This was something that would have to happen eventually, and it +makes sense to do it now rather than iterate over every page involved in a +cache flush and figure out if it needs to happen. + +The point of all this is better performance, and Fengwei Yin has measured +improvement on x86. I suspect you'll see improvement on your architecture +too. Try the new will-it-scale test mentioned here: +https://lore.kernel.org/linux-mm/20230206140639.538867-5-fengwei.yin@intel.com/ +You'll need to run it on an XFS filesystem and have +CONFIG_TRANSPARENT_HUGEPAGE set. + +This patchset is the basis for much of the anonymous large folio work +being done by Ryan, so it's received quite a lot of testing over the last +few months. + +This patch (of 38): + +Determine if a value lies within a range more efficiently (subtraction + +comparison vs two comparisons and an AND). It also has useful (under some +circumstances) behaviour if the range exceeds the maximum value of the +type. Convert all the conflicting definitions of in_range() within the +kernel; some can use the generic definition while others need their own +definition. + +Link: https://lkml.kernel.org/r/20230802151406.3735276-1-willy@infradead.org +Link: https://lkml.kernel.org/r/20230802151406.3735276-2-willy@infradead.org +Signed-off-by: Matthew Wilcox (Oracle) +Signed-off-by: Andrew Morton +Signed-off-by: Eliav Farber +Signed-off-by: Greg Kroah-Hartman +--- + arch/arm/mm/pageattr.c | 6 +- + drivers/gpu/drm/arm/display/include/malidp_utils.h | 2 + drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c | 24 +++++------ + drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 6 -- + drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c | 18 ++++---- + fs/btrfs/misc.h | 2 + fs/ext2/balloc.c | 2 + fs/ext4/ext4.h | 2 + fs/ufs/util.h | 6 -- + include/linux/minmax.h | 27 +++++++++++++ + lib/logic_pio.c | 3 - + net/netfilter/nf_nat_core.c | 6 +- + net/tipc/core.h | 2 + net/tipc/link.c | 10 ++-- + 14 files changed, 61 insertions(+), 55 deletions(-) + +--- a/arch/arm/mm/pageattr.c ++++ b/arch/arm/mm/pageattr.c +@@ -25,7 +25,7 @@ static int change_page_range(pte_t *ptep + return 0; + } + +-static bool in_range(unsigned long start, unsigned long size, ++static bool range_in_range(unsigned long start, unsigned long size, + unsigned long range_start, unsigned long range_end) + { + return start >= range_start && start < range_end && +@@ -46,8 +46,8 @@ static int change_memory_common(unsigned + if (!size) + return 0; + +- if (!in_range(start, size, MODULES_VADDR, MODULES_END) && +- !in_range(start, size, VMALLOC_START, VMALLOC_END)) ++ if (!range_in_range(start, size, MODULES_VADDR, MODULES_END) && ++ !range_in_range(start, size, VMALLOC_START, VMALLOC_END)) + return -EINVAL; + + data.set_mask = set_mask; +--- a/drivers/gpu/drm/arm/display/include/malidp_utils.h ++++ b/drivers/gpu/drm/arm/display/include/malidp_utils.h +@@ -35,7 +35,7 @@ static inline void set_range(struct mali + rg->end = end; + } + +-static inline bool in_range(struct malidp_range *rg, u32 v) ++static inline bool malidp_in_range(struct malidp_range *rg, u32 v) + { + return (v >= rg->start) && (v <= rg->end); + } +--- a/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c ++++ b/drivers/gpu/drm/arm/display/komeda/komeda_pipeline_state.c +@@ -305,12 +305,12 @@ komeda_layer_check_cfg(struct komeda_lay + if (komeda_fb_check_src_coords(kfb, src_x, src_y, src_w, src_h)) + return -EINVAL; + +- if (!in_range(&layer->hsize_in, src_w)) { ++ if (!malidp_in_range(&layer->hsize_in, src_w)) { + DRM_DEBUG_ATOMIC("invalidate src_w %d.\n", src_w); + return -EINVAL; + } + +- if (!in_range(&layer->vsize_in, src_h)) { ++ if (!malidp_in_range(&layer->vsize_in, src_h)) { + DRM_DEBUG_ATOMIC("invalidate src_h %d.\n", src_h); + return -EINVAL; + } +@@ -452,14 +452,14 @@ komeda_scaler_check_cfg(struct komeda_sc + hsize_out = dflow->out_w; + vsize_out = dflow->out_h; + +- if (!in_range(&scaler->hsize, hsize_in) || +- !in_range(&scaler->hsize, hsize_out)) { ++ if (!malidp_in_range(&scaler->hsize, hsize_in) || ++ !malidp_in_range(&scaler->hsize, hsize_out)) { + DRM_DEBUG_ATOMIC("Invalid horizontal sizes"); + return -EINVAL; + } + +- if (!in_range(&scaler->vsize, vsize_in) || +- !in_range(&scaler->vsize, vsize_out)) { ++ if (!malidp_in_range(&scaler->vsize, vsize_in) || ++ !malidp_in_range(&scaler->vsize, vsize_out)) { + DRM_DEBUG_ATOMIC("Invalid vertical sizes"); + return -EINVAL; + } +@@ -574,13 +574,13 @@ komeda_splitter_validate(struct komeda_s + return -EINVAL; + } + +- if (!in_range(&splitter->hsize, dflow->in_w)) { ++ if (!malidp_in_range(&splitter->hsize, dflow->in_w)) { + DRM_DEBUG_ATOMIC("split in_w:%d is out of the acceptable range.\n", + dflow->in_w); + return -EINVAL; + } + +- if (!in_range(&splitter->vsize, dflow->in_h)) { ++ if (!malidp_in_range(&splitter->vsize, dflow->in_h)) { + DRM_DEBUG_ATOMIC("split in_h: %d exceeds the acceptable range.\n", + dflow->in_h); + return -EINVAL; +@@ -624,13 +624,13 @@ komeda_merger_validate(struct komeda_mer + return -EINVAL; + } + +- if (!in_range(&merger->hsize_merged, output->out_w)) { ++ if (!malidp_in_range(&merger->hsize_merged, output->out_w)) { + DRM_DEBUG_ATOMIC("merged_w: %d is out of the accepted range.\n", + output->out_w); + return -EINVAL; + } + +- if (!in_range(&merger->vsize_merged, output->out_h)) { ++ if (!malidp_in_range(&merger->vsize_merged, output->out_h)) { + DRM_DEBUG_ATOMIC("merged_h: %d is out of the accepted range.\n", + output->out_h); + return -EINVAL; +@@ -866,8 +866,8 @@ void komeda_complete_data_flow_cfg(struc + * input/output range. + */ + if (dflow->en_scaling && scaler) +- dflow->en_split = !in_range(&scaler->hsize, dflow->in_w) || +- !in_range(&scaler->hsize, dflow->out_w); ++ dflow->en_split = !malidp_in_range(&scaler->hsize, dflow->in_w) || ++ !malidp_in_range(&scaler->hsize, dflow->out_w); + } + + static bool merger_is_available(struct komeda_pipeline *pipe, +--- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c ++++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c +@@ -657,12 +657,6 @@ struct block_header { + u32 data[]; + }; + +-/* this should be a general kernel helper */ +-static int in_range(u32 addr, u32 start, u32 size) +-{ +- return addr >= start && addr < start + size; +-} +- + static bool fw_block_mem(struct a6xx_gmu_bo *bo, const struct block_header *blk) + { + if (!in_range(blk->addr, bo->iova, bo->size)) +--- a/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c ++++ b/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c +@@ -2131,7 +2131,7 @@ static const struct ethtool_ops cxgb_eth + .set_link_ksettings = set_link_ksettings, + }; + +-static int in_range(int val, int lo, int hi) ++static int cxgb_in_range(int val, int lo, int hi) + { + return val < 0 || (val <= hi && val >= lo); + } +@@ -2162,19 +2162,19 @@ static int cxgb_extension_ioctl(struct n + return -EINVAL; + if (t.qset_idx >= SGE_QSETS) + return -EINVAL; +- if (!in_range(t.intr_lat, 0, M_NEWTIMER) || +- !in_range(t.cong_thres, 0, 255) || +- !in_range(t.txq_size[0], MIN_TXQ_ENTRIES, ++ if (!cxgb_in_range(t.intr_lat, 0, M_NEWTIMER) || ++ !cxgb_in_range(t.cong_thres, 0, 255) || ++ !cxgb_in_range(t.txq_size[0], MIN_TXQ_ENTRIES, + MAX_TXQ_ENTRIES) || +- !in_range(t.txq_size[1], MIN_TXQ_ENTRIES, ++ !cxgb_in_range(t.txq_size[1], MIN_TXQ_ENTRIES, + MAX_TXQ_ENTRIES) || +- !in_range(t.txq_size[2], MIN_CTRL_TXQ_ENTRIES, ++ !cxgb_in_range(t.txq_size[2], MIN_CTRL_TXQ_ENTRIES, + MAX_CTRL_TXQ_ENTRIES) || +- !in_range(t.fl_size[0], MIN_FL_ENTRIES, ++ !cxgb_in_range(t.fl_size[0], MIN_FL_ENTRIES, + MAX_RX_BUFFERS) || +- !in_range(t.fl_size[1], MIN_FL_ENTRIES, ++ !cxgb_in_range(t.fl_size[1], MIN_FL_ENTRIES, + MAX_RX_JUMBO_BUFFERS) || +- !in_range(t.rspq_size, MIN_RSPQ_ENTRIES, ++ !cxgb_in_range(t.rspq_size, MIN_RSPQ_ENTRIES, + MAX_RSPQ_ENTRIES)) + return -EINVAL; + +--- a/fs/btrfs/misc.h ++++ b/fs/btrfs/misc.h +@@ -8,8 +8,6 @@ + #include + #include + +-#define in_range(b, first, len) ((b) >= (first) && (b) < (first) + (len)) +- + static inline void cond_wake_up(struct wait_queue_head *wq) + { + /* +--- a/fs/ext2/balloc.c ++++ b/fs/ext2/balloc.c +@@ -36,8 +36,6 @@ + */ + + +-#define in_range(b, first, len) ((b) >= (first) && (b) <= (first) + (len) - 1) +- + struct ext2_group_desc * ext2_get_group_desc(struct super_block * sb, + unsigned int block_group, + struct buffer_head ** bh) +--- a/fs/ext4/ext4.h ++++ b/fs/ext4/ext4.h +@@ -3659,8 +3659,6 @@ static inline void set_bitmap_uptodate(s + set_bit(BH_BITMAP_UPTODATE, &(bh)->b_state); + } + +-#define in_range(b, first, len) ((b) >= (first) && (b) <= (first) + (len) - 1) +- + /* For ioend & aio unwritten conversion wait queues */ + #define EXT4_WQ_HASH_SZ 37 + #define ext4_ioend_wq(v) (&ext4__ioend_wq[((unsigned long)(v)) %\ +--- a/fs/ufs/util.h ++++ b/fs/ufs/util.h +@@ -11,12 +11,6 @@ + #include + #include "swab.h" + +- +-/* +- * some useful macros +- */ +-#define in_range(b,first,len) ((b)>=(first)&&(b)<(first)+(len)) +- + /* + * functions used for retyping + */ +--- a/include/linux/minmax.h ++++ b/include/linux/minmax.h +@@ -3,6 +3,7 @@ + #define _LINUX_MINMAX_H + + #include ++#include + + /* + * min()/max()/clamp() macros must accomplish three things: +@@ -175,6 +176,32 @@ + */ + #define clamp_val(val, lo, hi) clamp_t(typeof(val), val, lo, hi) + ++static inline bool in_range64(u64 val, u64 start, u64 len) ++{ ++ return (val - start) < len; ++} ++ ++static inline bool in_range32(u32 val, u32 start, u32 len) ++{ ++ return (val - start) < len; ++} ++ ++/** ++ * in_range - Determine if a value lies within a range. ++ * @val: Value to test. ++ * @start: First value in range. ++ * @len: Number of values in range. ++ * ++ * This is more efficient than "if (start <= val && val < (start + len))". ++ * It also gives a different answer if @start + @len overflows the size of ++ * the type by a sufficient amount to encompass @val. Decide for yourself ++ * which behaviour you want, or prove that start + len never overflow. ++ * Do not blindly replace one form with the other. ++ */ ++#define in_range(val, start, len) \ ++ ((sizeof(start) | sizeof(len) | sizeof(val)) <= sizeof(u32) ? \ ++ in_range32(val, start, len) : in_range64(val, start, len)) ++ + /** + * swap - swap values of @a and @b + * @a: first value +--- a/lib/logic_pio.c ++++ b/lib/logic_pio.c +@@ -20,9 +20,6 @@ + static LIST_HEAD(io_range_list); + static DEFINE_MUTEX(io_range_mutex); + +-/* Consider a kernel general helper for this */ +-#define in_range(b, first, len) ((b) >= (first) && (b) < (first) + (len)) +- + /** + * logic_pio_register_range - register logical PIO range for a host + * @new_range: pointer to the IO range to be registered. +--- a/net/netfilter/nf_nat_core.c ++++ b/net/netfilter/nf_nat_core.c +@@ -262,7 +262,7 @@ static bool l4proto_in_range(const struc + /* If we source map this tuple so reply looks like reply_tuple, will + * that meet the constraints of range. + */ +-static int in_range(const struct nf_conntrack_tuple *tuple, ++static int nf_in_range(const struct nf_conntrack_tuple *tuple, + const struct nf_nat_range2 *range) + { + /* If we are supposed to map IPs, then we must be in the +@@ -311,7 +311,7 @@ find_appropriate_src(struct net *net, + &ct->tuplehash[IP_CT_DIR_REPLY].tuple); + result->dst = tuple->dst; + +- if (in_range(result, range)) ++ if (nf_in_range(result, range)) + return 1; + } + } +@@ -543,7 +543,7 @@ get_unique_tuple(struct nf_conntrack_tup + if (maniptype == NF_NAT_MANIP_SRC && + !(range->flags & NF_NAT_RANGE_PROTO_RANDOM_ALL)) { + /* try the original tuple first */ +- if (in_range(orig_tuple, range)) { ++ if (nf_in_range(orig_tuple, range)) { + if (!nf_nat_used_tuple(orig_tuple, ct)) { + *tuple = *orig_tuple; + return; +--- a/net/tipc/core.h ++++ b/net/tipc/core.h +@@ -199,7 +199,7 @@ static inline int less(u16 left, u16 rig + return less_eq(left, right) && (mod(right) != mod(left)); + } + +-static inline int in_range(u16 val, u16 min, u16 max) ++static inline int tipc_in_range(u16 val, u16 min, u16 max) + { + return !less(val, min) && !more(val, max); + } +--- a/net/tipc/link.c ++++ b/net/tipc/link.c +@@ -1588,7 +1588,7 @@ next_gap_ack: + last_ga->bgack_cnt); + } + /* Check against the last Gap ACK block */ +- if (in_range(seqno, start, end)) ++ if (tipc_in_range(seqno, start, end)) + continue; + /* Update/release the packet peer is acking */ + bc_has_acked = true; +@@ -2216,12 +2216,12 @@ static int tipc_link_proto_rcv(struct ti + strncpy(if_name, data, TIPC_MAX_IF_NAME); + + /* Update own tolerance if peer indicates a non-zero value */ +- if (in_range(peers_tol, TIPC_MIN_LINK_TOL, TIPC_MAX_LINK_TOL)) { ++ if (tipc_in_range(peers_tol, TIPC_MIN_LINK_TOL, TIPC_MAX_LINK_TOL)) { + l->tolerance = peers_tol; + l->bc_rcvlink->tolerance = peers_tol; + } + /* Update own priority if peer's priority is higher */ +- if (in_range(peers_prio, l->priority + 1, TIPC_MAX_LINK_PRI)) ++ if (tipc_in_range(peers_prio, l->priority + 1, TIPC_MAX_LINK_PRI)) + l->priority = peers_prio; + + /* If peer is going down we want full re-establish cycle */ +@@ -2264,13 +2264,13 @@ static int tipc_link_proto_rcv(struct ti + l->rcv_nxt_state = msg_seqno(hdr) + 1; + + /* Update own tolerance if peer indicates a non-zero value */ +- if (in_range(peers_tol, TIPC_MIN_LINK_TOL, TIPC_MAX_LINK_TOL)) { ++ if (tipc_in_range(peers_tol, TIPC_MIN_LINK_TOL, TIPC_MAX_LINK_TOL)) { + l->tolerance = peers_tol; + l->bc_rcvlink->tolerance = peers_tol; + } + /* Update own prio if peer indicates a different value */ + if ((peers_prio != l->priority) && +- in_range(peers_prio, 1, TIPC_MAX_LINK_PRI)) { ++ tipc_in_range(peers_prio, 1, TIPC_MAX_LINK_PRI)) { + l->priority = peers_prio; + rc = tipc_link_fsm_evt(l, LINK_FAILURE_EVT); + } diff --git a/queue-5.10/minmax-allow-comparisons-of-int-against-unsigned-char-short.patch b/queue-5.10/minmax-allow-comparisons-of-int-against-unsigned-char-short.patch new file mode 100644 index 0000000000..b8cd043dd6 --- /dev/null +++ b/queue-5.10/minmax-allow-comparisons-of-int-against-unsigned-char-short.patch @@ -0,0 +1,43 @@ +From prvs=378230090=farbere@amazon.com Fri Oct 17 11:08:59 2025 +From: Eliav Farber +Date: Fri, 17 Oct 2025 09:05:03 +0000 +Subject: minmax: allow comparisons of 'int' against 'unsigned char/short' +To: , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , +Cc: Christoph Hellwig , Linus Torvalds +Message-ID: <20251017090519.46992-12-farbere@amazon.com> + +From: David Laight + +[ Upstream commit 4ead534fba42fc4fd41163297528d2aa731cd121 ] + +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.aculab.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 +Signed-off-by: Eliav Farber +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/minmax.h | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/include/linux/minmax.h ++++ b/include/linux/minmax.h +@@ -26,8 +26,9 @@ + __builtin_choose_expr(__is_constexpr(is_signed_type(typeof(x))), \ + is_signed_type(typeof(x)), 0) + +-#define __types_ok(x, y) \ +- (__is_signed(x) == __is_signed(y)) ++#define __types_ok(x, y) \ ++ (__is_signed(x) == __is_signed(y) || \ ++ __is_signed((x) + 0) == __is_signed((y) + 0)) + + #define __cmp_op_min < + #define __cmp_op_max > diff --git a/queue-5.10/minmax-allow-min-max-clamp-if-the-arguments-have-the-same-signedness.patch b/queue-5.10/minmax-allow-min-max-clamp-if-the-arguments-have-the-same-signedness.patch new file mode 100644 index 0000000000..75a0e42414 --- /dev/null +++ b/queue-5.10/minmax-allow-min-max-clamp-if-the-arguments-have-the-same-signedness.patch @@ -0,0 +1,174 @@ +From prvs=378230090=farbere@amazon.com Fri Oct 17 11:08:35 2025 +From: Eliav Farber +Date: Fri, 17 Oct 2025 09:05:01 +0000 +Subject: minmax: allow min()/max()/clamp() if the arguments have the same signedness. +To: , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , +Cc: Christoph Hellwig , Linus Torvalds +Message-ID: <20251017090519.46992-10-farbere@amazon.com> + +From: David Laight + +[ Upstream commit d03eba99f5bf7cbc6e2fdde3b6fa36954ad58e09 ] + +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.aculab.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 +Signed-off-by: Eliav Farber +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/minmax.h | 62 ++++++++++++++++++++++++++----------------------- + 1 file changed, 33 insertions(+), 29 deletions(-) + +--- a/include/linux/minmax.h ++++ b/include/linux/minmax.h +@@ -12,9 +12,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). +@@ -22,23 +21,30 @@ + #define __typecheck(x, y) \ + (!!(sizeof((typeof(x) *)1 == (typeof(y) *)1))) + +-#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) + +-#define __safe_cmp(x, y) \ +- (__typecheck(x, y) && __no_side_effects(x, y)) ++#define __types_ok(x, y) \ ++ (__is_signed(x) == __is_signed(y)) + +-#define __cmp(x, y, op) ((x) op (y) ? (x) : (y)) ++#define __cmp_op_min < ++#define __cmp_op_max > + +-#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 = (x); \ + typeof(y) unique_y = (y); \ +- __cmp(unique_x, unique_y, op); }) +- +-#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)) ++ 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); }) ++ ++#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))) + + #define __clamp(val, lo, hi) \ + ((val) >= (hi) ? (hi) : ((val) <= (lo) ? (lo) : (val))) +@@ -47,17 +53,15 @@ + typeof(val) unique_val = (val); \ + typeof(lo) unique_lo = (lo); \ + typeof(hi) unique_hi = (hi); \ ++ static_assert(__builtin_choose_expr(__is_constexpr((lo) > (hi)), \ ++ (lo) <= (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); }) + +-#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))); }) +@@ -67,14 +71,14 @@ + * @x: first value + * @y: second value + */ +-#define min(x, y) __careful_cmp(x, y, <) ++#define min(x, y) __careful_cmp(min, x, y) + + /** + * 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) + + /** + * umin - return minimum of two non-negative values +@@ -83,7 +87,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) + + /** + * umax - return maximum of two non-negative values +@@ -91,7 +95,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) + + /** + * min3 - return minimum of three values +@@ -143,7 +147,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)) + + /** + * max_t - return maximum of two values, using the specified type +@@ -151,7 +155,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)) + + /* + * Do not check the array parameter using __must_be_array(). diff --git a/queue-5.10/minmax-avoid-overly-complicated-constant-expressions-in-vm-code.patch b/queue-5.10/minmax-avoid-overly-complicated-constant-expressions-in-vm-code.patch new file mode 100644 index 0000000000..77a729909e --- /dev/null +++ b/queue-5.10/minmax-avoid-overly-complicated-constant-expressions-in-vm-code.patch @@ -0,0 +1,66 @@ +From prvs=378230090=farbere@amazon.com Fri Oct 17 11:09:55 2025 +From: Eliav Farber +Date: Fri, 17 Oct 2025 09:05:05 +0000 +Subject: minmax: avoid overly complicated constant expressions in VM code +To: , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , +Cc: Linus Torvalds , Lorenzo Stoakes , David Laight +Message-ID: <20251017090519.46992-14-farbere@amazon.com> + +From: Linus Torvalds + +[ Upstream commit 3a7e02c040b130b5545e4b115aada7bacd80a2b6 ] + +The minmax infrastructure is overkill for simple constants, and can +cause huge expansions because those simple constants are then used by +other things. + +For example, 'pageblock_order' is a core VM constant, but because it was +implemented using 'min_t()' and all the type-checking that involves, it +actually expanded to something like 2.5kB of preprocessor noise. + +And when that simple constant was then used inside other expansions: + + #define pageblock_nr_pages (1UL << pageblock_order) + #define pageblock_start_pfn(pfn) ALIGN_DOWN((pfn), pageblock_nr_pages) + +and we then use that inside a 'max()' macro: + + case ISOLATE_SUCCESS: + update_cached = false; + last_migrated_pfn = max(cc->zone->zone_start_pfn, + pageblock_start_pfn(cc->migrate_pfn - 1)); + +the end result was that one statement expanding to 253kB in size. + +There are probably other cases of this, but this one case certainly +stood out. + +I've added 'MIN_T()' and 'MAX_T()' macros for this kind of "core simple +constant with specific type" use. These macros skip the type checking, +and as such need to be very sparingly used only for obvious cases that +have active issues like this. + +Reported-by: Lorenzo Stoakes +Link: https://lore.kernel.org/all/36aa2cad-1db1-4abf-8dd2-fb20484aabc3@lucifer.local/ +Cc: David Laight +Signed-off-by: Linus Torvalds +Signed-off-by: Eliav Farber +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/minmax.h | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/include/linux/minmax.h ++++ b/include/linux/minmax.h +@@ -270,4 +270,11 @@ static inline bool in_range32(u32 val, u + #define swap(a, b) \ + do { typeof(a) __tmp = (a); (a) = (b); (b) = __tmp; } while (0) + ++/* ++ * Use these carefully: no type checking, and uses the arguments ++ * multiple times. Use for obvious constants only. ++ */ ++#define MIN_T(type,a,b) __cmp(min,(type)(a),(type)(b)) ++#define MAX_T(type,a,b) __cmp(max,(type)(a),(type)(b)) ++ + #endif /* _LINUX_MINMAX_H */ diff --git a/queue-5.10/minmax-clamp-more-efficiently-by-avoiding-extra-comparison.patch b/queue-5.10/minmax-clamp-more-efficiently-by-avoiding-extra-comparison.patch new file mode 100644 index 0000000000..e7ec30bc74 --- /dev/null +++ b/queue-5.10/minmax-clamp-more-efficiently-by-avoiding-extra-comparison.patch @@ -0,0 +1,184 @@ +From prvs=378230090=farbere@amazon.com Fri Oct 17 11:07:07 2025 +From: Eliav Farber +Date: Fri, 17 Oct 2025 09:04:56 +0000 +Subject: minmax: clamp more efficiently by avoiding extra comparison +To: , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , +Message-ID: <20251017090519.46992-5-farbere@amazon.com> + +From: "Jason A. Donenfeld" + +[ 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 +Cc: Andy Shevchenko +Cc: Kees Cook +Signed-off-by: Andrew Morton +Signed-off-by: Eliav Farber +Signed-off-by: Greg Kroah-Hartman +--- + 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); \ diff --git a/queue-5.10/minmax-deduplicate-__unconst_integer_typeof.patch b/queue-5.10/minmax-deduplicate-__unconst_integer_typeof.patch new file mode 100644 index 0000000000..441d2d997c --- /dev/null +++ b/queue-5.10/minmax-deduplicate-__unconst_integer_typeof.patch @@ -0,0 +1,79 @@ +From prvs=378230090=farbere@amazon.com Fri Oct 17 11:07:56 2025 +From: Eliav Farber +Date: Fri, 17 Oct 2025 09:04:59 +0000 +Subject: minmax: deduplicate __unconst_integer_typeof() +To: , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , +Message-ID: <20251017090519.46992-8-farbere@amazon.com> + +From: Andy Shevchenko + +[ Upstream commit 5e57418a2031cd5e1863efdf3d7447a16a368172 ] + +It appears that compiler_types.h already have an implementation of the +__unconst_integer_typeof() called __unqual_scalar_typeof(). Use it +instead of the copy. + +Link: https://lkml.kernel.org/r/20230911154913.4176033-1-andriy.shevchenko@linux.intel.com +Signed-off-by: Andy Shevchenko +Acked-by: Herve Codina +Signed-off-by: Andrew Morton +Signed-off-by: Eliav Farber +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/minmax.h | 26 +++----------------------- + 1 file changed, 3 insertions(+), 23 deletions(-) + +--- a/include/linux/minmax.h ++++ b/include/linux/minmax.h +@@ -2,6 +2,7 @@ + #ifndef _LINUX_MINMAX_H + #define _LINUX_MINMAX_H + ++#include + #include + #include + +@@ -152,27 +153,6 @@ + #define max_t(type, x, y) __careful_cmp((type)(x), (type)(y), >) + + /* +- * Remove a const qualifier from integer types +- * _Generic(foo, type-name: association, ..., default: association) performs a +- * comparison against the foo type (not the qualified type). +- * Do not use the const keyword in the type-name as it will not match the +- * unqualified type of foo. +- */ +-#define __unconst_integer_type_cases(type) \ +- unsigned type: (unsigned type)0, \ +- signed type: (signed type)0 +- +-#define __unconst_integer_typeof(x) typeof( \ +- _Generic((x), \ +- char: (char)0, \ +- __unconst_integer_type_cases(char), \ +- __unconst_integer_type_cases(short), \ +- __unconst_integer_type_cases(int), \ +- __unconst_integer_type_cases(long), \ +- __unconst_integer_type_cases(long long), \ +- default: (x))) +- +-/* + * Do not check the array parameter using __must_be_array(). + * In the following legit use-case where the "array" passed is a simple pointer, + * __must_be_array() will return a failure. +@@ -186,13 +166,13 @@ + * 'int *buff' and 'int buff[N]' types. + * + * The array can be an array of const items. +- * typeof() keeps the const qualifier. Use __unconst_integer_typeof() in order ++ * typeof() keeps the const qualifier. Use __unqual_scalar_typeof() in order + * to discard the const qualifier for the __element variable. + */ + #define __minmax_array(op, array, len) ({ \ + typeof(&(array)[0]) __array = (array); \ + typeof(len) __len = (len); \ +- __unconst_integer_typeof(__array[0]) __element = __array[--__len]; \ ++ __unqual_scalar_typeof(__array[0]) __element = __array[--__len];\ + while (__len--) \ + __element = op(__element, __array[__len]); \ + __element; }) diff --git a/queue-5.10/minmax-don-t-use-max-in-situations-that-want-a-c-constant-expression.patch b/queue-5.10/minmax-don-t-use-max-in-situations-that-want-a-c-constant-expression.patch new file mode 100644 index 0000000000..dadf86f8ba --- /dev/null +++ b/queue-5.10/minmax-don-t-use-max-in-situations-that-want-a-c-constant-expression.patch @@ -0,0 +1,84 @@ +From prvs=378230090=farbere@amazon.com Fri Oct 17 11:11:06 2025 +From: Eliav Farber +Date: Fri, 17 Oct 2025 09:05:09 +0000 +Subject: minmax: don't use max() in situations that want a C constant expression +To: , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , +Cc: Linus Torvalds , David Laight , Lorenzo Stoakes +Message-ID: <20251017090519.46992-18-farbere@amazon.com> + +From: Linus Torvalds + +[ Upstream commit cb04e8b1d2f24c4c2c92f7b7529031fc35a16fed ] + +We only had a couple of array[] declarations, and changing them to just +use 'MAX()' instead of 'max()' fixes the issue. + +This will allow us to simplify our min/max macros enormously, since they +can now unconditionally use temporary variables to avoid using the +argument values multiple times. + +Cc: David Laight +Cc: Lorenzo Stoakes +Signed-off-by: Linus Torvalds +Signed-off-by: Eliav Farber +Signed-off-by: Greg Kroah-Hartman +--- + drivers/input/touchscreen/cyttsp4_core.c | 2 +- + drivers/md/dm-integrity.c | 4 ++-- + fs/btrfs/tree-checker.c | 2 +- + lib/vsprintf.c | 2 +- + 4 files changed, 5 insertions(+), 5 deletions(-) + +--- a/drivers/input/touchscreen/cyttsp4_core.c ++++ b/drivers/input/touchscreen/cyttsp4_core.c +@@ -857,7 +857,7 @@ static void cyttsp4_get_mt_touches(struc + struct cyttsp4_touch tch; + int sig; + int i, j, t = 0; +- int ids[max(CY_TMA1036_MAX_TCH, CY_TMA4XX_MAX_TCH)]; ++ int ids[MAX(CY_TMA1036_MAX_TCH, CY_TMA4XX_MAX_TCH)]; + + memset(ids, 0, si->si_ofs.tch_abs[CY_TCH_T].max * sizeof(int)); + for (i = 0; i < num_cur_tch; i++) { +--- a/drivers/md/dm-integrity.c ++++ b/drivers/md/dm-integrity.c +@@ -1600,7 +1600,7 @@ static void integrity_metadata(struct wo + struct bio *bio = dm_bio_from_per_bio_data(dio, sizeof(struct dm_integrity_io)); + char *checksums; + unsigned extra_space = unlikely(digest_size > ic->tag_size) ? digest_size - ic->tag_size : 0; +- char checksums_onstack[max((size_t)HASH_MAX_DIGESTSIZE, MAX_TAG_SIZE)]; ++ char checksums_onstack[MAX(HASH_MAX_DIGESTSIZE, MAX_TAG_SIZE)]; + sector_t sector; + unsigned sectors_to_process; + +@@ -1882,7 +1882,7 @@ retry_kmap: + } while (++s < ic->sectors_per_block); + #ifdef INTERNAL_VERIFY + if (ic->internal_hash) { +- char checksums_onstack[max((size_t)HASH_MAX_DIGESTSIZE, MAX_TAG_SIZE)]; ++ char checksums_onstack[MAX(HASH_MAX_DIGESTSIZE, MAX_TAG_SIZE)]; + + integrity_sector_checksum(ic, logical_sector, mem + bv.bv_offset, checksums_onstack); + if (unlikely(memcmp(checksums_onstack, journal_entry_tag(ic, je), ic->tag_size))) { +--- a/fs/btrfs/tree-checker.c ++++ b/fs/btrfs/tree-checker.c +@@ -587,7 +587,7 @@ static int check_dir_item(struct extent_ + */ + if (key->type == BTRFS_DIR_ITEM_KEY || + key->type == BTRFS_XATTR_ITEM_KEY) { +- char namebuf[max(BTRFS_NAME_LEN, XATTR_NAME_MAX)]; ++ char namebuf[MAX(BTRFS_NAME_LEN, XATTR_NAME_MAX)]; + + read_extent_buffer(leaf, namebuf, + (unsigned long)(di + 1), name_len); +--- a/lib/vsprintf.c ++++ b/lib/vsprintf.c +@@ -1078,7 +1078,7 @@ char *resource_string(char *buf, char *e + #define FLAG_BUF_SIZE (2 * sizeof(res->flags)) + #define DECODED_BUF_SIZE sizeof("[mem - 64bit pref window disabled]") + #define RAW_BUF_SIZE sizeof("[mem - flags 0x]") +- char sym[max(2*RSRC_BUF_SIZE + DECODED_BUF_SIZE, ++ char sym[MAX(2*RSRC_BUF_SIZE + DECODED_BUF_SIZE, + 2*RSRC_BUF_SIZE + FLAG_BUF_SIZE + RAW_BUF_SIZE)]; + + char *p = sym, *pend = sym + sizeof(sym); diff --git a/queue-5.10/minmax-fix-header-inclusions.patch b/queue-5.10/minmax-fix-header-inclusions.patch new file mode 100644 index 0000000000..93f409a784 --- /dev/null +++ b/queue-5.10/minmax-fix-header-inclusions.patch @@ -0,0 +1,39 @@ +From prvs=378230090=farbere@amazon.com Fri Oct 17 11:08:16 2025 +From: Eliav Farber +Date: Fri, 17 Oct 2025 09:05:00 +0000 +Subject: minmax: fix header inclusions +To: , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , +Message-ID: <20251017090519.46992-9-farbere@amazon.com> + +From: Andy Shevchenko + +[ Upstream commit f6e9d38f8eb00ac8b52e6d15f6aa9bcecacb081b ] + +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@linux.intel.com +Signed-off-by: Andy Shevchenko +Reviewed-by: Herve Codina +Cc: Rasmus Villemoes + +Signed-off-by: Andrew Morton +Signed-off-by: Eliav Farber +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/minmax.h | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/include/linux/minmax.h ++++ b/include/linux/minmax.h +@@ -2,7 +2,8 @@ + #ifndef _LINUX_MINMAX_H + #define _LINUX_MINMAX_H + +-#include ++#include ++#include + #include + #include + diff --git a/queue-5.10/minmax-fix-indentation-of-__cmp_once-and-__clamp_once.patch b/queue-5.10/minmax-fix-indentation-of-__cmp_once-and-__clamp_once.patch new file mode 100644 index 0000000000..9cf006ad94 --- /dev/null +++ b/queue-5.10/minmax-fix-indentation-of-__cmp_once-and-__clamp_once.patch @@ -0,0 +1,74 @@ +From prvs=378230090=farbere@amazon.com Fri Oct 17 11:08:55 2025 +From: Eliav Farber +Date: Fri, 17 Oct 2025 09:05:02 +0000 +Subject: minmax: fix indentation of __cmp_once() and __clamp_once() +To: , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , +Cc: Christoph Hellwig , Linus Torvalds +Message-ID: <20251017090519.46992-11-farbere@amazon.com> + +From: David Laight + +[ Upstream commit f4b84b2ff851f01d0fac619eadef47eb41648534 ] + +Remove the extra indentation and align continuation markers. + +Link: https://lkml.kernel.org/r/bed41317a05c498ea0209eafbcab45a5@AcuMS.aculab.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 +Signed-off-by: Eliav Farber +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/minmax.h | 30 +++++++++++++++--------------- + 1 file changed, 15 insertions(+), 15 deletions(-) + +--- a/include/linux/minmax.h ++++ b/include/linux/minmax.h +@@ -35,11 +35,11 @@ + #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 = (x); \ +- typeof(y) unique_y = (y); \ +- 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); }) ++ typeof(x) unique_x = (x); \ ++ typeof(y) unique_y = (y); \ ++ 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); }) + + #define __careful_cmp(op, x, y) \ + __builtin_choose_expr(__is_constexpr((x) - (y)), \ +@@ -49,16 +49,16 @@ + #define __clamp(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); \ +- typeof(lo) unique_lo = (lo); \ +- typeof(hi) unique_hi = (hi); \ +- static_assert(__builtin_choose_expr(__is_constexpr((lo) > (hi)), \ +- (lo) <= (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); }) ++#define __clamp_once(val, lo, hi, unique_val, unique_lo, unique_hi) ({ \ ++ typeof(val) unique_val = (val); \ ++ typeof(lo) unique_lo = (lo); \ ++ typeof(hi) unique_hi = (hi); \ ++ static_assert(__builtin_choose_expr(__is_constexpr((lo) > (hi)), \ ++ (lo) <= (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); }) + + #define __careful_clamp(val, lo, hi) ({ \ + __builtin_choose_expr(__is_constexpr((val) - (lo) + (hi)), \ diff --git a/queue-5.10/minmax-fix-up-min3-and-max3-too.patch b/queue-5.10/minmax-fix-up-min3-and-max3-too.patch new file mode 100644 index 0000000000..aec6d2c66b --- /dev/null +++ b/queue-5.10/minmax-fix-up-min3-and-max3-too.patch @@ -0,0 +1,79 @@ +From prvs=378230090=farbere@amazon.com Fri Oct 17 11:12:01 2025 +From: Eliav Farber +Date: Fri, 17 Oct 2025 09:05:12 +0000 +Subject: minmax: fix up min3() and max3() too +To: , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , +Cc: Linus Torvalds , David Laight , Arnd Bergmann +Message-ID: <20251017090519.46992-21-farbere@amazon.com> + +From: Linus Torvalds + +[ Upstream commit 21b136cc63d2a9ddd60d4699552b69c214b32964 ] + +David Laight pointed out that we should deal with the min3() and max3() +mess too, which still does excessive expansion. + +And our current macros are actually rather broken. + +In particular, the macros did this: + + #define min3(x, y, z) min((typeof(x))min(x, y), z) + #define max3(x, y, z) max((typeof(x))max(x, y), z) + +and that not only is a nested expansion of possibly very complex +arguments with all that involves, the typing with that "typeof()" cast +is completely wrong. + +For example, imagine what happens in max3() if 'x' happens to be a +'unsigned char', but 'y' and 'z' are 'unsigned long'. The types are +compatible, and there's no warning - but the result is just random +garbage. + +No, I don't think we've ever hit that issue in practice, but since we +now have sane infrastructure for doing this right, let's just use it. +It fixes any excessive expansion, and also avoids these kinds of broken +type issues. + +Requested-by: David Laight +Acked-by: Arnd Bergmann +Signed-off-by: Linus Torvalds +Signed-off-by: Eliav Farber +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/minmax.h | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +--- a/include/linux/minmax.h ++++ b/include/linux/minmax.h +@@ -152,13 +152,20 @@ + #define umax(x, y) \ + __careful_cmp(max, (x) + 0u + 0ul + 0ull, (y) + 0u + 0ul + 0ull) + ++#define __careful_op3(op, x, y, z, ux, uy, uz) ({ \ ++ __auto_type ux = (x); __auto_type uy = (y);__auto_type uz = (z);\ ++ BUILD_BUG_ON_MSG(!__types_ok3(x,y,z,ux,uy,uz), \ ++ #op"3("#x", "#y", "#z") signedness error"); \ ++ __cmp(op, ux, __cmp(op, uy, uz)); }) ++ + /** + * min3 - return minimum of three values + * @x: first value + * @y: second value + * @z: third value + */ +-#define min3(x, y, z) min((typeof(x))min(x, y), z) ++#define min3(x, y, z) \ ++ __careful_op3(min, x, y, z, __UNIQUE_ID(x_), __UNIQUE_ID(y_), __UNIQUE_ID(z_)) + + /** + * max3 - return maximum of three values +@@ -166,7 +173,8 @@ + * @y: second value + * @z: third value + */ +-#define max3(x, y, z) max((typeof(x))max(x, y), z) ++#define max3(x, y, z) \ ++ __careful_op3(max, x, y, z, __UNIQUE_ID(x_), __UNIQUE_ID(y_), __UNIQUE_ID(z_)) + + /** + * min_not_zero - return the minimum that is _not_ zero, unless both are zero diff --git a/queue-5.10/minmax-improve-macro-expansion-and-type-checking.patch b/queue-5.10/minmax-improve-macro-expansion-and-type-checking.patch new file mode 100644 index 0000000000..645d7c702a --- /dev/null +++ b/queue-5.10/minmax-improve-macro-expansion-and-type-checking.patch @@ -0,0 +1,202 @@ +From prvs=378230090=farbere@amazon.com Fri Oct 17 11:11:40 2025 +From: Eliav Farber +Date: Fri, 17 Oct 2025 09:05:11 +0000 +Subject: minmax: improve macro expansion and type checking +To: , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , +Cc: Linus Torvalds , Arnd Bergmann , David Laight , Lorenzo Stoakes +Message-ID: <20251017090519.46992-20-farbere@amazon.com> + +From: Linus Torvalds + +[ Upstream commit 22f5468731491e53356ba7c028f0fdea20b18e2c ] + +This clarifies the rules for min()/max()/clamp() type checking and makes +them a much more efficient macro expansion. + +In particular, we now look at the type and range of the inputs to see +whether they work together, generating a mask of acceptable comparisons, +and then just verifying that the inputs have a shared case: + + - an expression with a signed type can be used for + (1) signed comparisons + (2) unsigned comparisons if it is statically known to have a + non-negative value + + - an expression with an unsigned type can be used for + (3) unsigned comparison + (4) signed comparisons if the type is smaller than 'int' and thus + the C integer promotion rules will make it signed anyway + +Here rule (1) and (3) are obvious, and rule (2) is important in order to +allow obvious trivial constants to be used together with unsigned +values. + +Rule (4) is not necessarily a good idea, but matches what we used to do, +and we have extant cases of this situation in the kernel. Notably with +bcachefs having an expression like + + min(bch2_bucket_sectors_dirty(a), ca->mi.bucket_size) + +where bch2_bucket_sectors_dirty() returns an 's64', and +'ca->mi.bucket_size' is of type 'u16'. + +Technically that bcachefs comparison is clearly sensible on a C type +level, because the 'u16' will go through the normal C integer promotion, +and become 'int', and then we're comparing two signed values and +everything looks sane. + +However, it's not entirely clear that a 'min(s64,u16)' operation makes a +lot of conceptual sense, and it's possible that we will remove rule (4). +After all, the _reason_ we have these complicated type checks is exactly +that the C type promotion rules are not very intuitive. + +But at least for now the rule is in place for backwards compatibility. + +Also note that rule (2) existed before, but is hugely relaxed by this +commit. It used to be true only for the simplest compile-time +non-negative integer constants. The new macro model will allow cases +where the compiler can trivially see that an expression is non-negative +even if it isn't necessarily a constant. + +For example, the amdgpu driver does + + min_t(size_t, sizeof(fru_info->serial), pia[addr] & 0x3F)); + +because our old 'min()' macro would see that 'pia[addr] & 0x3F' is of +type 'int' and clearly not a C constant expression, so doing a 'min()' +with a 'size_t' is a signedness violation. + +Our new 'min()' macro still sees that 'pia[addr] & 0x3F' is of type +'int', but is smart enough to also see that it is clearly non-negative, +and thus would allow that case without any complaints. + +Cc: Arnd Bergmann +Cc: David Laight +Cc: Lorenzo Stoakes +Signed-off-by: Linus Torvalds +Signed-off-by: Eliav Farber +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/compiler.h | 9 +++++ + include/linux/minmax.h | 78 ++++++++++++++++++++++++++++++++++++----------- + 2 files changed, 70 insertions(+), 17 deletions(-) + +--- a/include/linux/compiler.h ++++ b/include/linux/compiler.h +@@ -252,6 +252,15 @@ static inline void *offset_to_ptr(const + #define is_signed_type(type) (((type)(-1)) < (__force type)1) + + /* ++ * Useful shorthand for "is this condition known at compile-time?" ++ * ++ * Note that the condition may involve non-constant values, ++ * but the compiler may know enough about the details of the ++ * values to determine that the condition is statically true. ++ */ ++#define statically_true(x) (__builtin_constant_p(x) && (x)) ++ ++/* + * This is needed in functions which generate the stack canary, see + * arch/x86/kernel/smpboot.c::start_secondary() for an example. + */ +--- a/include/linux/minmax.h ++++ b/include/linux/minmax.h +@@ -26,19 +26,63 @@ + #define __typecheck(x, y) \ + (!!(sizeof((typeof(x) *)1 == (typeof(y) *)1))) + +-/* 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) +- +-/* True for a non-negative signed int constant */ +-#define __is_noneg_int(x) \ +- (__builtin_choose_expr(__is_constexpr(x) && __is_signed(x), x, -1) >= 0) +- +-#define __types_ok(x, y, ux, uy) \ +- (__is_signed(ux) == __is_signed(uy) || \ +- __is_signed((ux) + 0) == __is_signed((uy) + 0) || \ +- __is_noneg_int(x) || __is_noneg_int(y)) ++/* ++ * __sign_use for integer expressions: ++ * bit #0 set if ok for unsigned comparisons ++ * bit #1 set if ok for signed comparisons ++ * ++ * In particular, statically non-negative signed integer ++ * expressions are ok for both. ++ * ++ * NOTE! Unsigned types smaller than 'int' are implicitly ++ * converted to 'int' in expressions, and are accepted for ++ * signed conversions for now. This is debatable. ++ * ++ * Note that 'x' is the original expression, and 'ux' is ++ * the unique variable that contains the value. ++ * ++ * We use 'ux' for pure type checking, and 'x' for when ++ * we need to look at the value (but without evaluating ++ * it for side effects! Careful to only ever evaluate it ++ * with sizeof() or __builtin_constant_p() etc). ++ * ++ * Pointers end up being checked by the normal C type ++ * rules at the actual comparison, and these expressions ++ * only need to be careful to not cause warnings for ++ * pointer use. ++ */ ++#define __signed_type_use(x,ux) (2+__is_nonneg(x,ux)) ++#define __unsigned_type_use(x,ux) (1+2*(sizeof(ux)<4)) ++#define __sign_use(x,ux) (is_signed_type(typeof(ux))? \ ++ __signed_type_use(x,ux):__unsigned_type_use(x,ux)) ++ ++/* ++ * To avoid warnings about casting pointers to integers ++ * of different sizes, we need that special sign type. ++ * ++ * On 64-bit we can just always use 'long', since any ++ * integer or pointer type can just be cast to that. ++ * ++ * This does not work for 128-bit signed integers since ++ * the cast would truncate them, but we do not use s128 ++ * types in the kernel (we do use 'u128', but they will ++ * be handled by the !is_signed_type() case). ++ * ++ * NOTE! The cast is there only to avoid any warnings ++ * from when values that aren't signed integer types. ++ */ ++#ifdef CONFIG_64BIT ++ #define __signed_type(ux) long ++#else ++ #define __signed_type(ux) typeof(__builtin_choose_expr(sizeof(ux)>4,1LL,1L)) ++#endif ++#define __is_nonneg(x,ux) statically_true((__signed_type(ux))(x)>=0) ++ ++#define __types_ok(x,y,ux,uy) \ ++ (__sign_use(x,ux) & __sign_use(y,uy)) ++ ++#define __types_ok3(x,y,z,ux,uy,uz) \ ++ (__sign_use(x,ux) & __sign_use(y,uy) & __sign_use(z,uz)) + + #define __cmp_op_min < + #define __cmp_op_max > +@@ -53,8 +97,8 @@ + + #define __careful_cmp_once(op, x, y, ux, uy) ({ \ + __auto_type ux = (x); __auto_type uy = (y); \ +- static_assert(__types_ok(x, y, ux, uy), \ +- #op "(" #x ", " #y ") signedness error, fix types or consider u" #op "() before " #op "_t()"); \ ++ BUILD_BUG_ON_MSG(!__types_ok(x,y,ux,uy), \ ++ #op"("#x", "#y") signedness error"); \ + __cmp(op, ux, uy); }) + + #define __careful_cmp(op, x, y) \ +@@ -70,8 +114,8 @@ + static_assert(__builtin_choose_expr(__is_constexpr((lo) > (hi)), \ + (lo) <= (hi), true), \ + "clamp() low limit " #lo " greater than high limit " #hi); \ +- static_assert(__types_ok(uval, lo, uval, ulo), "clamp() 'lo' signedness error"); \ +- static_assert(__types_ok(uval, hi, uval, uhi), "clamp() 'hi' signedness error"); \ ++ BUILD_BUG_ON_MSG(!__types_ok3(val,lo,hi,uval,ulo,uhi), \ ++ "clamp("#val", "#lo", "#hi") signedness error"); \ + __clamp(uval, ulo, uhi); }) + + #define __careful_clamp(val, lo, hi) \ diff --git a/queue-5.10/minmax-introduce-min-max-_array.patch b/queue-5.10/minmax-introduce-min-max-_array.patch new file mode 100644 index 0000000000..89d0019de7 --- /dev/null +++ b/queue-5.10/minmax-introduce-min-max-_array.patch @@ -0,0 +1,99 @@ +From prvs=378230090=farbere@amazon.com Fri Oct 17 11:07:34 2025 +From: Eliav Farber +Date: Fri, 17 Oct 2025 09:04:58 +0000 +Subject: minmax: Introduce {min,max}_array() +To: , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , +Cc: Andy Shevchenko , Christophe Leroy +Message-ID: <20251017090519.46992-7-farbere@amazon.com> + +From: Herve Codina + +[ Upstream commit c952c748c7a983a8bda9112984e6f2c1f6e441a5 ] + +Introduce min_array() (resp max_array()) in order to get the +minimal (resp maximum) of values present in an array. + +Signed-off-by: Herve Codina +Reviewed-by: Andy Shevchenko +Reviewed-by: Christophe Leroy +Link: https://lore.kernel.org/r/20230623085830.749991-8-herve.codina@bootlin.com +Signed-off-by: Mark Brown +Signed-off-by: Eliav Farber +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/minmax.h | 64 +++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 64 insertions(+) + +--- a/include/linux/minmax.h ++++ b/include/linux/minmax.h +@@ -151,6 +151,70 @@ + */ + #define max_t(type, x, y) __careful_cmp((type)(x), (type)(y), >) + ++/* ++ * Remove a const qualifier from integer types ++ * _Generic(foo, type-name: association, ..., default: association) performs a ++ * comparison against the foo type (not the qualified type). ++ * Do not use the const keyword in the type-name as it will not match the ++ * unqualified type of foo. ++ */ ++#define __unconst_integer_type_cases(type) \ ++ unsigned type: (unsigned type)0, \ ++ signed type: (signed type)0 ++ ++#define __unconst_integer_typeof(x) typeof( \ ++ _Generic((x), \ ++ char: (char)0, \ ++ __unconst_integer_type_cases(char), \ ++ __unconst_integer_type_cases(short), \ ++ __unconst_integer_type_cases(int), \ ++ __unconst_integer_type_cases(long), \ ++ __unconst_integer_type_cases(long long), \ ++ default: (x))) ++ ++/* ++ * Do not check the array parameter using __must_be_array(). ++ * In the following legit use-case where the "array" passed is a simple pointer, ++ * __must_be_array() will return a failure. ++ * --- 8< --- ++ * int *buff ++ * ... ++ * min = min_array(buff, nb_items); ++ * --- 8< --- ++ * ++ * The first typeof(&(array)[0]) is needed in order to support arrays of both ++ * 'int *buff' and 'int buff[N]' types. ++ * ++ * The array can be an array of const items. ++ * typeof() keeps the const qualifier. Use __unconst_integer_typeof() in order ++ * to discard the const qualifier for the __element variable. ++ */ ++#define __minmax_array(op, array, len) ({ \ ++ typeof(&(array)[0]) __array = (array); \ ++ typeof(len) __len = (len); \ ++ __unconst_integer_typeof(__array[0]) __element = __array[--__len]; \ ++ while (__len--) \ ++ __element = op(__element, __array[__len]); \ ++ __element; }) ++ ++/** ++ * min_array - return minimum of values present in an array ++ * @array: array ++ * @len: array length ++ * ++ * Note that @len must not be zero (empty array). ++ */ ++#define min_array(array, len) __minmax_array(min, array, len) ++ ++/** ++ * max_array - return maximum of values present in an array ++ * @array: array ++ * @len: array length ++ * ++ * Note that @len must not be zero (empty array). ++ */ ++#define max_array(array, len) __minmax_array(max, array, len) ++ + /** + * clamp_t - return a value clamped to a given range using a given type + * @type: the type of variable to use diff --git a/queue-5.10/minmax-make-generic-min-and-max-macros-available-everywhere.patch b/queue-5.10/minmax-make-generic-min-and-max-macros-available-everywhere.patch new file mode 100644 index 0000000000..483e076d1a --- /dev/null +++ b/queue-5.10/minmax-make-generic-min-and-max-macros-available-everywhere.patch @@ -0,0 +1,342 @@ +From prvs=378230090=farbere@amazon.com Fri Oct 17 11:10:56 2025 +From: Eliav Farber +Date: Fri, 17 Oct 2025 09:05:08 +0000 +Subject: minmax: make generic MIN() and MAX() macros available everywhere +To: , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , +Cc: Linus Torvalds , David Laight , Lorenzo Stoakes +Message-ID: <20251017090519.46992-17-farbere@amazon.com> + +From: Linus Torvalds + +[ Upstream commit 1a251f52cfdc417c84411a056bc142cbd77baef4 ] + +This just standardizes the use of MIN() and MAX() macros, with the very +traditional semantics. The goal is to use these for C constant +expressions and for top-level / static initializers, and so be able to +simplify the min()/max() macros. + +These macro names were used by various kernel code - they are very +traditional, after all - and all such users have been fixed up, with a +few different approaches: + + - trivial duplicated macro definitions have been removed + + Note that 'trivial' here means that it's obviously kernel code that + already included all the major kernel headers, and thus gets the new + generic MIN/MAX macros automatically. + + - non-trivial duplicated macro definitions are guarded with #ifndef + + This is the "yes, they define their own versions, but no, the include + situation is not entirely obvious, and maybe they don't get the + generic version automatically" case. + + - strange use case #1 + + A couple of drivers decided that the way they want to describe their + versioning is with + + #define MAJ 1 + #define MIN 2 + #define DRV_VERSION __stringify(MAJ) "." __stringify(MIN) + + which adds zero value and I just did my Alexander the Great + impersonation, and rewrote that pointless Gordian knot as + + #define DRV_VERSION "1.2" + + instead. + + - strange use case #2 + + A couple of drivers thought that it's a good idea to have a random + 'MIN' or 'MAX' define for a value or index into a table, rather than + the traditional macro that takes arguments. + + These values were re-written as C enum's instead. The new + function-line macros only expand when followed by an open + parenthesis, and thus don't clash with enum use. + +Happily, there weren't really all that many of these cases, and a lot of +users already had the pattern of using '#ifndef' guarding (or in one +case just using '#undef MIN') before defining their own private version +that does the same thing. I left such cases alone. + +Cc: David Laight +Cc: Lorenzo Stoakes +Signed-off-by: Linus Torvalds +Signed-off-by: Eliav Farber +Signed-off-by: Greg Kroah-Hartman +--- + arch/um/drivers/mconsole_user.c | 2 + drivers/edac/skx_common.h | 1 + drivers/gpu/drm/amd/display/modules/hdcp/hdcp_ddc.c | 2 + drivers/gpu/drm/amd/pm/powerplay/hwmgr/ppevvmath.h | 14 ++++- + drivers/gpu/drm/radeon/evergreen_cs.c | 2 + drivers/hwmon/adt7475.c | 24 +++++----- + drivers/media/dvb-frontends/stv0367_priv.h | 3 + + drivers/net/fjes/fjes_main.c | 4 - + drivers/nfc/pn544/i2c.c | 2 + drivers/platform/x86/sony-laptop.c | 1 + drivers/scsi/isci/init.c | 6 -- + drivers/staging/media/atomisp/pci/hive_isp_css_include/math_support.h | 5 -- + include/linux/minmax.h | 2 + kernel/trace/preemptirq_delay_test.c | 2 + lib/btree.c | 1 + lib/decompress_unlzma.c | 2 + lib/zstd/zstd_internal.h | 2 + mm/zsmalloc.c | 1 + 18 files changed, 37 insertions(+), 39 deletions(-) + +--- a/arch/um/drivers/mconsole_user.c ++++ b/arch/um/drivers/mconsole_user.c +@@ -71,7 +71,9 @@ static struct mconsole_command *mconsole + return NULL; + } + ++#ifndef MIN + #define MIN(a,b) ((a)<(b) ? (a):(b)) ++#endif + + #define STRINGX(x) #x + #define STRING(x) STRINGX(x) +--- a/drivers/edac/skx_common.h ++++ b/drivers/edac/skx_common.h +@@ -36,7 +36,6 @@ + #define I10NM_NUM_CHANNELS 2 + #define I10NM_NUM_DIMMS 2 + +-#define MAX(a, b) ((a) > (b) ? (a) : (b)) + #define NUM_IMC MAX(SKX_NUM_IMC, I10NM_NUM_IMC) + #define NUM_CHANNELS MAX(SKX_NUM_CHANNELS, I10NM_NUM_CHANNELS) + #define NUM_DIMMS MAX(SKX_NUM_DIMMS, I10NM_NUM_DIMMS) +--- a/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_ddc.c ++++ b/drivers/gpu/drm/amd/display/modules/hdcp/hdcp_ddc.c +@@ -25,7 +25,9 @@ + + #include "hdcp.h" + ++#ifndef MIN + #define MIN(a, b) ((a) < (b) ? (a) : (b)) ++#endif + #define HDCP_I2C_ADDR 0x3a /* 0x74 >> 1*/ + #define KSV_READ_SIZE 0xf /* 0x6803b - 0x6802c */ + #define HDCP_MAX_AUX_TRANSACTION_SIZE 16 +--- a/drivers/gpu/drm/amd/pm/powerplay/hwmgr/ppevvmath.h ++++ b/drivers/gpu/drm/amd/pm/powerplay/hwmgr/ppevvmath.h +@@ -22,12 +22,18 @@ + */ + #include + +-#define SHIFT_AMOUNT 16 /* We multiply all original integers with 2^SHIFT_AMOUNT to get the fInt representation */ ++enum ppevvmath_constants { ++ /* We multiply all original integers with 2^SHIFT_AMOUNT to get the fInt representation */ ++ SHIFT_AMOUNT = 16, + +-#define PRECISION 5 /* Change this value to change the number of decimal places in the final output - 5 is a good default */ ++ /* Change this value to change the number of decimal places in the final output - 5 is a good default */ ++ PRECISION = 5, + +-#define SHIFTED_2 (2 << SHIFT_AMOUNT) +-#define MAX (1 << (SHIFT_AMOUNT - 1)) - 1 /* 32767 - Might change in the future */ ++ SHIFTED_2 = (2 << SHIFT_AMOUNT), ++ ++ /* 32767 - Might change in the future */ ++ MAX = (1 << (SHIFT_AMOUNT - 1)) - 1, ++}; + + /* ------------------------------------------------------------------------------- + * NEW TYPE - fINT +--- a/drivers/gpu/drm/radeon/evergreen_cs.c ++++ b/drivers/gpu/drm/radeon/evergreen_cs.c +@@ -32,8 +32,10 @@ + #include "evergreen_reg_safe.h" + #include "cayman_reg_safe.h" + ++#ifndef MIN + #define MAX(a,b) (((a)>(b))?(a):(b)) + #define MIN(a,b) (((a)<(b))?(a):(b)) ++#endif + + #define REG_SAFE_BM_SIZE ARRAY_SIZE(evergreen_reg_safe_bm) + +--- a/drivers/hwmon/adt7475.c ++++ b/drivers/hwmon/adt7475.c +@@ -23,23 +23,23 @@ + #include + + /* Indexes for the sysfs hooks */ +- +-#define INPUT 0 +-#define MIN 1 +-#define MAX 2 +-#define CONTROL 3 +-#define OFFSET 3 +-#define AUTOMIN 4 +-#define THERM 5 +-#define HYSTERSIS 6 +- ++enum adt_sysfs_id { ++ INPUT = 0, ++ MIN = 1, ++ MAX = 2, ++ CONTROL = 3, ++ OFFSET = 3, // Dup ++ AUTOMIN = 4, ++ THERM = 5, ++ HYSTERSIS = 6, + /* + * These are unique identifiers for the sysfs functions - unlike the + * numbers above, these are not also indexes into an array + */ ++ ALARM = 9, ++ FAULT = 10, ++}; + +-#define ALARM 9 +-#define FAULT 10 + + /* 7475 Common Registers */ + +--- a/drivers/media/dvb-frontends/stv0367_priv.h ++++ b/drivers/media/dvb-frontends/stv0367_priv.h +@@ -25,8 +25,11 @@ + #endif + + /* MACRO definitions */ ++#ifndef MIN + #define MAX(X, Y) ((X) >= (Y) ? (X) : (Y)) + #define MIN(X, Y) ((X) <= (Y) ? (X) : (Y)) ++#endif ++ + #define INRANGE(X, Y, Z) \ + ((((X) <= (Y)) && ((Y) <= (Z))) || \ + (((Z) <= (Y)) && ((Y) <= (X))) ? 1 : 0) +--- a/drivers/net/fjes/fjes_main.c ++++ b/drivers/net/fjes/fjes_main.c +@@ -14,9 +14,7 @@ + #include "fjes.h" + #include "fjes_trace.h" + +-#define MAJ 1 +-#define MIN 2 +-#define DRV_VERSION __stringify(MAJ) "." __stringify(MIN) ++#define DRV_VERSION "1.2" + #define DRV_NAME "fjes" + char fjes_driver_name[] = DRV_NAME; + char fjes_driver_version[] = DRV_VERSION; +--- a/drivers/nfc/pn544/i2c.c ++++ b/drivers/nfc/pn544/i2c.c +@@ -126,8 +126,6 @@ struct pn544_i2c_fw_secure_blob { + #define PN544_FW_CMD_RESULT_COMMAND_REJECTED 0xE0 + #define PN544_FW_CMD_RESULT_CHUNK_ERROR 0xE6 + +-#define MIN(X, Y) ((X) < (Y) ? (X) : (Y)) +- + #define PN544_FW_WRITE_BUFFER_MAX_LEN 0x9f7 + #define PN544_FW_I2C_MAX_PAYLOAD PN544_HCI_I2C_LLC_MAX_SIZE + #define PN544_FW_I2C_WRITE_FRAME_HEADER_LEN 8 +--- a/drivers/platform/x86/sony-laptop.c ++++ b/drivers/platform/x86/sony-laptop.c +@@ -757,7 +757,6 @@ static union acpi_object *__call_snc_met + return result; + } + +-#define MIN(a, b) (a > b ? b : a) + static int sony_nc_buffer_call(acpi_handle handle, char *name, u64 *value, + void *buffer, size_t buflen) + { +--- a/drivers/scsi/isci/init.c ++++ b/drivers/scsi/isci/init.c +@@ -65,11 +65,7 @@ + #include "task.h" + #include "probe_roms.h" + +-#define MAJ 1 +-#define MIN 2 +-#define BUILD 0 +-#define DRV_VERSION __stringify(MAJ) "." __stringify(MIN) "." \ +- __stringify(BUILD) ++#define DRV_VERSION "1.2.0" + + MODULE_VERSION(DRV_VERSION); + +--- a/drivers/staging/media/atomisp/pci/hive_isp_css_include/math_support.h ++++ b/drivers/staging/media/atomisp/pci/hive_isp_css_include/math_support.h +@@ -31,11 +31,6 @@ + /* A => B */ + #define IMPLIES(a, b) (!(a) || (b)) + +-/* for preprocessor and array sizing use MIN and MAX +- otherwise use min and max */ +-#define MAX(a, b) (((a) > (b)) ? (a) : (b)) +-#define MIN(a, b) (((a) < (b)) ? (a) : (b)) +- + #define ROUND_DIV(a, b) (((b) != 0) ? ((a) + ((b) >> 1)) / (b) : 0) + #define CEIL_DIV(a, b) (((b) != 0) ? ((a) + (b) - 1) / (b) : 0) + #define CEIL_MUL(a, b) (CEIL_DIV(a, b) * (b)) +--- a/include/linux/minmax.h ++++ b/include/linux/minmax.h +@@ -277,6 +277,8 @@ static inline bool in_range32(u32 val, u + * Use these carefully: no type checking, and uses the arguments + * multiple times. Use for obvious constants only. + */ ++#define MIN(a,b) __cmp(min,a,b) ++#define MAX(a,b) __cmp(max,a,b) + #define MIN_T(type,a,b) __cmp(min,(type)(a),(type)(b)) + #define MAX_T(type,a,b) __cmp(max,(type)(a),(type)(b)) + +--- a/kernel/trace/preemptirq_delay_test.c ++++ b/kernel/trace/preemptirq_delay_test.c +@@ -31,8 +31,6 @@ MODULE_PARM_DESC(burst_size, "The size o + + static struct completion done; + +-#define MIN(x, y) ((x) < (y) ? (x) : (y)) +- + static void busy_wait(ulong time) + { + u64 start, end; +--- a/lib/btree.c ++++ b/lib/btree.c +@@ -43,7 +43,6 @@ + #include + #include + +-#define MAX(a, b) ((a) > (b) ? (a) : (b)) + #define NODESIZE MAX(L1_CACHE_BYTES, 128) + + struct btree_geo { +--- a/lib/decompress_unlzma.c ++++ b/lib/decompress_unlzma.c +@@ -37,7 +37,9 @@ + + #include + ++#ifndef MIN + #define MIN(a, b) (((a) < (b)) ? (a) : (b)) ++#endif + + static long long INIT read_int(unsigned char *ptr, int size) + { +--- a/lib/zstd/zstd_internal.h ++++ b/lib/zstd/zstd_internal.h +@@ -36,8 +36,6 @@ + /*-************************************* + * shared macros + ***************************************/ +-#define MIN(a, b) ((a) < (b) ? (a) : (b)) +-#define MAX(a, b) ((a) > (b) ? (a) : (b)) + #define CHECK_F(f) \ + { \ + size_t const errcod = f; \ +--- a/mm/zsmalloc.c ++++ b/mm/zsmalloc.c +@@ -126,7 +126,6 @@ + #define ISOLATED_BITS 3 + #define MAGIC_VAL_BITS 8 + +-#define MAX(a, b) ((a) >= (b) ? (a) : (b)) + /* ZS_MIN_ALLOC_SIZE must be multiple of ZS_ALIGN */ + #define ZS_MIN_ALLOC_SIZE \ + MAX(32, (ZS_MAX_PAGES_PER_ZSPAGE << PAGE_SHIFT >> OBJ_INDEX_BITS)) diff --git a/queue-5.10/minmax-relax-check-to-allow-comparison-between-unsigned-arguments-and-signed-constants.patch b/queue-5.10/minmax-relax-check-to-allow-comparison-between-unsigned-arguments-and-signed-constants.patch new file mode 100644 index 0000000000..5989539216 --- /dev/null +++ b/queue-5.10/minmax-relax-check-to-allow-comparison-between-unsigned-arguments-and-signed-constants.patch @@ -0,0 +1,76 @@ +From prvs=378230090=farbere@amazon.com Fri Oct 17 11:09:53 2025 +From: Eliav Farber +Date: Fri, 17 Oct 2025 09:05:04 +0000 +Subject: minmax: relax check to allow comparison between unsigned arguments and signed constants +To: , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , +Cc: Christoph Hellwig , Linus Torvalds +Message-ID: <20251017090519.46992-13-farbere@amazon.com> + +From: David Laight + +[ Upstream commit 867046cc7027703f60a46339ffde91a1970f2901 ] + +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.aculab.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 +Signed-off-by: Eliav Farber +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/minmax.h | 24 +++++++++++++++++------- + 1 file changed, 17 insertions(+), 7 deletions(-) + +--- a/include/linux/minmax.h ++++ b/include/linux/minmax.h +@@ -10,13 +10,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 constants. ++ * - 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 == (typeof(y) *)1))) +@@ -26,9 +31,14 @@ + __builtin_choose_expr(__is_constexpr(is_signed_type(typeof(x))), \ + is_signed_type(typeof(x)), 0) + +-#define __types_ok(x, y) \ +- (__is_signed(x) == __is_signed(y) || \ +- __is_signed((x) + 0) == __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) >= 0) ++ ++#define __types_ok(x, y) \ ++ (__is_signed(x) == __is_signed(y) || \ ++ __is_signed((x) + 0) == __is_signed((y) + 0) || \ ++ __is_noneg_int(x) || __is_noneg_int(y)) + + #define __cmp_op_min < + #define __cmp_op_max > diff --git a/queue-5.10/minmax-sanity-check-constant-bounds-when-clamping.patch b/queue-5.10/minmax-sanity-check-constant-bounds-when-clamping.patch new file mode 100644 index 0000000000..5edc727466 --- /dev/null +++ b/queue-5.10/minmax-sanity-check-constant-bounds-when-clamping.patch @@ -0,0 +1,78 @@ +From linux-staging+bounces-34941-greg=kroah.com@lists.linux.dev Fri Oct 17 11:08:22 2025 +From: Eliav Farber +Date: Fri, 17 Oct 2025 09:04:55 +0000 +Subject: minmax: sanity check constant bounds when clamping +To: , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , +Message-ID: <20251017090519.46992-4-farbere@amazon.com> + +From: "Jason A. Donenfeld" + +[ Upstream commit 5efcecd9a3b18078d3398b359a84c83f549e22cf ] + +The clamp family of functions only makes sense if hi>=lo. 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 +Signed-off-by: Eliav Farber +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/minmax.h | 26 ++++++++++++++++++++++++-- + 1 file changed, 24 insertions(+), 2 deletions(-) + +--- 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)) + ++#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 = (val); \ ++ typeof(lo) unique_lo = (lo); \ ++ typeof(hi) unique_hi = (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) + + /* + * ..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)) + + /** + * clamp_val - return a value clamped to a given range using val's type diff --git a/queue-5.10/minmax-simplify-and-clarify-min_t-max_t-implementation.patch b/queue-5.10/minmax-simplify-and-clarify-min_t-max_t-implementation.patch new file mode 100644 index 0000000000..a3cdec4454 --- /dev/null +++ b/queue-5.10/minmax-simplify-and-clarify-min_t-max_t-implementation.patch @@ -0,0 +1,76 @@ +From prvs=378230090=farbere@amazon.com Fri Oct 17 11:10:34 2025 +From: Eliav Farber +Date: Fri, 17 Oct 2025 09:05:07 +0000 +Subject: minmax: simplify and clarify min_t()/max_t() implementation +To: , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , +Cc: Linus Torvalds , David Laight , Lorenzo Stoakes +Message-ID: <20251017090519.46992-16-farbere@amazon.com> + +From: Linus Torvalds + +[ Upstream commit 017fa3e89187848fd056af757769c9e66ac3e93d ] + +This simplifies the min_t() and max_t() macros by no longer making them +work in the context of a C constant expression. + +That means that you can no longer use them for static initializers or +for array sizes in type definitions, but there were only a couple of +such uses, and all of them were converted (famous last words) to use +MIN_T/MAX_T instead. + +Cc: David Laight +Cc: Lorenzo Stoakes +Signed-off-by: Linus Torvalds +Signed-off-by: Eliav Farber +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/minmax.h | 19 +++++++++++-------- + 1 file changed, 11 insertions(+), 8 deletions(-) + +--- a/include/linux/minmax.h ++++ b/include/linux/minmax.h +@@ -45,17 +45,20 @@ + + #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 = (x); \ +- typeof(y) unique_y = (y); \ ++#define __cmp_once_unique(op, type, x, y, ux, uy) \ ++ ({ type ux = (x); type uy = (y); __cmp(op, ux, uy); }) ++ ++#define __cmp_once(op, type, x, y) \ ++ __cmp_once_unique(op, type, x, y, __UNIQUE_ID(x_), __UNIQUE_ID(y_)) ++ ++#define __careful_cmp_once(op, x, y) ({ \ + 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); }) ++ __cmp_once(op, __auto_type, x, y); }) + + #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))) ++ __cmp(op, x, y), __careful_cmp_once(op, x, y)) + + #define __clamp(val, lo, hi) \ + ((val) >= (hi) ? (hi) : ((val) <= (lo) ? (lo) : (val))) +@@ -158,7 +161,7 @@ + * @x: first value + * @y: second value + */ +-#define min_t(type, x, y) __careful_cmp(min, (type)(x), (type)(y)) ++#define min_t(type, x, y) __cmp_once(min, type, x, y) + + /** + * max_t - return maximum of two values, using the specified type +@@ -166,7 +169,7 @@ + * @x: first value + * @y: second value + */ +-#define max_t(type, x, y) __careful_cmp(max, (type)(x), (type)(y)) ++#define max_t(type, x, y) __cmp_once(max, type, x, y) + + /* + * Do not check the array parameter using __must_be_array(). diff --git a/queue-5.10/minmax-simplify-min-max-clamp-implementation.patch b/queue-5.10/minmax-simplify-min-max-clamp-implementation.patch new file mode 100644 index 0000000000..c37b0f99bb --- /dev/null +++ b/queue-5.10/minmax-simplify-min-max-clamp-implementation.patch @@ -0,0 +1,140 @@ +From prvs=378230090=farbere@amazon.com Fri Oct 17 11:11:23 2025 +From: Eliav Farber +Date: Fri, 17 Oct 2025 09:05:10 +0000 +Subject: minmax: simplify min()/max()/clamp() implementation +To: , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , +Cc: Linus Torvalds , David Laight , Lorenzo Stoakes +Message-ID: <20251017090519.46992-19-farbere@amazon.com> + +From: Linus Torvalds + +[ Upstream commit dc1c8034e31b14a2e5e212104ec508aec44ce1b9 ] + +Now that we no longer have any C constant expression contexts (ie array +size declarations or static initializers) that use min() or max(), we +can simpify the implementation by not having to worry about the result +staying as a C constant expression. + +So now we can unconditionally just use temporary variables of the right +type, and get rid of the excessive expansion that used to come from the +use of + + __builtin_choose_expr(__is_constexpr(...), .. + +to pick the specialized code for constant expressions. + +Another expansion simplification is to pass the temporary variables (in +addition to the original expression) to our __types_ok() macro. That +may superficially look like it complicates the macro, but when we only +want the type of the expression, expanding the temporary variable names +is much simpler and smaller than expanding the potentially complicated +original expression. + +As a result, on my machine, doing a + + $ time make drivers/staging/media/atomisp/pci/isp/kernels/ynr/ynr_1.0/ia_css_ynr.host.i + +goes from + + real 0m16.621s + user 0m15.360s + sys 0m1.221s + +to + + real 0m2.532s + user 0m2.091s + sys 0m0.452s + +because the token expansion goes down dramatically. + +In particular, the longest line expansion (which was line 71 of that +'ia_css_ynr.host.c' file) shrinks from 23,338kB (yes, 23MB for one +single line) to "just" 1,444kB (now "only" 1.4MB). + +And yes, that line is still the line from hell, because it's doing +multiple levels of "min()/max()" expansion thanks to some of them being +hidden inside the uDIGIT_FITTING() macro. + +Lorenzo has a nice cleanup patch that makes that driver use inline +functions instead of macros for sDIGIT_FITTING() and uDIGIT_FITTING(), +which will fix that line once and for all, but the 16-fold reduction in +this case does show why we need to simplify these helpers. + +Cc: David Laight +Cc: Lorenzo Stoakes +Signed-off-by: Linus Torvalds +Signed-off-by: Eliav Farber +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/minmax.h | 43 ++++++++++++++++++++----------------------- + 1 file changed, 20 insertions(+), 23 deletions(-) + +--- a/include/linux/minmax.h ++++ b/include/linux/minmax.h +@@ -35,10 +35,10 @@ + #define __is_noneg_int(x) \ + (__builtin_choose_expr(__is_constexpr(x) && __is_signed(x), x, -1) >= 0) + +-#define __types_ok(x, y) \ +- (__is_signed(x) == __is_signed(y) || \ +- __is_signed((x) + 0) == __is_signed((y) + 0) || \ +- __is_noneg_int(x) || __is_noneg_int(y)) ++#define __types_ok(x, y, ux, uy) \ ++ (__is_signed(ux) == __is_signed(uy) || \ ++ __is_signed((ux) + 0) == __is_signed((uy) + 0) || \ ++ __is_noneg_int(x) || __is_noneg_int(y)) + + #define __cmp_op_min < + #define __cmp_op_max > +@@ -51,34 +51,31 @@ + #define __cmp_once(op, type, x, y) \ + __cmp_once_unique(op, type, x, y, __UNIQUE_ID(x_), __UNIQUE_ID(y_)) + +-#define __careful_cmp_once(op, x, y) ({ \ +- static_assert(__types_ok(x, y), \ ++#define __careful_cmp_once(op, x, y, ux, uy) ({ \ ++ __auto_type ux = (x); __auto_type uy = (y); \ ++ static_assert(__types_ok(x, y, ux, uy), \ + #op "(" #x ", " #y ") signedness error, fix types or consider u" #op "() before " #op "_t()"); \ +- __cmp_once(op, __auto_type, x, y); }) ++ __cmp(op, ux, uy); }) + +-#define __careful_cmp(op, x, y) \ +- __builtin_choose_expr(__is_constexpr((x) - (y)), \ +- __cmp(op, x, y), __careful_cmp_once(op, x, y)) ++#define __careful_cmp(op, x, y) \ ++ __careful_cmp_once(op, x, y, __UNIQUE_ID(x_), __UNIQUE_ID(y_)) + + #define __clamp(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); \ +- typeof(lo) unique_lo = (lo); \ +- typeof(hi) unique_hi = (hi); \ ++#define __clamp_once(val, lo, hi, uval, ulo, uhi) ({ \ ++ __auto_type uval = (val); \ ++ __auto_type ulo = (lo); \ ++ __auto_type uhi = (hi); \ + static_assert(__builtin_choose_expr(__is_constexpr((lo) > (hi)), \ + (lo) <= (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); }) +- +-#define __careful_clamp(val, lo, 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))); }) ++ static_assert(__types_ok(uval, lo, uval, ulo), "clamp() 'lo' signedness error"); \ ++ static_assert(__types_ok(uval, hi, uval, uhi), "clamp() 'hi' signedness error"); \ ++ __clamp(uval, ulo, uhi); }) ++ ++#define __careful_clamp(val, lo, hi) \ ++ __clamp_once(val, lo, hi, __UNIQUE_ID(v_), __UNIQUE_ID(l_), __UNIQUE_ID(h_)) + + /** + * min - return minimum of two values of the same or compatible types diff --git a/queue-5.10/minmax.h-add-whitespace-around-operators-and-after-commas.patch b/queue-5.10/minmax.h-add-whitespace-around-operators-and-after-commas.patch new file mode 100644 index 0000000000..57f74ff1e7 --- /dev/null +++ b/queue-5.10/minmax.h-add-whitespace-around-operators-and-after-commas.patch @@ -0,0 +1,118 @@ +From prvs=378230090=farbere@amazon.com Fri Oct 17 11:12:16 2025 +From: Eliav Farber +Date: Fri, 17 Oct 2025 09:05:13 +0000 +Subject: minmax.h: add whitespace around operators and after commas +To: , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , +Cc: Arnd Bergmann , Christoph Hellwig , Dan Carpenter , Jens Axboe , Lorenzo Stoakes , Mateusz Guzik , Pedro Falcato +Message-ID: <20251017090519.46992-22-farbere@amazon.com> + +From: David Laight + +[ Upstream commit 71ee9b16251ea4bf7c1fe222517c82bdb3220acc ] + +Patch series "minmax.h: Cleanups and minor optimisations". + +Some tidyups and minor changes to minmax.h. + +This patch (of 7): + +Link: https://lkml.kernel.org/r/c50365d214e04f9ba256d417c8bebbc0@AcuMS.aculab.com +Link: https://lkml.kernel.org/r/f04b2e1310244f62826267346fde0553@AcuMS.aculab.com +Signed-off-by: David Laight +Cc: Andy Shevchenko +Cc: Arnd Bergmann +Cc: Christoph Hellwig +Cc: Dan Carpenter +Cc: Jason A. Donenfeld +Cc: Jens Axboe +Cc: Lorenzo Stoakes +Cc: Mateusz Guzik +Cc: Matthew Wilcox +Cc: Pedro Falcato +Signed-off-by: Andrew Morton +Signed-off-by: Eliav Farber +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/minmax.h | 34 +++++++++++++++++----------------- + 1 file changed, 17 insertions(+), 17 deletions(-) + +--- a/include/linux/minmax.h ++++ b/include/linux/minmax.h +@@ -51,10 +51,10 @@ + * only need to be careful to not cause warnings for + * pointer use. + */ +-#define __signed_type_use(x,ux) (2+__is_nonneg(x,ux)) +-#define __unsigned_type_use(x,ux) (1+2*(sizeof(ux)<4)) +-#define __sign_use(x,ux) (is_signed_type(typeof(ux))? \ +- __signed_type_use(x,ux):__unsigned_type_use(x,ux)) ++#define __signed_type_use(x, ux) (2 + __is_nonneg(x, ux)) ++#define __unsigned_type_use(x, ux) (1 + 2 * (sizeof(ux) < 4)) ++#define __sign_use(x, ux) (is_signed_type(typeof(ux)) ? \ ++ __signed_type_use(x, ux) : __unsigned_type_use(x, ux)) + + /* + * To avoid warnings about casting pointers to integers +@@ -74,15 +74,15 @@ + #ifdef CONFIG_64BIT + #define __signed_type(ux) long + #else +- #define __signed_type(ux) typeof(__builtin_choose_expr(sizeof(ux)>4,1LL,1L)) ++ #define __signed_type(ux) typeof(__builtin_choose_expr(sizeof(ux) > 4, 1LL, 1L)) + #endif +-#define __is_nonneg(x,ux) statically_true((__signed_type(ux))(x)>=0) ++#define __is_nonneg(x, ux) statically_true((__signed_type(ux))(x) >= 0) + +-#define __types_ok(x,y,ux,uy) \ +- (__sign_use(x,ux) & __sign_use(y,uy)) ++#define __types_ok(x, y, ux, uy) \ ++ (__sign_use(x, ux) & __sign_use(y, uy)) + +-#define __types_ok3(x,y,z,ux,uy,uz) \ +- (__sign_use(x,ux) & __sign_use(y,uy) & __sign_use(z,uz)) ++#define __types_ok3(x, y, z, ux, uy, uz) \ ++ (__sign_use(x, ux) & __sign_use(y, uy) & __sign_use(z, uz)) + + #define __cmp_op_min < + #define __cmp_op_max > +@@ -97,7 +97,7 @@ + + #define __careful_cmp_once(op, x, y, ux, uy) ({ \ + __auto_type ux = (x); __auto_type uy = (y); \ +- BUILD_BUG_ON_MSG(!__types_ok(x,y,ux,uy), \ ++ BUILD_BUG_ON_MSG(!__types_ok(x, y, ux, uy), \ + #op"("#x", "#y") signedness error"); \ + __cmp(op, ux, uy); }) + +@@ -114,7 +114,7 @@ + static_assert(__builtin_choose_expr(__is_constexpr((lo) > (hi)), \ + (lo) <= (hi), true), \ + "clamp() low limit " #lo " greater than high limit " #hi); \ +- BUILD_BUG_ON_MSG(!__types_ok3(val,lo,hi,uval,ulo,uhi), \ ++ BUILD_BUG_ON_MSG(!__types_ok3(val, lo, hi, uval, ulo, uhi), \ + "clamp("#val", "#lo", "#hi") signedness error"); \ + __clamp(uval, ulo, uhi); }) + +@@ -154,7 +154,7 @@ + + #define __careful_op3(op, x, y, z, ux, uy, uz) ({ \ + __auto_type ux = (x); __auto_type uy = (y);__auto_type uz = (z);\ +- BUILD_BUG_ON_MSG(!__types_ok3(x,y,z,ux,uy,uz), \ ++ BUILD_BUG_ON_MSG(!__types_ok3(x, y, z, ux, uy, uz), \ + #op"3("#x", "#y", "#z") signedness error"); \ + __cmp(op, ux, __cmp(op, uy, uz)); }) + +@@ -326,9 +326,9 @@ static inline bool in_range32(u32 val, u + * Use these carefully: no type checking, and uses the arguments + * multiple times. Use for obvious constants only. + */ +-#define MIN(a,b) __cmp(min,a,b) +-#define MAX(a,b) __cmp(max,a,b) +-#define MIN_T(type,a,b) __cmp(min,(type)(a),(type)(b)) +-#define MAX_T(type,a,b) __cmp(max,(type)(a),(type)(b)) ++#define MIN(a, b) __cmp(min, a, b) ++#define MAX(a, b) __cmp(max, a, b) ++#define MIN_T(type, a, b) __cmp(min, (type)(a), (type)(b)) ++#define MAX_T(type, a, b) __cmp(max, (type)(a), (type)(b)) + + #endif /* _LINUX_MINMAX_H */ diff --git a/queue-5.10/minmax.h-move-all-the-clamp-definitions-after-the-min-max-ones.patch b/queue-5.10/minmax.h-move-all-the-clamp-definitions-after-the-min-max-ones.patch new file mode 100644 index 0000000000..9a700ecb11 --- /dev/null +++ b/queue-5.10/minmax.h-move-all-the-clamp-definitions-after-the-min-max-ones.patch @@ -0,0 +1,186 @@ +From prvs=378230090=farbere@amazon.com Fri Oct 17 11:13:38 2025 +From: Eliav Farber +Date: Fri, 17 Oct 2025 09:05:17 +0000 +Subject: minmax.h: move all the clamp() definitions after the min/max() ones +To: , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , +Cc: Arnd Bergmann , Christoph Hellwig , Dan Carpenter , Jens Axboe , Lorenzo Stoakes , Mateusz Guzik , Pedro Falcato +Message-ID: <20251017090519.46992-26-farbere@amazon.com> + +From: David Laight + +[ Upstream commit c3939872ee4a6b8bdcd0e813c66823b31e6e26f7 ] + +At some point the definitions for clamp() got added in the middle of the +ones for min() and max(). Re-order the definitions so they are more +sensibly grouped. + +Link: https://lkml.kernel.org/r/8bb285818e4846469121c8abc3dfb6e2@AcuMS.aculab.com +Signed-off-by: David Laight +Cc: Andy Shevchenko +Cc: Arnd Bergmann +Cc: Christoph Hellwig +Cc: Dan Carpenter +Cc: Jason A. Donenfeld +Cc: Jens Axboe +Cc: Lorenzo Stoakes +Cc: Mateusz Guzik +Cc: Matthew Wilcox +Cc: Pedro Falcato +Signed-off-by: Andrew Morton +Signed-off-by: Eliav Farber +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/minmax.h | 109 ++++++++++++++++++++++--------------------------- + 1 file changed, 51 insertions(+), 58 deletions(-) + +--- a/include/linux/minmax.h ++++ b/include/linux/minmax.h +@@ -99,22 +99,6 @@ + #define __careful_cmp(op, x, y) \ + __careful_cmp_once(op, x, y, __UNIQUE_ID(x_), __UNIQUE_ID(y_)) + +-#define __clamp(val, lo, hi) \ +- ((val) >= (hi) ? (hi) : ((val) <= (lo) ? (lo) : (val))) +- +-#define __clamp_once(val, lo, hi, uval, ulo, uhi) ({ \ +- __auto_type uval = (val); \ +- __auto_type ulo = (lo); \ +- __auto_type uhi = (hi); \ +- BUILD_BUG_ON_MSG(statically_true(ulo > uhi), \ +- "clamp() low limit " #lo " greater than high limit " #hi); \ +- BUILD_BUG_ON_MSG(!__types_ok3(uval, ulo, uhi), \ +- "clamp("#val", "#lo", "#hi") signedness error"); \ +- __clamp(uval, ulo, uhi); }) +- +-#define __careful_clamp(val, lo, hi) \ +- __clamp_once(val, lo, hi, __UNIQUE_ID(v_), __UNIQUE_ID(l_), __UNIQUE_ID(h_)) +- + /** + * min - return minimum of two values of the same or compatible types + * @x: first value +@@ -171,6 +155,22 @@ + __careful_op3(max, x, y, z, __UNIQUE_ID(x_), __UNIQUE_ID(y_), __UNIQUE_ID(z_)) + + /** ++ * min_t - return minimum of two values, using the specified type ++ * @type: data type to use ++ * @x: first value ++ * @y: second value ++ */ ++#define min_t(type, x, y) __cmp_once(min, type, x, y) ++ ++/** ++ * max_t - return maximum of two values, using the specified type ++ * @type: data type to use ++ * @x: first value ++ * @y: second value ++ */ ++#define max_t(type, x, y) __cmp_once(max, type, x, y) ++ ++/** + * min_not_zero - return the minimum that is _not_ zero, unless both are zero + * @x: value1 + * @y: value2 +@@ -180,6 +180,22 @@ + typeof(y) __y = (y); \ + __x == 0 ? __y : ((__y == 0) ? __x : min(__x, __y)); }) + ++#define __clamp(val, lo, hi) \ ++ ((val) >= (hi) ? (hi) : ((val) <= (lo) ? (lo) : (val))) ++ ++#define __clamp_once(val, lo, hi, uval, ulo, uhi) ({ \ ++ __auto_type uval = (val); \ ++ __auto_type ulo = (lo); \ ++ __auto_type uhi = (hi); \ ++ BUILD_BUG_ON_MSG(statically_true(ulo > uhi), \ ++ "clamp() low limit " #lo " greater than high limit " #hi); \ ++ BUILD_BUG_ON_MSG(!__types_ok3(uval, ulo, uhi), \ ++ "clamp("#val", "#lo", "#hi") signedness error"); \ ++ __clamp(uval, ulo, uhi); }) ++ ++#define __careful_clamp(val, lo, hi) \ ++ __clamp_once(val, lo, hi, __UNIQUE_ID(v_), __UNIQUE_ID(l_), __UNIQUE_ID(h_)) ++ + /** + * clamp - return a value clamped to a given range with strict typechecking + * @val: current value +@@ -191,28 +207,30 @@ + */ + #define clamp(val, lo, hi) __careful_clamp(val, lo, hi) + +-/* +- * ..and if you can't take the strict +- * types, you can specify one yourself. +- * +- * Or not use min/max/clamp at all, of course. +- */ +- + /** +- * min_t - return minimum of two values, using the specified type +- * @type: data type to use +- * @x: first value +- * @y: second value ++ * clamp_t - return a value clamped to a given range using a given type ++ * @type: the type of variable to use ++ * @val: current value ++ * @lo: minimum allowable value ++ * @hi: maximum allowable value ++ * ++ * This macro does no typechecking and uses temporary variables of type ++ * @type to make all the comparisons. + */ +-#define min_t(type, x, y) __cmp_once(min, type, x, y) ++#define clamp_t(type, val, lo, hi) __careful_clamp((type)(val), (type)(lo), (type)(hi)) + + /** +- * max_t - return maximum of two values, using the specified type +- * @type: data type to use +- * @x: first value +- * @y: second value ++ * clamp_val - return a value clamped to a given range using val's type ++ * @val: current value ++ * @lo: minimum allowable value ++ * @hi: maximum allowable value ++ * ++ * This macro does no typechecking and uses temporary variables of whatever ++ * type the input argument @val is. This is useful when @val is an unsigned ++ * type and @lo and @hi are literals that will otherwise be assigned a signed ++ * integer type. + */ +-#define max_t(type, x, y) __cmp_once(max, type, x, y) ++#define clamp_val(val, lo, hi) clamp_t(typeof(val), val, lo, hi) + + /* + * Do not check the array parameter using __must_be_array(). +@@ -257,31 +275,6 @@ + */ + #define max_array(array, len) __minmax_array(max, array, len) + +-/** +- * clamp_t - return a value clamped to a given range using a given type +- * @type: the type of variable to use +- * @val: current value +- * @lo: minimum allowable value +- * @hi: maximum allowable value +- * +- * This macro does no typechecking and uses temporary variables of type +- * @type to make all the comparisons. +- */ +-#define clamp_t(type, val, lo, hi) __careful_clamp((type)(val), (type)(lo), (type)(hi)) +- +-/** +- * clamp_val - return a value clamped to a given range using val's type +- * @val: current value +- * @lo: minimum allowable value +- * @hi: maximum allowable value +- * +- * This macro does no typechecking and uses temporary variables of whatever +- * type the input argument @val is. This is useful when @val is an unsigned +- * type and @lo and @hi are literals that will otherwise be assigned a signed +- * integer type. +- */ +-#define clamp_val(val, lo, hi) clamp_t(typeof(val), val, lo, hi) +- + static inline bool in_range64(u64 val, u64 start, u64 len) + { + return (val - start) < len; diff --git a/queue-5.10/minmax.h-reduce-the-define-expansion-of-min-max-and-clamp.patch b/queue-5.10/minmax.h-reduce-the-define-expansion-of-min-max-and-clamp.patch new file mode 100644 index 0000000000..9ece63f1fe --- /dev/null +++ b/queue-5.10/minmax.h-reduce-the-define-expansion-of-min-max-and-clamp.patch @@ -0,0 +1,100 @@ +From prvs=378230090=farbere@amazon.com Fri Oct 17 11:12:54 2025 +From: Eliav Farber +Date: Fri, 17 Oct 2025 09:05:15 +0000 +Subject: minmax.h: reduce the #define expansion of min(), max() and clamp() +To: , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , +Cc: Arnd Bergmann , Christoph Hellwig , Dan Carpenter , Jens Axboe , Lorenzo Stoakes , Mateusz Guzik , Pedro Falcato +Message-ID: <20251017090519.46992-24-farbere@amazon.com> + +From: David Laight + +[ Upstream commit b280bb27a9f7c91ddab730e1ad91a9c18a051f41 ] + +Since the test for signed values being non-negative only relies on +__builtion_constant_p() (not is_constexpr()) it can use the 'ux' variable +instead of the caller supplied expression. This means that the #define +parameters are only expanded twice. Once in the code and once quoted in +the error message. + +Link: https://lkml.kernel.org/r/051afc171806425da991908ed8688a98@AcuMS.aculab.com +Signed-off-by: David Laight +Cc: Andy Shevchenko +Cc: Arnd Bergmann +Cc: Christoph Hellwig +Cc: Dan Carpenter +Cc: Jason A. Donenfeld +Cc: Jens Axboe +Cc: Lorenzo Stoakes +Cc: Mateusz Guzik +Cc: Matthew Wilcox +Cc: Pedro Falcato +Signed-off-by: Andrew Morton +Signed-off-by: Eliav Farber +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/minmax.h | 24 ++++++++++++------------ + 1 file changed, 12 insertions(+), 12 deletions(-) + +--- a/include/linux/minmax.h ++++ b/include/linux/minmax.h +@@ -46,10 +46,10 @@ + * comparison, and these expressions only need to be careful to not cause + * warnings for pointer use. + */ +-#define __signed_type_use(x, ux) (2 + __is_nonneg(x, ux)) +-#define __unsigned_type_use(x, ux) (1 + 2 * (sizeof(ux) < 4)) +-#define __sign_use(x, ux) (is_signed_type(typeof(ux)) ? \ +- __signed_type_use(x, ux) : __unsigned_type_use(x, ux)) ++#define __signed_type_use(ux) (2 + __is_nonneg(ux)) ++#define __unsigned_type_use(ux) (1 + 2 * (sizeof(ux) < 4)) ++#define __sign_use(ux) (is_signed_type(typeof(ux)) ? \ ++ __signed_type_use(ux) : __unsigned_type_use(ux)) + + /* + * Check whether a signed value is always non-negative. +@@ -71,13 +71,13 @@ + #else + #define __signed_type(ux) typeof(__builtin_choose_expr(sizeof(ux) > 4, 1LL, 1L)) + #endif +-#define __is_nonneg(x, ux) statically_true((__signed_type(ux))(x) >= 0) ++#define __is_nonneg(ux) statically_true((__signed_type(ux))(ux) >= 0) + +-#define __types_ok(x, y, ux, uy) \ +- (__sign_use(x, ux) & __sign_use(y, uy)) ++#define __types_ok(ux, uy) \ ++ (__sign_use(ux) & __sign_use(uy)) + +-#define __types_ok3(x, y, z, ux, uy, uz) \ +- (__sign_use(x, ux) & __sign_use(y, uy) & __sign_use(z, uz)) ++#define __types_ok3(ux, uy, uz) \ ++ (__sign_use(ux) & __sign_use(uy) & __sign_use(uz)) + + #define __cmp_op_min < + #define __cmp_op_max > +@@ -92,7 +92,7 @@ + + #define __careful_cmp_once(op, x, y, ux, uy) ({ \ + __auto_type ux = (x); __auto_type uy = (y); \ +- BUILD_BUG_ON_MSG(!__types_ok(x, y, ux, uy), \ ++ BUILD_BUG_ON_MSG(!__types_ok(ux, uy), \ + #op"("#x", "#y") signedness error"); \ + __cmp(op, ux, uy); }) + +@@ -109,7 +109,7 @@ + static_assert(__builtin_choose_expr(__is_constexpr((lo) > (hi)), \ + (lo) <= (hi), true), \ + "clamp() low limit " #lo " greater than high limit " #hi); \ +- BUILD_BUG_ON_MSG(!__types_ok3(val, lo, hi, uval, ulo, uhi), \ ++ BUILD_BUG_ON_MSG(!__types_ok3(uval, ulo, uhi), \ + "clamp("#val", "#lo", "#hi") signedness error"); \ + __clamp(uval, ulo, uhi); }) + +@@ -149,7 +149,7 @@ + + #define __careful_op3(op, x, y, z, ux, uy, uz) ({ \ + __auto_type ux = (x); __auto_type uy = (y);__auto_type uz = (z);\ +- BUILD_BUG_ON_MSG(!__types_ok3(x, y, z, ux, uy, uz), \ ++ BUILD_BUG_ON_MSG(!__types_ok3(ux, uy, uz), \ + #op"3("#x", "#y", "#z") signedness error"); \ + __cmp(op, ux, __cmp(op, uy, uz)); }) + diff --git a/queue-5.10/minmax.h-remove-some-defines-that-are-only-expanded-once.patch b/queue-5.10/minmax.h-remove-some-defines-that-are-only-expanded-once.patch new file mode 100644 index 0000000000..5c213f721f --- /dev/null +++ b/queue-5.10/minmax.h-remove-some-defines-that-are-only-expanded-once.patch @@ -0,0 +1,82 @@ +From prvs=378230090=farbere@amazon.com Fri Oct 17 11:14:00 2025 +From: Eliav Farber +Date: Fri, 17 Oct 2025 09:05:19 +0000 +Subject: minmax.h: remove some #defines that are only expanded once +To: , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , +Cc: Arnd Bergmann , Christoph Hellwig , Dan Carpenter , Jens Axboe , Lorenzo Stoakes , Mateusz Guzik , Pedro Falcato +Message-ID: <20251017090519.46992-28-farbere@amazon.com> + +From: David Laight + +[ Upstream commit 2b97aaf74ed534fb838d09867d09a3ca5d795208 ] + +The bodies of __signed_type_use() and __unsigned_type_use() are much the +same size as their names - so put the bodies in the only line that expands +them. + +Similarly __signed_type() is defined separately for 64bit and then used +exactly once just below. + +Change the test for __signed_type from CONFIG_64BIT to one based on gcc +defined macros so that the code is valid if it gets used outside of a +kernel build. + +Link: https://lkml.kernel.org/r/9386d1ebb8974fbabbed2635160c3975@AcuMS.aculab.com +Signed-off-by: David Laight +Cc: Andy Shevchenko +Cc: Arnd Bergmann +Cc: Christoph Hellwig +Cc: Dan Carpenter +Cc: Jason A. Donenfeld +Cc: Jens Axboe +Cc: Lorenzo Stoakes +Cc: Mateusz Guzik +Cc: Matthew Wilcox +Cc: Pedro Falcato +Signed-off-by: Andrew Morton +Signed-off-by: Eliav Farber +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/minmax.h | 14 ++++++-------- + 1 file changed, 6 insertions(+), 8 deletions(-) + +--- a/include/linux/minmax.h ++++ b/include/linux/minmax.h +@@ -46,10 +46,8 @@ + * comparison, and these expressions only need to be careful to not cause + * warnings for pointer use. + */ +-#define __signed_type_use(ux) (2 + __is_nonneg(ux)) +-#define __unsigned_type_use(ux) (1 + 2 * (sizeof(ux) < 4)) + #define __sign_use(ux) (is_signed_type(typeof(ux)) ? \ +- __signed_type_use(ux) : __unsigned_type_use(ux)) ++ (2 + __is_nonneg(ux)) : (1 + 2 * (sizeof(ux) < 4))) + + /* + * Check whether a signed value is always non-negative. +@@ -57,7 +55,7 @@ + * A cast is needed to avoid any warnings from values that aren't signed + * integer types (in which case the result doesn't matter). + * +- * On 64-bit any integer or pointer type can safely be cast to 'long'. ++ * On 64-bit any integer or pointer type can safely be cast to 'long long'. + * But on 32-bit we need to avoid warnings about casting pointers to integers + * of different sizes without truncating 64-bit values so 'long' or 'long long' + * must be used depending on the size of the value. +@@ -66,12 +64,12 @@ + * them, but we do not use s128 types in the kernel (we do use 'u128', + * but they are handled by the !is_signed_type() case). + */ +-#ifdef CONFIG_64BIT +- #define __signed_type(ux) long ++#if __SIZEOF_POINTER__ == __SIZEOF_LONG_LONG__ ++#define __is_nonneg(ux) statically_true((long long)(ux) >= 0) + #else +- #define __signed_type(ux) typeof(__builtin_choose_expr(sizeof(ux) > 4, 1LL, 1L)) ++#define __is_nonneg(ux) statically_true( \ ++ (typeof(__builtin_choose_expr(sizeof(ux) > 4, 1LL, 1L)))(ux) >= 0) + #endif +-#define __is_nonneg(ux) statically_true((__signed_type(ux))(ux) >= 0) + + #define __types_ok(ux, uy) \ + (__sign_use(ux) & __sign_use(uy)) diff --git a/queue-5.10/minmax.h-simplify-the-variants-of-clamp.patch b/queue-5.10/minmax.h-simplify-the-variants-of-clamp.patch new file mode 100644 index 0000000000..19831fa1ad --- /dev/null +++ b/queue-5.10/minmax.h-simplify-the-variants-of-clamp.patch @@ -0,0 +1,97 @@ +From prvs=378230090=farbere@amazon.com Fri Oct 17 11:13:55 2025 +From: Eliav Farber +Date: Fri, 17 Oct 2025 09:05:18 +0000 +Subject: minmax.h: simplify the variants of clamp() +To: , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , +Cc: Arnd Bergmann , Christoph Hellwig , Dan Carpenter , Jens Axboe , Lorenzo Stoakes , Mateusz Guzik , Pedro Falcato +Message-ID: <20251017090519.46992-27-farbere@amazon.com> + +From: David Laight + +[ Upstream commit 495bba17cdf95e9703af1b8ef773c55ef0dfe703 ] + +Always pass a 'type' through to __clamp_once(), pass '__auto_type' from +clamp() itself. + +The expansion of __types_ok3() is reasonable so it isn't worth the added +complexity of avoiding it when a fixed type is used for all three values. + +Link: https://lkml.kernel.org/r/8f69f4deac014f558bab186444bac2e8@AcuMS.aculab.com +Signed-off-by: David Laight +Cc: Andy Shevchenko +Cc: Arnd Bergmann +Cc: Christoph Hellwig +Cc: Dan Carpenter +Cc: Jason A. Donenfeld +Cc: Jens Axboe +Cc: Lorenzo Stoakes +Cc: Mateusz Guzik +Cc: Matthew Wilcox +Cc: Pedro Falcato +Signed-off-by: Andrew Morton +Signed-off-by: Eliav Farber +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/minmax.h | 24 ++++++++++++------------ + 1 file changed, 12 insertions(+), 12 deletions(-) + +--- a/include/linux/minmax.h ++++ b/include/linux/minmax.h +@@ -183,29 +183,29 @@ + #define __clamp(val, lo, hi) \ + ((val) >= (hi) ? (hi) : ((val) <= (lo) ? (lo) : (val))) + +-#define __clamp_once(val, lo, hi, uval, ulo, uhi) ({ \ +- __auto_type uval = (val); \ +- __auto_type ulo = (lo); \ +- __auto_type uhi = (hi); \ ++#define __clamp_once(type, val, lo, hi, uval, ulo, uhi) ({ \ ++ type uval = (val); \ ++ type ulo = (lo); \ ++ type uhi = (hi); \ + BUILD_BUG_ON_MSG(statically_true(ulo > uhi), \ + "clamp() low limit " #lo " greater than high limit " #hi); \ + BUILD_BUG_ON_MSG(!__types_ok3(uval, ulo, uhi), \ + "clamp("#val", "#lo", "#hi") signedness error"); \ + __clamp(uval, ulo, uhi); }) + +-#define __careful_clamp(val, lo, hi) \ +- __clamp_once(val, lo, hi, __UNIQUE_ID(v_), __UNIQUE_ID(l_), __UNIQUE_ID(h_)) ++#define __careful_clamp(type, val, lo, hi) \ ++ __clamp_once(type, val, lo, hi, __UNIQUE_ID(v_), __UNIQUE_ID(l_), __UNIQUE_ID(h_)) + + /** +- * clamp - return a value clamped to a given range with strict typechecking ++ * clamp - return a value clamped to a given range with typechecking + * @val: current value + * @lo: lowest allowable value + * @hi: highest allowable value + * +- * This macro does strict typechecking of @lo/@hi to make sure they are of the +- * same type as @val. See the unnecessary pointer comparisons. ++ * This macro checks @val/@lo/@hi to make sure they have compatible ++ * signedness. + */ +-#define clamp(val, lo, hi) __careful_clamp(val, lo, hi) ++#define clamp(val, lo, hi) __careful_clamp(__auto_type, val, lo, hi) + + /** + * clamp_t - return a value clamped to a given range using a given type +@@ -217,7 +217,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) __careful_clamp((type)(val), (type)(lo), (type)(hi)) ++#define clamp_t(type, val, lo, hi) __careful_clamp(type, val, lo, hi) + + /** + * clamp_val - return a value clamped to a given range using val's type +@@ -230,7 +230,7 @@ + * type and @lo and @hi are literals that will otherwise be assigned a signed + * integer type. + */ +-#define clamp_val(val, lo, hi) clamp_t(typeof(val), val, lo, hi) ++#define clamp_val(val, lo, hi) __careful_clamp(typeof(val), val, lo, hi) + + /* + * Do not check the array parameter using __must_be_array(). diff --git a/queue-5.10/minmax.h-update-some-comments.patch b/queue-5.10/minmax.h-update-some-comments.patch new file mode 100644 index 0000000000..de0f4deb59 --- /dev/null +++ b/queue-5.10/minmax.h-update-some-comments.patch @@ -0,0 +1,128 @@ +From prvs=378230090=farbere@amazon.com Fri Oct 17 11:12:31 2025 +From: Eliav Farber +Date: Fri, 17 Oct 2025 09:05:14 +0000 +Subject: minmax.h: update some comments +To: , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , +Cc: Arnd Bergmann , Christoph Hellwig , Dan Carpenter , Jens Axboe , Lorenzo Stoakes , Mateusz Guzik , Pedro Falcato +Message-ID: <20251017090519.46992-23-farbere@amazon.com> + +From: David Laight + +[ Upstream commit 10666e99204818ef45c702469488353b5bb09ec7 ] + +- Change three to several. +- Remove the comment about retaining constant expressions, no longer true. +- Realign to nearer 80 columns and break on major punctiation. +- Add a leading comment to the block before __signed_type() and __is_nonneg() + Otherwise the block explaining the cast is a bit 'floating'. + Reword the rest of that comment to improve readability. + +Link: https://lkml.kernel.org/r/85b050c81c1d4076aeb91a6cded45fee@AcuMS.aculab.com +Signed-off-by: David Laight +Cc: Andy Shevchenko +Cc: Arnd Bergmann +Cc: Christoph Hellwig +Cc: Dan Carpenter +Cc: Jason A. Donenfeld +Cc: Jens Axboe +Cc: Lorenzo Stoakes +Cc: Mateusz Guzik +Cc: Matthew Wilcox +Cc: Pedro Falcato +Signed-off-by: Andrew Morton +Signed-off-by: Eliav Farber +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/minmax.h | 61 ++++++++++++++++++++++--------------------------- + 1 file changed, 28 insertions(+), 33 deletions(-) + +--- a/include/linux/minmax.h ++++ b/include/linux/minmax.h +@@ -8,13 +8,10 @@ + #include + + /* +- * min()/max()/clamp() macros must accomplish three things: ++ * min()/max()/clamp() macros must accomplish several things: + * + * - Avoid multiple evaluations of the arguments (so side-effects like + * "x++" happen only once) when non-constant. +- * - 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 +@@ -31,25 +28,23 @@ + * bit #0 set if ok for unsigned comparisons + * bit #1 set if ok for signed comparisons + * +- * In particular, statically non-negative signed integer +- * expressions are ok for both. ++ * In particular, statically non-negative signed integer expressions ++ * are ok for both. + * +- * NOTE! Unsigned types smaller than 'int' are implicitly +- * converted to 'int' in expressions, and are accepted for +- * signed conversions for now. This is debatable. +- * +- * Note that 'x' is the original expression, and 'ux' is +- * the unique variable that contains the value. +- * +- * We use 'ux' for pure type checking, and 'x' for when +- * we need to look at the value (but without evaluating +- * it for side effects! Careful to only ever evaluate it +- * with sizeof() or __builtin_constant_p() etc). +- * +- * Pointers end up being checked by the normal C type +- * rules at the actual comparison, and these expressions +- * only need to be careful to not cause warnings for +- * pointer use. ++ * NOTE! Unsigned types smaller than 'int' are implicitly converted to 'int' ++ * in expressions, and are accepted for signed conversions for now. ++ * This is debatable. ++ * ++ * Note that 'x' is the original expression, and 'ux' is the unique variable ++ * that contains the value. ++ * ++ * We use 'ux' for pure type checking, and 'x' for when we need to look at the ++ * value (but without evaluating it for side effects! ++ * Careful to only ever evaluate it with sizeof() or __builtin_constant_p() etc). ++ * ++ * Pointers end up being checked by the normal C type rules at the actual ++ * comparison, and these expressions only need to be careful to not cause ++ * warnings for pointer use. + */ + #define __signed_type_use(x, ux) (2 + __is_nonneg(x, ux)) + #define __unsigned_type_use(x, ux) (1 + 2 * (sizeof(ux) < 4)) +@@ -57,19 +52,19 @@ + __signed_type_use(x, ux) : __unsigned_type_use(x, ux)) + + /* +- * To avoid warnings about casting pointers to integers +- * of different sizes, we need that special sign type. ++ * Check whether a signed value is always non-negative. + * +- * On 64-bit we can just always use 'long', since any +- * integer or pointer type can just be cast to that. ++ * A cast is needed to avoid any warnings from values that aren't signed ++ * integer types (in which case the result doesn't matter). + * +- * This does not work for 128-bit signed integers since +- * the cast would truncate them, but we do not use s128 +- * types in the kernel (we do use 'u128', but they will +- * be handled by the !is_signed_type() case). +- * +- * NOTE! The cast is there only to avoid any warnings +- * from when values that aren't signed integer types. ++ * On 64-bit any integer or pointer type can safely be cast to 'long'. ++ * But on 32-bit we need to avoid warnings about casting pointers to integers ++ * of different sizes without truncating 64-bit values so 'long' or 'long long' ++ * must be used depending on the size of the value. ++ * ++ * This does not work for 128-bit signed integers since the cast would truncate ++ * them, but we do not use s128 types in the kernel (we do use 'u128', ++ * but they are handled by the !is_signed_type() case). + */ + #ifdef CONFIG_64BIT + #define __signed_type(ux) long diff --git a/queue-5.10/minmax.h-use-build_bug_on_msg-for-the-lo-hi-test-in-clamp.patch b/queue-5.10/minmax.h-use-build_bug_on_msg-for-the-lo-hi-test-in-clamp.patch new file mode 100644 index 0000000000..c8e660e027 --- /dev/null +++ b/queue-5.10/minmax.h-use-build_bug_on_msg-for-the-lo-hi-test-in-clamp.patch @@ -0,0 +1,47 @@ +From prvs=378230090=farbere@amazon.com Fri Oct 17 11:13:15 2025 +From: Eliav Farber +Date: Fri, 17 Oct 2025 09:05:16 +0000 +Subject: minmax.h: use BUILD_BUG_ON_MSG() for the lo < hi test in clamp() +To: , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , +Cc: Arnd Bergmann , Christoph Hellwig , Dan Carpenter , Jens Axboe , Lorenzo Stoakes , Mateusz Guzik , Pedro Falcato +Message-ID: <20251017090519.46992-25-farbere@amazon.com> + +From: David Laight + +[ Upstream commit a5743f32baec4728711bbc01d6ac2b33d4c67040 ] + +Use BUILD_BUG_ON_MSG(statically_true(ulo > uhi), ...) for the sanity check +of the bounds in clamp(). Gives better error coverage and one less +expansion of the arguments. + +Link: https://lkml.kernel.org/r/34d53778977747f19cce2abb287bb3e6@AcuMS.aculab.com +Signed-off-by: David Laight +Cc: Andy Shevchenko +Cc: Arnd Bergmann +Cc: Christoph Hellwig +Cc: Dan Carpenter +Cc: Jason A. Donenfeld +Cc: Jens Axboe +Cc: Lorenzo Stoakes +Cc: Mateusz Guzik +Cc: Matthew Wilcox +Cc: Pedro Falcato +Signed-off-by: Andrew Morton +Signed-off-by: Eliav Farber +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/minmax.h | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +--- a/include/linux/minmax.h ++++ b/include/linux/minmax.h +@@ -106,8 +106,7 @@ + __auto_type uval = (val); \ + __auto_type ulo = (lo); \ + __auto_type uhi = (hi); \ +- static_assert(__builtin_choose_expr(__is_constexpr((lo) > (hi)), \ +- (lo) <= (hi), true), \ ++ BUILD_BUG_ON_MSG(statically_true(ulo > uhi), \ + "clamp() low limit " #lo " greater than high limit " #hi); \ + BUILD_BUG_ON_MSG(!__types_ok3(uval, ulo, uhi), \ + "clamp("#val", "#lo", "#hi") signedness error"); \ diff --git a/queue-5.10/overflow-tracing-define-the-is_signed_type-macro-once.patch b/queue-5.10/overflow-tracing-define-the-is_signed_type-macro-once.patch new file mode 100644 index 0000000000..77424e104b --- /dev/null +++ b/queue-5.10/overflow-tracing-define-the-is_signed_type-macro-once.patch @@ -0,0 +1,87 @@ +From linux-staging+bounces-34939-greg=kroah.com@lists.linux.dev Fri Oct 17 11:09:40 2025 +From: Eliav Farber +Date: Fri, 17 Oct 2025 09:04:53 +0000 +Subject: overflow, tracing: Define the is_signed_type() macro once +To: , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , +Cc: Arnd Bergmann , Dan Williams , Eric Dumazet , Isabella Basso , Josh Poimboeuf , Masami Hiramatsu , Sander Vanheule , Vlastimil Babka , Yury Norov +Message-ID: <20251017090519.46992-2-farbere@amazon.com> + +From: Bart Van Assche + +[ Upstream commit 92d23c6e94157739b997cacce151586a0d07bb8a ] + +There are two definitions of the is_signed_type() macro: one in + and a second definition in . + +As suggested by Linus Torvalds, move the definition of the +is_signed_type() macro into the header file. Change +the definition of the is_signed_type() macro to make sure that it does +not trigger any sparse warnings with future versions of sparse for +bitwise types. See also: +https://lore.kernel.org/all/CAHk-=whjH6p+qzwUdx5SOVVHjS3WvzJQr6mDUwhEyTf6pJWzaQ@mail.gmail.com/ +https://lore.kernel.org/all/CAHk-=wjQGnVfb4jehFR0XyZikdQvCZouE96xR_nnf5kqaM5qqQ@mail.gmail.com/ + +Cc: Andrew Morton +Cc: Arnd Bergmann +Cc: Dan Williams +Cc: Eric Dumazet +Cc: Ingo Molnar +Cc: Isabella Basso +Cc: "Jason A. Donenfeld" +Cc: Josh Poimboeuf +Cc: Luc Van Oostenryck +Cc: Masami Hiramatsu +Cc: Nathan Chancellor +Cc: Peter Zijlstra +Cc: Rasmus Villemoes +Cc: Sander Vanheule +Cc: Steven Rostedt +Cc: Vlastimil Babka +Cc: Yury Norov +Signed-off-by: Bart Van Assche +Signed-off-by: Kees Cook +Link: https://lore.kernel.org/r/20220826162116.1050972-3-bvanassche@acm.org +Signed-off-by: Eliav Farber +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/compiler.h | 6 ++++++ + include/linux/overflow.h | 1 - + include/linux/trace_events.h | 2 -- + 3 files changed, 6 insertions(+), 3 deletions(-) + +--- a/include/linux/compiler.h ++++ b/include/linux/compiler.h +@@ -246,6 +246,12 @@ static inline void *offset_to_ptr(const + #define __must_be_array(a) BUILD_BUG_ON_ZERO(__same_type((a), &(a)[0])) + + /* ++ * Whether 'type' is a signed type or an unsigned type. Supports scalar types, ++ * bool and also pointer types. ++ */ ++#define is_signed_type(type) (((type)(-1)) < (__force type)1) ++ ++/* + * This is needed in functions which generate the stack canary, see + * arch/x86/kernel/smpboot.c::start_secondary() for an example. + */ +--- a/include/linux/overflow.h ++++ b/include/linux/overflow.h +@@ -29,7 +29,6 @@ + * https://mail-index.netbsd.org/tech-misc/2007/02/05/0000.html - + * credit to Christian Biere. + */ +-#define is_signed_type(type) (((type)(-1)) < (type)1) + #define __type_half_max(type) ((type)1 << (8*sizeof(type) - 1 - is_signed_type(type))) + #define type_max(T) ((T)((__type_half_max(T) - 1) + __type_half_max(T))) + #define type_min(T) ((T)((T)-type_max(T)-(T)1)) +--- a/include/linux/trace_events.h ++++ b/include/linux/trace_events.h +@@ -700,8 +700,6 @@ extern int trace_add_event_call(struct t + extern int trace_remove_event_call(struct trace_event_call *call); + extern int trace_event_get_offsets(struct trace_event_call *call); + +-#define is_signed_type(type) (((type)(-1)) < (type)1) +- + int ftrace_set_clr_event(struct trace_array *tr, char *buf, int set); + int trace_set_clr_event(const char *system, const char *event, int set); + int trace_array_set_clr_event(struct trace_array *tr, const char *system, diff --git a/queue-5.10/series b/queue-5.10/series index 87303f2264..344c3f953b 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -193,3 +193,30 @@ cramfs-verify-inode-mode-when-loading-from-disk.patch locking-introduce-__cleanup-based-infrastructure.patch fscontext-do-not-consume-log-entries-when-returning-emsgsize.patch arm64-mte-do-not-flag-the-zero-page-as-pg_mte_tagged.patch +overflow-tracing-define-the-is_signed_type-macro-once.patch +btrfs-remove-duplicated-in_range-macro.patch +minmax-sanity-check-constant-bounds-when-clamping.patch +minmax-clamp-more-efficiently-by-avoiding-extra-comparison.patch +minmax-add-in_range-macro.patch +minmax-introduce-min-max-_array.patch +minmax-deduplicate-__unconst_integer_typeof.patch +minmax-fix-header-inclusions.patch +minmax-allow-min-max-clamp-if-the-arguments-have-the-same-signedness.patch +minmax-fix-indentation-of-__cmp_once-and-__clamp_once.patch +minmax-allow-comparisons-of-int-against-unsigned-char-short.patch +minmax-relax-check-to-allow-comparison-between-unsigned-arguments-and-signed-constants.patch +minmax-avoid-overly-complicated-constant-expressions-in-vm-code.patch +minmax-add-a-few-more-min_t-max_t-users.patch +minmax-simplify-and-clarify-min_t-max_t-implementation.patch +minmax-make-generic-min-and-max-macros-available-everywhere.patch +minmax-don-t-use-max-in-situations-that-want-a-c-constant-expression.patch +minmax-simplify-min-max-clamp-implementation.patch +minmax-improve-macro-expansion-and-type-checking.patch +minmax-fix-up-min3-and-max3-too.patch +minmax.h-add-whitespace-around-operators-and-after-commas.patch +minmax.h-update-some-comments.patch +minmax.h-reduce-the-define-expansion-of-min-max-and-clamp.patch +minmax.h-use-build_bug_on_msg-for-the-lo-hi-test-in-clamp.patch +minmax.h-move-all-the-clamp-definitions-after-the-min-max-ones.patch +minmax.h-simplify-the-variants-of-clamp.patch +minmax.h-remove-some-defines-that-are-only-expanded-once.patch -- 2.47.3