From: Greg Kroah-Hartman Date: Mon, 29 Sep 2025 13:56:58 +0000 (+0200) Subject: 6.1-stable patches X-Git-Tag: v5.4.300~18 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=bc4182a77e4f1e868995e9c6c147a89be905f3a1;p=thirdparty%2Fkernel%2Fstable-queue.git 6.1-stable patches added patches: minmax-add-a-few-more-min_t-max_t-users.patch minmax-avoid-overly-complicated-constant-expressions-in-vm-code.patch minmax-simplify-and-clarify-min_t-max_t-implementation.patch --- diff --git a/queue-6.1/minmax-add-a-few-more-min_t-max_t-users.patch b/queue-6.1/minmax-add-a-few-more-min_t-max_t-users.patch new file mode 100644 index 0000000000..22885377c9 --- /dev/null +++ b/queue-6.1/minmax-add-a-few-more-min_t-max_t-users.patch @@ -0,0 +1,142 @@ +From prvs=3555e8f33=farbere@amazon.com Wed Sep 24 22:29:32 2025 +From: Eliav Farber +Date: Wed, 24 Sep 2025 20:23:09 +0000 +Subject: minmax: add a few more MIN_T/MAX_T users +To: , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , +Cc: Linus Torvalds , David Laight , Lorenzo Stoakes +Message-ID: <20250924202320.32333-9-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 +- + net/ipv4/proc.c | 2 +- + net/ipv6/proc.c | 2 +- + 7 files changed, 8 insertions(+), 8 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 +@@ -532,7 +532,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 +@@ -2618,7 +2618,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 +@@ -2827,7 +2827,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/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-6.1/minmax-avoid-overly-complicated-constant-expressions-in-vm-code.patch b/queue-6.1/minmax-avoid-overly-complicated-constant-expressions-in-vm-code.patch new file mode 100644 index 0000000000..fc0e0576c6 --- /dev/null +++ b/queue-6.1/minmax-avoid-overly-complicated-constant-expressions-in-vm-code.patch @@ -0,0 +1,78 @@ +From linux-staging+bounces-34579-greg=kroah.com@lists.linux.dev Wed Sep 24 22:28:45 2025 +From: Eliav Farber +Date: Wed, 24 Sep 2025 20:23:06 +0000 +Subject: minmax: avoid overly complicated constant expressions in VM code +To: , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , +Cc: Linus Torvalds , Lorenzo Stoakes , David Laight +Message-ID: <20250924202320.32333-6-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 +++++++ + include/linux/pageblock-flags.h | 2 +- + 2 files changed, 8 insertions(+), 1 deletion(-) + +--- 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 */ +--- a/include/linux/pageblock-flags.h ++++ b/include/linux/pageblock-flags.h +@@ -41,7 +41,7 @@ extern unsigned int pageblock_order; + * Huge pages are a constant size, but don't exceed the maximum allocation + * granularity. + */ +-#define pageblock_order min_t(unsigned int, HUGETLB_PAGE_ORDER, MAX_ORDER - 1) ++#define pageblock_order MIN_T(unsigned int, HUGETLB_PAGE_ORDER, MAX_ORDER - 1) + + #endif /* CONFIG_HUGETLB_PAGE_SIZE_VARIABLE */ + diff --git a/queue-6.1/minmax-simplify-and-clarify-min_t-max_t-implementation.patch b/queue-6.1/minmax-simplify-and-clarify-min_t-max_t-implementation.patch new file mode 100644 index 0000000000..744ec3128b --- /dev/null +++ b/queue-6.1/minmax-simplify-and-clarify-min_t-max_t-implementation.patch @@ -0,0 +1,76 @@ +From linux-staging+bounces-34580-greg=kroah.com@lists.linux.dev Wed Sep 24 22:29:02 2025 +From: Eliav Farber +Date: Wed, 24 Sep 2025 20:23:07 +0000 +Subject: minmax: simplify and clarify min_t()/max_t() implementation +To: , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , +Cc: Linus Torvalds , David Laight , Lorenzo Stoakes +Message-ID: <20250924202320.32333-7-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-6.1/series b/queue-6.1/series index afd9ff8ef1..38e1f6f009 100644 --- a/queue-6.1/series +++ b/queue-6.1/series @@ -61,3 +61,6 @@ minmax-add-in_range-macro.patch minmax-introduce-min-max-_array.patch minmax-deduplicate-__unconst_integer_typeof.patch minmax-fix-indentation-of-__cmp_once-and-__clamp_once.patch +minmax-avoid-overly-complicated-constant-expressions-in-vm-code.patch +minmax-simplify-and-clarify-min_t-max_t-implementation.patch +minmax-add-a-few-more-min_t-max_t-users.patch