From: Lance Yang <lance.yang@linux.dev>
To: realwujing@qq.com
Cc: david@kernel.org, akpm@linux-foundation.org, hannes@cmpxchg.org,
jackmanb@google.com, linux-kernel@vger.kernel.org,
linux-mm@kvack.org, mhocko@suse.com, surenb@google.com,
vbabka@suse.cz, yuanql9@chinatelecom.cn, ziy@nvidia.com,
Lance Yang <lance.yang@linux.dev>
Subject: Re: [PATCH 1/1] mm/page_alloc: auto-tune min_free_kbytes on atomic allocation failure
Date: Mon, 5 Jan 2026 14:38:30 +0800 [thread overview]
Message-ID: <20260105063830.15140-1-lance.yang@linux.dev> (raw)
In-Reply-To: <tencent_9DB6637676D639B4B7AEA09CC6A6F9E49D0A@qq.com>
On Sun, 4 Jan 2026 20:26:52 +0800, wujing wrote:
> Introduce a mechanism to dynamically increase vm.min_free_kbytes when
> critical atomic allocations (GFP_ATOMIC, order-0) fail. This prevents
> recurring network packet drops or other atomic failures by proactively
> reserving more memory.
Just wondering, could we adjust watermark_scale_factor instead of
min_free_kbytes?
Increasing min_free_kbytes directly reduces available memory, while
watermark_scale_factor just makes kswapd wake up earlier for reclaim ...
Seems like less side effect than min_free_kbytes :)
Cheers,
Lance
>
> The adjustment doubles min_free_kbytes upon upon failure (exponential backoff),
> capped at 1% of total RAM.
>
> Observed failure logs:
> [38535641.026406] node 0: slabs: 941, objs: 54656, free: 0
> [38535641.037711] node 1: slabs: 349, objs: 22096, free: 272
> [38535641.049025] node 1: slabs: 349, objs: 22096, free: 272
> [38535642.795972] SLUB: Unable to allocate memory on node -1, gfp=0x480020(GFP_ATOMIC)
> [38535642.805017] cache: skbuff_head_cache, object size: 232, buffer size: 256, default order: 2, min order: 0
> [38535642.816311] node 0: slabs: 854, objs: 42320, free: 0
> [38535642.823066] node 1: slabs: 400, objs: 25360, free: 294
> [38535643.070199] SLUB: Unable to allocate memory on node -1, gfp=0x480020(GFP_ATOMIC)
> [38535643.078861] cache: skbuff_head_cache, object size: 232, buffer size: 256, default order: 2, min order: 0
> [38535643.089719] node 0: slabs: 841, objs: 41824, free: 0
> [38535643.096513] node 1: slabs: 393, objs: 24480, free: 272
> [38535643.484149] SLUB: Unable to allocate memory on node -1, gfp=0x480020(GFP_ATOMIC)
> [38535643.492831] cache: skbuff_head_cache, object size: 232, buffer size: 256, default order: 2, min order: 0
> [38535643.503666] node 0: slabs: 898, objs: 43120, free: 159
> [38535643.510140] node 1: slabs: 404, objs: 25424, free: 319
> [38535644.699224] SLUB: Unable to allocate memory on node -1, gfp=0x480020(GFP_ATOMIC)
> [38535644.707911] cache: skbuff_head_cache, object size: 232, buffer size: 256, default order: 2, min order: 0
> [38535644.718700] node 0: slabs: 1031, objs: 43328, free: 0
> [38535644.725059] node 1: slabs: 339, objs: 17616, free: 317
> [38535645.428345] SLUB: Unable to allocate memory on node -1, gfp=0x480020(GFP_ATOMIC)
> [38535645.436888] cache: skbuff_head_cache, object size: 232, buffer size: 256, default order: 2, min order: 0
> [38535645.447664] node 0: slabs: 940, objs: 40864, free: 144
> [38535645.454026] node 1: slabs: 322, objs: 19168, free: 383
> [38535645.556122] SLUB: Unable to allocate memory on node -1, gfp=0x480020(GFP_ATOMIC)
> [38535645.564576] cache: skbuff_head_cache, object size: 232, buffer size: 256, default order: 2, min order: 0
> [38535649.655523] warn_alloc: 59 callbacks suppressed
> [38535649.655527] swapper/100: page allocation failure: order:0, mode:0x480020(GFP_ATOMIC), nodemask=(null)
> [38535649.671692] swapper/100 cpuset=/ mems_allowed=0-1
>
> Signed-off-by: wujing <realwujing@qq.com>
> Signed-off-by: Qiliang Yuan <yuanql9@chinatelecom.cn>
> ---
> mm/page_alloc.c | 33 +++++++++++++++++++++++++++++++++
> 1 file changed, 33 insertions(+)
>
> diff --git a/mm/page_alloc.c b/mm/page_alloc.c
> index c380f063e8b7..9a24e2b6cfbf 100644
> --- a/mm/page_alloc.c
> +++ b/mm/page_alloc.c
> @@ -30,6 +30,7 @@
> #include <linux/oom.h>
> #include <linux/topology.h>
> #include <linux/sysctl.h>
> +#include <linux/workqueue.h>
> #include <linux/cpu.h>
> #include <linux/cpuset.h>
> #include <linux/pagevec.h>
> @@ -3975,6 +3976,9 @@ static void warn_alloc_show_mem(gfp_t gfp_mask, nodemask_t *nodemask)
> mem_cgroup_show_protected_memory(NULL);
> }
>
> +static void boost_min_free_kbytes_workfn(struct work_struct *work);
> +static DECLARE_WORK(boost_min_free_kbytes_work, boost_min_free_kbytes_workfn);
> +
> void warn_alloc(gfp_t gfp_mask, nodemask_t *nodemask, const char *fmt, ...)
> {
> struct va_format vaf;
> @@ -4947,6 +4951,10 @@ __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order,
> goto retry;
> }
> fail:
> + /* Auto-tuning: trigger boost if atomic allocation fails */
> + if ((gfp_mask & GFP_ATOMIC) && order == 0)
> + schedule_work(&boost_min_free_kbytes_work);
> +
> warn_alloc(gfp_mask, ac->nodemask,
> "page allocation failure: order:%u", order);
> got_pg:
> @@ -7682,3 +7690,28 @@ struct page *alloc_pages_nolock_noprof(gfp_t gfp_flags, int nid, unsigned int or
> return page;
> }
> EXPORT_SYMBOL_GPL(alloc_pages_nolock_noprof);
> +
> +static void boost_min_free_kbytes_workfn(struct work_struct *work)
> +{
> + int new_min;
> +
> + /* Cap at 1% of total RAM for safety */
> + unsigned long total_kbytes = totalram_pages() << (PAGE_SHIFT - 10);
> + int max_limit = total_kbytes / 100;
> +
> + /* Exponential increase: double the current value */
> + new_min = min_free_kbytes * 2;
> +
> + if (new_min > max_limit)
> + new_min = max_limit;
> +
> + if (new_min > min_free_kbytes) {
> + min_free_kbytes = new_min;
> + /* Update user_min_free_kbytes so it persists through recalculations */
> + if (new_min > user_min_free_kbytes)
> + user_min_free_kbytes = new_min;
> +
> + setup_per_zone_wmarks();
> + pr_info("Auto-tuning: unexpected atomic failure detected, increasing min_free_kbytes to %d\n", min_free_kbytes);
> + }
> +}
next prev parent reply other threads:[~2026-01-05 6:38 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-01-04 12:23 [PATCH 0/1] mm/page_alloc: dynamic min_free_kbytes adjustment wujing
2026-01-04 12:26 ` [PATCH 1/1] mm/page_alloc: auto-tune min_free_kbytes on atomic allocation failure wujing
2026-01-04 18:14 ` Andrew Morton
2026-01-05 2:32 ` Matthew Wilcox
2026-01-05 6:38 ` Lance Yang [this message]
2026-01-05 7:29 ` wujing
2026-01-05 16:47 ` Michal Hocko
2026-01-05 8:17 ` [PATCH v2 0/1] mm/page_alloc: dynamic min_free_kbytes adjustment wujing
2026-01-05 11:59 ` [PATCH v3 0/1] mm/page_alloc: dynamic watermark boosting wujing
[not found] ` <20260105115943.1361645-1-realwujing@qq.com>
2026-01-05 11:59 ` [PATCH v3 1/1] mm/page_alloc: auto-tune watermarks on atomic allocation failure wujing
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=20260105063830.15140-1-lance.yang@linux.dev \
--to=lance.yang@linux.dev \
--cc=akpm@linux-foundation.org \
--cc=david@kernel.org \
--cc=hannes@cmpxchg.org \
--cc=jackmanb@google.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=mhocko@suse.com \
--cc=realwujing@qq.com \
--cc=surenb@google.com \
--cc=vbabka@suse.cz \
--cc=yuanql9@chinatelecom.cn \
--cc=ziy@nvidia.com \
/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