| From linux-staging+bounces-34536-greg=kroah.com@lists.linux.dev Mon Sep 22 12:34:42 2025 |
| From: Eliav Farber <farbere@amazon.com> |
| Date: Mon, 22 Sep 2025 10:32:27 +0000 |
| Subject: minmax: avoid overly complicated constant expressions in VM code |
| To: <richard@nod.at>, <anton.ivanov@cambridgegreys.com>, <johannes@sipsolutions.net>, <dave.hansen@linux.intel.com>, <luto@kernel.org>, <peterz@infradead.org>, <tglx@linutronix.de>, <mingo@redhat.com>, <bp@alien8.de>, <x86@kernel.org>, <hpa@zytor.com>, <tony.luck@intel.com>, <qiuxu.zhuo@intel.com>, <james.morse@arm.com>, <mchehab@kernel.org>, <rric@kernel.org>, <harry.wentland@amd.com>, <sunpeng.li@amd.com>, <Rodrigo.Siqueira@amd.com>, <alexander.deucher@amd.com>, <christian.koenig@amd.com>, <Xinhui.Pan@amd.com>, <airlied@gmail.com>, <daniel@ffwll.ch>, <evan.quan@amd.com>, <maarten.lankhorst@linux.intel.com>, <mripard@kernel.org>, <tzimmermann@suse.de>, <jdelvare@suse.com>, <linux@roeck-us.net>, <linus.walleij@linaro.org>, <dmitry.torokhov@gmail.com>, <wens@csie.org>, <jernej.skrabec@gmail.com>, <samuel@sholland.org>, <agk@redhat.com>, <snitzer@kernel.org>, <dm-devel@lists.linux.dev>, <mailhol.vincent@wanadoo.fr>, <wg@grandegger.com>, <mkl@pengutronix.de>, <davem@davemloft.net>, <edumazet@google.com>, <kuba@kernel.org>, <pabeni@redhat.com>, <alexandre.torgue@foss.st.com>, <joabreu@synopsys.com>, <mcoquelin.stm32@gmail.com>, <krzysztof.kozlowski@linaro.org>, <malattia@linux.it>, <hdegoede@redhat.com>, <ilpo.jarvinen@linux.intel.com>, <markgross@kernel.org>, <artur.paszkiewicz@intel.com>, <jejb@linux.ibm.com>, <martin.petersen@oracle.com>, <sakari.ailus@linux.intel.com>, <gregkh@linuxfoundation.org>, <clm@fb.com>, <josef@toxicpanda.com>, <dsterba@suse.com>, <luc.vanoostenryck@gmail.com>, <rostedt@goodmis.org>, <mhiramat@kernel.org>, <pmladek@suse.com>, <andriy.shevchenko@linux.intel.com>, <linux@rasmusvillemoes.dk>, <senozhatsky@chromium.org>, <minchan@kernel.org>, <akpm@linux-foundation.org>, <dsahern@kernel.org>, <shuah@kernel.org>, <keescook@chromium.org>, <wad@chromium.org>, <farbere@amazon.com>, <David.Laight@ACULAB.COM>, <arnd@kernel.org>, <linux-um@lists.infradead.org>, <linux-kernel@vger.kernel.org>, <linux-edac@vger.kernel.org>, <amd-gfx@lists.freedesktop.org>, <dri-devel@lists.freedesktop.org>, <linux-hwmon@vger.kernel.org>, <linux-input@vger.kernel.org>, <linux-arm-kernel@lists.infradead.org>, <linux-sunxi@lists.linux.dev>, <linux-media@vger.kernel.org>, <linux-can@vger.kernel.org>, <netdev@vger.kernel.org>, <linux-stm32@st-md-mailman.stormreply.com>, <platform-driver-x86@vger.kernel.org>, <linux-scsi@vger.kernel.org>, <linux-staging@lists.linux.dev>, <linux-btrfs@vger.kernel.org>, <linux-sparse@vger.kernel.org>, <linux-trace-kernel@vger.kernel.org>, <linux-mm@kvack.org>, <linux-kselftest@vger.kernel.org>, <bpf@vger.kernel.org>, <stable@vger.kernel.org> |
| Cc: Linus Torvalds <torvalds@linux-foundation.org>, Lorenzo Stoakes <lorenzo.stoakes@oracle.com>, David Laight <David.Laight@aculab.com> |
| Message-ID: <20250922103241.16213-2-farbere@amazon.com> |
| |
| From: Linus Torvalds <torvalds@linux-foundation.org> |
| |
| [ 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 <lorenzo.stoakes@oracle.com> |
| Link: https://lore.kernel.org/all/36aa2cad-1db1-4abf-8dd2-fb20484aabc3@lucifer.local/ |
| Cc: David Laight <David.Laight@aculab.com> |
| Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> |
| Signed-off-by: Eliav Farber <farbere@amazon.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| 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) |
| +#define pageblock_order MIN_T(unsigned int, HUGETLB_PAGE_ORDER, MAX_ORDER) |
| |
| #endif /* CONFIG_HUGETLB_PAGE_SIZE_VARIABLE */ |
| |