From: Shakeel Butt <shakeel.butt@linux.dev>
To: Ketan Kishore <ketan.kishore@oss.qualcomm.com>
Cc: Andrew Morton <akpm@linux-foundation.org>,
Johannes Weiner <hannes@cmpxchg.org>,
David Hildenbrand <david@kernel.org>,
Michal Hocko <mhocko@kernel.org>, Qi Zheng <qi.zheng@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>,
Yu Zhao <yuzhao@google.com>,
kernel@oss.qualcomm.com, linux-mm@kvack.org,
linux-kernel@vger.kernel.org,
Prakash Gupta <prakash.gupta@oss.qualcomm.com>
Subject: Re: [PATCH] mm/mglru: fix lockless folio_putback_lru() race in evict_folios()
Date: Fri, 7 Aug 2026 08:12:54 -0700 [thread overview]
Message-ID: <anX1F_q_BsMjuqB6@linux.dev> (raw)
In-Reply-To: <20260807-evict_folios_race-v1-1-b167c6b4cfde@oss.qualcomm.com>
On Fri, Aug 07, 2026 at 04:00:30PM +0530, Ketan Kishore wrote:
> 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.
folio_putback_lru() requires lru_lock to not be held because it holds lru lock
internally.
folio_putback_lru
folio_add_lru
__folio_batch_add_and_move
folio_batch_move_lru
folio_lruvec_relock_irqsave
>
> 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 <prakash.gupta@oss.qualcomm.com>
> Signed-off-by: Ketan Kishore <ketan.kishore@oss.qualcomm.com>
> ---
> 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);
This will introduce a deadlock.
next prev parent reply other threads:[~2026-08-07 15:13 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-07 10:30 [PATCH] mm/mglru: fix lockless folio_putback_lru() race in evict_folios() Ketan Kishore
2026-08-07 15:12 ` Shakeel Butt [this message]
2026-08-07 17:02 ` [syzbot ci] " syzbot ci
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=anX1F_q_BsMjuqB6@linux.dev \
--to=shakeel.butt@linux.dev \
--cc=akpm@linux-foundation.org \
--cc=axelrasmussen@google.com \
--cc=baohua@kernel.org \
--cc=david@kernel.org \
--cc=hannes@cmpxchg.org \
--cc=kasong@tencent.com \
--cc=kernel@oss.qualcomm.com \
--cc=ketan.kishore@oss.qualcomm.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=ljs@kernel.org \
--cc=mhocko@kernel.org \
--cc=prakash.gupta@oss.qualcomm.com \
--cc=qi.zheng@linux.dev \
--cc=weixugc@google.com \
--cc=yuanchu@google.com \
--cc=yuzhao@google.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.