From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from out-185.mta1.migadu.com (out-185.mta1.migadu.com [95.215.58.185]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 62DA62DB7BB for ; Fri, 7 Aug 2026 15:13:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=95.215.58.185 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786115602; cv=none; b=C/3XUi/XsMpUUHemVeCgwn2YXf3/BWY9c3J2kLrxRcwgRdwnshOkC+3Zjl98xdInB0OzLu+uhusGR/SxT6r8/2VxBBEDTjBPFxrFmhC9tETJbAzNroEJKkqQB6q5QDdUNv1/o3wnYhYZ4orwvKXkFu9fue8YQ1pNk5Ghff4f9Sw= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786115602; c=relaxed/simple; bh=6oWIS7XQ6qiTgzXC5rictzOSD4fzYW3Tq/Ec91GipQE=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=En/sV1zVyWfpzh9L/f2Qflp9xtZQQfywxHgHvqV2O/EMj4wR6+HzTtwFp4P3Q5xEzf89ZG9uUiLEAfG6Yq6W0OaU585ApzOw8PKj6OpFWIA9SDEh+3cy25eqrB7iYKZfI/kOKqgoNO/Pxw72HBzW1cyCGstKZoM39QHlSZTfRic= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev; spf=pass smtp.mailfrom=linux.dev; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b=DRCYWaFH; arc=none smtp.client-ip=95.215.58.185 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.dev Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.dev Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.dev header.i=@linux.dev header.b="DRCYWaFH" Date: Fri, 7 Aug 2026 08:12:54 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1786115598; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: in-reply-to:in-reply-to:references:references; bh=f+d1J4LC7Erxo96ihjUCf50fLWAw7uZ8BNFe2NoXbak=; b=DRCYWaFHA69mf5mz1kk9tHFtqgLW9FJ7dyfDDpj5KsAf0euN0ucbfk/fAPhYoFR/DGQqA0 0fcsXLkQdR30ujBE0w1O2l9oCD4MFyWT2CPo4yIWz0t0sZ1Q6mfInxABJvA5iK0HP0O+O1 xx6xGzJ5j34gthlvzEr+jGhkMpX9coE= X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. From: Shakeel Butt To: Ketan Kishore Cc: Andrew Morton , Johannes Weiner , David Hildenbrand , Michal Hocko , Qi Zheng , Lorenzo Stoakes , Kairui Song , Barry Song , Axel Rasmussen , Yuanchu Xie , Wei Xu , Yu Zhao , kernel@oss.qualcomm.com, linux-mm@kvack.org, linux-kernel@vger.kernel.org, Prakash Gupta Subject: Re: [PATCH] mm/mglru: fix lockless folio_putback_lru() race in evict_folios() Message-ID: References: <20260807-evict_folios_race-v1-1-b167c6b4cfde@oss.qualcomm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20260807-evict_folios_race-v1-1-b167c6b4cfde@oss.qualcomm.com> X-Migadu-Flow: FLOW_OUT 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 > 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); This will introduce a deadlock.