All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Vlastimil Babka (SUSE)" <vbabka@kernel.org>,
	"Johannes Weiner" <hannes@cmpxchg.org>
Cc: "Suren Baghdasaryan" <surenb@google.com>,
	"Michal Hocko" <mhocko@suse.com>,
	"Brendan Jackman" <brendan.jackman@linux.dev>,
	"Zi Yan" <ziy@nvidia.com>, "David Hildenbrand" <david@kernel.org>,
	"Qi Zheng" <qi.zheng@linux.dev>,
	"Shakeel Butt" <shakeel.butt@linux.dev>,
	"Lorenzo Stoakes" <ljs@kernel.org>,
	"Kairui Song" <kasong@tencent.com>,
	"Barry Song" <baohua@kernel.org>,
	"Axel Rasmussen" <axelrasmussen@google.com>,
	"Yuanchu Xie" <yuanchu@google.com>, "Wei Xu" <weixugc@google.com>,
	"Baoquan He" <baoquan.he@linux.dev>,
	"Baolin Wang" <baolin.wang@linux.alibaba.com>,
	"JP Kobryn" <jp.kobryn@linux.dev>,
	"Frank van der Linden" <fvdl@google.com>,
	"Thadeu Lima de Souza Cascardo" <cascardo@igalia.com>,
	"Andrew Morton" <akpm@linux-foundation.org>,
	linux-mm@kvack.org
Subject: Re: [PATCH] mm, vmscan: make kswapd unreserve highatomic pageblocks
Date: Thu, 05 Nov 2026 18:39:10 +0000	[thread overview]
Message-ID: <sashiko-outbox-199783@kernel.org> (raw)
In-Reply-To: <20261104-kswapd-highatomic-unreserve-v1-1-38be5106adf5@kernel.org>

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
- [Medium] mm, vmscan: premature highatomic unreserve in balance_pgdat()
- [Medium] mm, vmscan: incomplete highatomic unreserve in balance_pgdat()
- [Low] mm, vmscan: contradictory migratetype comment in balance_pgdat()
--

commit 9f34d95b6ce713649b203e410b246f2a907d1814
Author: Vlastimil Babka (SUSE) <vbabka@kernel.org>

mm, vmscan: make kswapd unreserve highatomic pageblocks

This commit extracts unreserve_highatomic_pageblock_zone() and calls it from
balance_pgdat() when kswapd raises reclaim priority or reclaims no pages. This
allows kswapd to unreserve MIGRATE_HIGHATOMIC pageblocks on nodes where direct
reclaim does not run.

