Skip to content

Commit 3a7e02c

Browse files
committed
minmax: avoid overly complicated constant expressions in VM code
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 <[email protected]> Link: https://lore.kernel.org/all/[email protected]/ Cc: David Laight <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent e8432ac commit 3a7e02c

File tree

2 files changed

+9
-2
lines changed

2 files changed

+9
-2
lines changed

include/linux/minmax.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,4 +270,11 @@ static inline bool in_range32(u32 val, u32 start, u32 len)
270270
#define swap(a, b) \
271271
do { typeof(a) __tmp = (a); (a) = (b); (b) = __tmp; } while (0)
272272

273+
/*
274+
* Use these carefully: no type checking, and uses the arguments
275+
* multiple times. Use for obvious constants only.
276+
*/
277+
#define MIN_T(type,a,b) __cmp(min,(type)(a),(type)(b))
278+
#define MAX_T(type,a,b) __cmp(max,(type)(a),(type)(b))
279+
273280
#endif /* _LINUX_MINMAX_H */

include/linux/pageblock-flags.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,13 @@ extern unsigned int pageblock_order;
4141
* Huge pages are a constant size, but don't exceed the maximum allocation
4242
* granularity.
4343
*/
44-
#define pageblock_order min_t(unsigned int, HUGETLB_PAGE_ORDER, MAX_PAGE_ORDER)
44+
#define pageblock_order MIN_T(unsigned int, HUGETLB_PAGE_ORDER, MAX_PAGE_ORDER)
4545

4646
#endif /* CONFIG_HUGETLB_PAGE_SIZE_VARIABLE */
4747

4848
#elif defined(CONFIG_TRANSPARENT_HUGEPAGE)
4949

50-
#define pageblock_order min_t(unsigned int, HPAGE_PMD_ORDER, MAX_PAGE_ORDER)
50+
#define pageblock_order MIN_T(unsigned int, HPAGE_PMD_ORDER, MAX_PAGE_ORDER)
5151

5252
#else /* CONFIG_TRANSPARENT_HUGEPAGE */
5353

0 commit comments

Comments
 (0)