When THP is enabled, set_recommended_min_free_kbytes() may raise min_free_kbytes using a heuristic that scales with pageblock_nr_pages. With MIGRATE_PCPTYPES equal to 3, the formula accounts for 11 pageblocks for every eligible populated zone before capping the result at 5% of low memory. This is reasonable when a pageblock is 2 MiB, as on common 4 KiB page configurations, but scales poorly with larger base page sizes. With the default arm64 pageblock sizes, the contribution per eligible zone before the 5% cap is: 4 KiB pages: 2 MiB pageblock, 22 MiB per zone 16 KiB pages: 32 MiB pageblock, 352 MiB per zone 64 KiB pages: 512 MiB pageblock, 5.5 GiB per zone Consequently, min_free_kbytes can reach excessive and unwanted levels. Add an absolute 1 GiB cap to the recommendation, in addition to the existing percentage cap. This bounds the automatic recommendation to a sane value on systems with large pageblocks while preserving existing behavior for typical systems with 2 MiB pageblocks. Link: https://lore.kernel.org/r/20260716173504.760369-1-noren@nvidia.com/ Suggested-by: Lorenzo Stoakes (ARM) Signed-off-by: Nimrod Oren --- v1: * Cap the final recommendation at 1 GiB as suggested by Lorenzo. RFC v1: https://lore.kernel.org/r/20260716173504.760369-1-noren@nvidia.com/ --- mm/khugepaged.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/mm/khugepaged.c b/mm/khugepaged.c index 27e8f3077e80..d9caf10e05b5 100644 --- a/mm/khugepaged.c +++ b/mm/khugepaged.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include "internal.h" @@ -3096,9 +3097,13 @@ void set_recommended_min_free_kbytes(void) recommended_min += pageblock_nr_pages * nr_zones * MIGRATE_PCPTYPES * MIGRATE_PCPTYPES; - /* don't ever allow to reserve more than 5% of the lowmem */ + /* + * Don't ever allow to reserve more than 5% of lowmem or 1 GiB, + * whichever is smaller. + */ recommended_min = min(recommended_min, (unsigned long) nr_free_buffer_pages() / 20); + recommended_min = min(recommended_min, SZ_1G / PAGE_SIZE); recommended_min <<= (PAGE_SHIFT-10); if (recommended_min > min_free_kbytes) { -- 2.45.0