folio_putback_lru() requires lru_lock to not be held by the caller, but it internally calls folio_add_lru() -> lruvec_add_folio() -> lru_gen_add_folio() -> list_add(), which modifies lrugen->folios[] without acquiring lruvec->lru_lock. In evict_folios(), lru_lock is dropped before shrink_folio_list() and the subsequent list_for_each_entry_safe_reverse() loop. When an unevictable folio is encountered in this lockless section, folio_putback_lru() is called to return it to lrugen->folios[]. This races with any concurrent CPU that holds lru_lock and operates on the same list (e.g. via list_del or list_move), corrupting prev->next. The corruption is detected later when move_folios_to_lru() re-acquires lru_lock and calls list_del() on a folio whose list linkage was corrupted, triggering BUG at lib/list_debug.c:64: list_del corruption. prev->next should be fffffffeead4fbc8, but was ffffeafeead44188. (prev=fffffffee4fc4c08) kernel BUG at lib/list_debug.c:64! Call trace: __list_del_entry_valid_or_report+0x100/0x14c evict_folios+0x145c/0x16dc try_to_shrink_lruvec+0x228/0x35c shrink_one+0x94/0x158 shrink_many+0x1c8/0x1f4 lru_gen_shrink_node+0x94/0x110 shrink_node+0x468/0x8b4 balance_pgdat+0x4f0/0x9a0 kswapd+0x268/0x470 The race window is amplified when unevictable memory is high, causing folio_putback_lru() to be called many times in the lockless section. move_folios_to_lru() already handles this correctly: it drops and re-acquires lru_lock around folio_putback_lru() for unevictable folios. Apply the same pattern to evict_folios(). Fixes: 359a5e1416ca ("mm: multi-gen LRU: retry folios written back while isolated") Signed-off-by: Prakash Gupta Signed-off-by: Ketan Kishore --- mm/vmscan.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mm/vmscan.c b/mm/vmscan.c index 26436059ea39..7c4adba13e4f 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -4923,7 +4923,9 @@ static int evict_folios(unsigned long nr_to_scan, struct lruvec *lruvec, if (!folio_evictable(folio)) { list_del(&folio->lru); + spin_lock_irq(&lruvec->lru_lock); folio_putback_lru(folio); + spin_unlock_irq(&lruvec->lru_lock); continue; } --- base-commit: ea2bff00da89d7767d677bb68470130ba96f4928 change-id: 20260807-evict_folios_race-f3b119e0cf97 Best regards, -- Ketan Kishore