]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
mm: fix duplicate accounting of free pages in should_reclaim_retry()
authorliuqiqi <liuqiqi@kylinos.cn>
Tue, 12 Aug 2025 07:02:10 +0000 (15:02 +0800)
committerAndrew Morton <akpm@linux-foundation.org>
Fri, 12 Sep 2025 00:25:09 +0000 (17:25 -0700)
In the zone_reclaimable_pages() function, if the page counts for
NR_ZONE_INACTIVE_FILE, NR_ZONE_ACTIVE_FILE, NR_ZONE_INACTIVE_ANON, and
NR_ZONE_ACTIVE_ANON are all zero, the function returns the number of free
pages as the result.

In this case, when should_reclaim_retry() calculates reclaimable pages, it
will inadvertently double-count the free pages in its accounting.

static inline bool
should_reclaim_retry(gfp_t gfp_mask, unsigned order,
                     struct alloc_context *ac, int alloc_flags,
                     bool did_some_progress, int *no_progress_loops)
{
        ...
                available = reclaimable = zone_reclaimable_pages(zone);
                available += zone_page_state_snapshot(zone, NR_FREE_PAGES);

This may result in an increase in the number of retries of
__alloc_pages_slowpath(), causing increased kswapd load.

Link: https://lkml.kernel.org/r/20250812070210.1624218-1-liuqiqi@kylinos.cn
Fixes: 6aaced5abd32 ("mm: vmscan: account for free pages to prevent infinite Loop in throttle_direct_reclaim()")
Signed-off-by: liuqiqi <liuqiqi@kylinos.cn>
Reviewed-by: Ye Liu <liuye@kylinos.cn>
Cc: David Hildenbrand <david@redhat.com>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
Cc: Michal Hocko <mhocko@kernel.org>
Cc: Qi Zheng <zhengqi.arch@bytedance.com>
Cc: Shakeel Butt <shakeel.butt@linux.dev>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
mm/vmscan.c

index 0f489976fa2be1cdee6462c73643f3a0d575455a..ca9e1cd3cd680d629e56c538f67c7a96954e0678 100644 (file)
@@ -398,14 +398,7 @@ unsigned long zone_reclaimable_pages(struct zone *zone)
        if (can_reclaim_anon_pages(NULL, zone_to_nid(zone), NULL))
                nr += zone_page_state_snapshot(zone, NR_ZONE_INACTIVE_ANON) +
                        zone_page_state_snapshot(zone, NR_ZONE_ACTIVE_ANON);
-       /*
-        * If there are no reclaimable file-backed or anonymous pages,
-        * ensure zones with sufficient free pages are not skipped.
-        * This prevents zones like DMA32 from being ignored in reclaim
-        * scenarios where they can still help alleviate memory pressure.
-        */
-       if (nr == 0)
-               nr = zone_page_state_snapshot(zone, NR_FREE_PAGES);
+
        return nr;
 }
 
@@ -6495,7 +6488,7 @@ static bool allow_direct_reclaim(pg_data_t *pgdat)
                return true;
 
        for_each_managed_zone_pgdat(zone, pgdat, i, ZONE_NORMAL) {
-               if (!zone_reclaimable_pages(zone))
+               if (!zone_reclaimable_pages(zone) && zone_page_state_snapshot(zone, NR_FREE_PAGES))
                        continue;
 
                pfmemalloc_reserve += min_wmark_pages(zone);