]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
mm/damon/ops-common: putback folios on invalid migrate nid
authorliyouhong <liyouhong@kylinos.cn>
Sun, 26 Jul 2026 01:48:15 +0000 (09:48 +0800)
committerAndrew Morton <akpm@linux-foundation.org>
Wed, 5 Aug 2026 03:02:04 +0000 (20:02 -0700)
damon_pa_migrate() and damos_va_migrate() isolate folios into a local list
and then call damon_migrate_pages().  When target_nid is invalid
(including the scheme default NUMA_NO_NODE / -1), damon_migrate_pages()
returns early without putting the folios back to the LRU.

Callers then discard the list head while those folios remain isolated with
an extra reference taken by folio_isolate_lru().  The pages stay off the
LRU for as long as the mapping exists (anon active+inactive counts drop
while RSS does not), and the leftover references can pin the pages after
the mapping is gone.

Put the folios back on the invalid-nid path so ignored migration requests
still return them to the LRU.

Link: https://lore.kernel.org/20260726014815.1280757-1-dayou5941@163.com
Fixes: 7e6c3130690a ("mm/damon/ops-common: ignore migration request to invalid nodes")
Assisted-by: Cursor:grok-4.5
Reviewed-by: SJ Park <sj@kernel.org>
Signed-off-by: liyouhong <liyouhong@kylinos.cn>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
mm/damon/ops-common.c

index 6bdd1cfd3863a38e166d7bbf61dba47a01faa020..9c178c175832fde9be6bf6a2489fa0a88fffe420 100644 (file)
@@ -392,8 +392,15 @@ unsigned long damon_migrate_pages(struct list_head *folio_list, int target_nid)
                return nr_migrated;
 
        if (target_nid < 0 || target_nid >= MAX_NUMNODES ||
-                       !node_state(target_nid, N_MEMORY))
+                       !node_state(target_nid, N_MEMORY)) {
+               while (!list_empty(folio_list)) {
+                       struct folio *folio = lru_to_folio(folio_list);
+
+                       list_del(&folio->lru);
+                       folio_putback_lru(folio);
+               }
                return nr_migrated;
+       }
 
        noreclaim_flag = memalloc_noreclaim_save();