> diff --git a/mm/vmscan.c b/mm/vmscan.c
> index 9959ca158ce83..91c622068d991 100644
> --- a/mm/vmscan.c
> +++ b/mm/vmscan.c
> @@ -7460,8 +7460,22 @@ static int balance_pgdat(pg_data_t *pgdat, int order, int highest_zoneidx)
>  		if (nr_boost_reclaim && !nr_reclaimed)
>  			break;
>  
> -		if (raise_priority || !nr_reclaimed)
> +		if (raise_priority || !nr_reclaimed) {

[Severity: Medium]
Will gating this on raise_priority cause kswapd to prematurely unreserve
MIGRATE_HIGHATOMIC pageblocks during ordinary, successful reclaim passes at
DEF_PRIORITY?

In balance_pgdat(), raise_priority is initialized to true at the start of
each loop iteration and is only cleared if kswapd_shrink_node() returns true
(or at DEF_PRIORITY - 2 during watermark-boosted reclaim):

mm/vmscan.c:kswapd_shrink_node() {
	sc->nr_to_reclaim = 0;
	for_each_managed_zone_pgdat(zone, pgdat, z, sc->reclaim_idx) {
		sc->nr_to_reclaim += max(high_wmark_pages(zone), SWAP_CLUSTER_MAX);
	}
	...
	return max(sc->nr_scanned, sc->nr_reclaimed - nr_reclaimed) >= sc->nr_to_reclaim;
}

Because sc->nr_to_reclaim is set to the full sum of high_wmark_pages(zone)
rather than the deficit between low and high watermarks, a normal pass at
DEF_PRIORITY that scans lruvec_size >> DEF_PRIORITY pages and reclaims
enough pages to balance the node (or aborts scanning early in
should_abort_scan() under CONFIG_LRU_GEN once WMARK_HIGH + MIN_LRU_BATCH is
met) still has kswapd_shrink_node() return false.

Since pgdat_balanced() is only checked at the top of the do-while loop (and
is already true during watermark-boosted reclaim when nr_boost_reclaim > 0),
a first pass at DEF_PRIORITY that makes progress or has already balanced the
node will still enter this branch, unreserve highatomic pageblocks into
MIGRATE_UNMOVABLE across all eligible zones, and only then notice
pgdat_balanced() is true at the top of the next iteration.

Should highatomic unreservation in balance_pgdat() only happen when
!nr_reclaimed (or after rechecking !pgdat_balanced() when reclaim fails to
make progress)?

> +			/*
> +			 * Similarly to when direct reclaim is retrying, try to
> +			 * unreserve highatomic pageblocks on the node. Convert
> +			 * them to movable ones as kswapd doesn't have a target
> +			 * migratetype, and passing unmovable should lead to
> +			 * least permanent fragmentation.
> +			 */

[Severity: Low]
This isn't a bug, but the comment says "Convert them to movable ones" while
the second half of the sentence and the call below use MIGRATE_UNMOVABLE.
Should that say "Convert them to unmovable ones"?

> +			for (int i = 0; i <= highest_zoneidx; i++) {
> +				struct zone *zone = pgdat->node_zones + i;
> +
> +				unreserve_highatomic_pageblock_zone(zone,
> +						MIGRATE_UNMOVABLE, false);
> +			}

[Severity: Medium]
Can a node filled with unreclaimable 1G hugepages still fail to balance in
balance_pgdat() and hit kswapd_failures exhaustion with this change?

There appear to be three related cases in this path:

First, unreserve_highatomic_pageblock_zone() preserves the last pageblock
when force is false:

mm/page_alloc.c:unreserve_highatomic_pageblock_zone() {
	if (!force && zone->nr_reserved_highatomic <= pageblock_nr_pages)
		return false;
}

However, __zone_watermark_unusable_free() still subtracts all of
z->nr_free_highatomic, including free pages in that last reserved pageblock.
Unlike direct reclaim, which follows up with force = true in
should_reclaim_retry(), balance_pgdat() never passes force = true, so if the
single remaining highatomic pageblock keeps usable free pages below the
watermark, pgdat_balanced() will remain false.

Second, reserve_highatomic_pageblock() can reserve up to 1% of
zone_managed_pages(zone), which includes 1G hugetlbfs pages (for example, up
to 320 pageblocks on a 64GB zone). Because
unreserve_highatomic_pageblock_zone() unreserves at most one pageblock per
call, a full balance_pgdat() walk from DEF_PRIORITY down to 1 unreserves at
most 12 pageblocks per zone (or at most 6 under CONFIG_LRU_GEN when
set_initial_priority() starts at DEF_PRIORITY / 2 because reclaimable is 0).

Third, unreserving highatomic pageblocks does not increment sc.nr_reclaimed,
and if the final unreserve at sc.priority == 1 balances the node, the loop
exits before rechecking pgdat_balanced() at the top of the loop:

mm/vmscan.c:balance_pgdat() {
	if (!sc.nr_reclaimed && !boosted) {
		int fail_cnt = atomic_inc_return(&pgdat->kswapd_failures);
		/* kswapd context, low overhead to trace every failure */
		trace_mm_vmscan_kswapd_reclaim_fail(pgdat->node_id, fail_cnt);
	}
}

Once pgdat->kswapd_failures reaches MAX_RECLAIM_RETRIES, kswapd stops even if
unreserving highatomic pageblocks was making progress or more reserved
highatomic pageblocks remain.

Could balance_pgdat() pass force = true at low priority, and avoid
incrementing kswapd_failures (or restart/recheck balance) when
unreserve_highatomic_pageblock_zone() succeeds?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261104-kswapd-highatomic-unreserve-v1-1-38be5106adf5@kernel.org?part=1


      parent reply	other threads:[~2026-11-05 18:39 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-04 18:38 [PATCH] mm, vmscan: make kswapd unreserve highatomic pageblocks Vlastimil Babka (SUSE)
2026-11-04 20:03 ` Thadeu Lima de Souza Cascardo
2026-11-04 21:17   ` Vlastimil Babka (SUSE)
2026-11-04 21:56 ` Jose A. Perez de Azpillaga
2026-11-05  8:02   ` Vlastimil Babka (SUSE)
2026-11-05 11:43     ` Jose A. Perez de Azpillaga
2026-11-05 11:52       ` Vlastimil Babka (SUSE)
2026-11-05 12:11         ` Jose A. Perez de Azpillaga
2026-11-05 18:39 ` sashiko-bot [this message]

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=sashiko-outbox-199783@kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=akpm@linux-foundation.org \
    --cc=axelrasmussen@google.com \
    --cc=baohua@kernel.org \
    --cc=baolin.wang@linux.alibaba.com \
    --cc=baoquan.he@linux.dev \
    --cc=brendan.jackman@linux.dev \
    --cc=cascardo@igalia.com \
    --cc=david@kernel.org \
    --cc=fvdl@google.com \
    --cc=hannes@cmpxchg.org \
    --cc=jp.kobryn@linux.dev \
    --cc=kasong@tencent.com \
    --cc=linux-mm@kvack.org \
    --cc=ljs@kernel.org \
    --cc=mhocko@suse.com \
    --cc=qi.zheng@linux.dev \
    --cc=sashiko-reviews@lists.linux.dev \
    --cc=shakeel.butt@linux.dev \
    --cc=surenb@google.com \
    --cc=vbabka@kernel.org \
    --cc=weixugc@google.com \
    --cc=yuanchu@google.com \
    --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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.