From: Taha Sezer <tahasezer.is@gmail.com>
To: akpm@linux-foundation.org, david@kernel.org
Cc: ljs@kernel.org, vbabka@kernel.org, mhocko@suse.com,
linux-mm@kvack.org, linux-kernel@vger.kernel.org,
Taha Sezer <tahasezer.is@gmail.com>
Subject: [PATCH] mm: vmpressure: scale window size based on machine memory
Date: Mon, 31 Aug 2026 16:03:16 +0300 [thread overview]
Message-ID: <20260831130316.448-1-tahasezer.is@gmail.com> (raw)
The vmpressure window size is currently a compile-time constant of
512 pages (2 MB with 4 KB pages), regardless of the machine size.
On large machines with hundreds of gigabytes of RAM, this small window
leads to excessive false-positive pressure notifications due to the
higher absolute reclaim activity. Conversely, the fixed size is
already appropriate for small machines.
Scale the window size logarithmically with total memory at boot time,
following the same approach used by calculate_normal_threshold() in
mm/vmstat.c. Total memory is converted to 128 MB units and fls() is
used for cheap logarithmic scaling. The multiplier is clamped between
4 and 64, yielding a window range of 128 pages (512 KB) to 2048 pages
(8 MB).
This resolves the TODO that has been in the code since the original
vmpressure implementation.
Signed-off-by: Taha Sezer <tahasezer.is@gmail.com>
---
include/linux/vmpressure.h | 2 +-
mm/vmpressure.c | 60 ++++++++++++++++++++++++++++++++++++--
2 files changed, 58 insertions(+), 4 deletions(-)
diff --git a/include/linux/vmpressure.h b/include/linux/vmpressure.h
index b4d13457b..09111f5bd 100644
--- a/include/linux/vmpressure.h
+++ b/include/linux/vmpressure.h
@@ -51,7 +51,7 @@ extern struct vmpressure *memcg_to_vmpressure(struct mem_cgroup *memcg);
extern struct mem_cgroup *vmpressure_to_memcg(struct vmpressure *vmpr);
/* Shared with the v1 vmpressure block in mm/memcontrol-v1.c. */
-extern const unsigned long vmpressure_win;
+extern unsigned long vmpressure_win;
extern enum vmpressure_levels vmpressure_calc_level(unsigned long scanned,
unsigned long reclaimed);
diff --git a/mm/vmpressure.c b/mm/vmpressure.c
index 9629240d7..f88bafb71 100644
--- a/mm/vmpressure.c
+++ b/mm/vmpressure.c
@@ -13,6 +13,7 @@
* (tree=false) socket-pressure path that runs on cgroup v2.
*/
+#include <linux/bitops.h>
#include <linux/cgroup.h>
#include <linux/log2.h>
#include <linux/mm.h>
@@ -31,10 +32,63 @@
* As the vmscan reclaimer logic works with chunks which are multiple of
* SWAP_CLUSTER_MAX, it makes sense to use it for the window size as well.
*
- * TODO: Make the window size depend on machine size, as we do for vmstat
- * thresholds. Currently we set it to 512 pages (2MB for 4KB pages).
+ * The window size scales logarithmically with total memory, following the
+ * same approach as calculate_normal_threshold() in mm/vmstat.c. On small
+ * machines the window stays small for responsiveness; on large machines it
+ * grows to reduce false positives from the higher absolute reclaim activity.
+ *
+ * Sample window sizes (SWAP_CLUSTER_MAX = 32, PAGE_SIZE = 4K):
+ *
+ * RAM fls(mem) multiplier window (pages) window (bytes)
+ * -----------------------------------------------------------------
+ * <= 4 GB 0-4 4 128 512 KB
+ * 8 GB 6 6 192 768 KB
+ * 16 GB 7 7 224 896 KB
+ * 32 GB 8 8 256 1 MB
+ * 64 GB 9 9 288 1.1 MB
+ * 128 GB 10 10 320 1.3 MB
+ * 256 GB 11 11 352 1.4 MB
+ * 512 GB 12 12 384 1.5 MB
+ * 1 TB 13 13 416 1.6 MB
*/
-const unsigned long vmpressure_win = SWAP_CLUSTER_MAX * 16;
+unsigned long __read_mostly vmpressure_win = SWAP_CLUSTER_MAX * 16;
+
+/*
+ * Initialize vmpressure window size based on machine memory.
+ *
+ * Use fls() for cheap logarithmic scaling, following the same approach
+ * as calculate_normal_threshold() in mm/vmstat.c. Memory is measured
+ * in 128 MB units so that the window starts growing once total RAM
+ * exceeds a few GB.
+ */
+static int __init vmpressure_win_init(void)
+{
+ unsigned long mem;
+ int multiplier;
+
+ /*
+ * Convert total pages to 128 MB units, matching the vmstat
+ * convention: mem = totalram >> (27 - PAGE_SHIFT).
+ */
+ mem = totalram_pages() >> (27 - PAGE_SHIFT);
+
+ /*
+ * fls(0) == 0, so for machines with < 128 MB the multiplier
+ * is clamped to 4, preserving the original 128-page minimum
+ * (SWAP_CLUSTER_MAX * 4). The maximum multiplier is clamped
+ * to 64, yielding a 2048-page (8 MB) ceiling which prevents
+ * excessively delayed notifications on very large machines.
+ */
+ multiplier = clamp(fls(mem), 4, 64);
+
+ vmpressure_win = SWAP_CLUSTER_MAX * (unsigned long)multiplier;
+
+ pr_info("vmpressure: window size set to %lu pages (%lu KB)\n",
+ vmpressure_win, vmpressure_win << (PAGE_SHIFT - 10));
+
+ return 0;
+}
+core_initcall(vmpressure_win_init);
/*
* These thresholds are used when we account memory pressure through
--
2.53.0
next reply other threads:[~2026-08-31 13:03 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-31 13:03 Taha Sezer [this message]
2026-08-31 13:27 ` [PATCH] mm: vmpressure: scale window size based on machine memory Lorenzo Stoakes (ARM)
2026-08-31 17:09 ` Andrew Morton
2026-09-01 6:43 ` Taha Sezer
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260831130316.448-1-tahasezer.is@gmail.com \
--to=tahasezer.is@gmail.com \
--cc=akpm@linux-foundation.org \
--cc=david@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=ljs@kernel.org \
--cc=mhocko@suse.com \
--cc=vbabka@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox