From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from out-178.mta0.migadu.com (out-178.mta0.migadu.com [91.218.175.178]) (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 E88D5360751 for ; Wed, 11 Mar 2026 14:24:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.218.175.178 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773239098; cv=none; b=HW8iihynWu/ioSfkYID9PhzYfPi07KiymWY6w5XLfWQc+MfAZ9CI6jufW16JIwAiup4NLS4Y4QIwHVQVaRJndTPGVOGnObBBP5Xy2JbwJR4oJmj3wnNeoC4sp9xiudtAgB8kPw6OmPdNCzSBZQElC9OpNtsM3Hu0gB4aE9EhQPk= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773239098; c=relaxed/simple; bh=XlUE/Tk8aYEfY95ixXwANfIIyeho0Z9p1zvr0sFlyBw=; h=Message-ID:Date:MIME-Version:Subject:To:Cc:References:From: In-Reply-To:Content-Type; b=YXP6KDGKN4ik4ICamtN5qx4Gd3f52BRIAbIRITKK5V/CEFInUO2udfT518g4X1cy5LpLtbvCkmY46p4h/VTGhVn2EdGaqvAruuIPIsv8riqTjRxfYOzAqQCLVX5WkfEdUCuchmUTwoV+FTF4WtFd+AAbrstneZR1t7k59GVC8/g= 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=Z0y7nMAQ; arc=none smtp.client-ip=91.218.175.178 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="Z0y7nMAQ" Message-ID: DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1773239093; 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: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=5Q6Luiv9qiVEnzjVEL5Hi88cV3Oz/GVyjOjLLRkZ23I=; b=Z0y7nMAQf6k0KtZFyhCOdCaRdFaGhBDk8Zzp0CYUoTHhwh5K6vchZWkSxaYmfe9RFWyekQ cMyM3G+r+YzYPmwgcXqTROWwZ/uPb3IaA2wgpFNFTGSjQBchnQYimWD+0plN110RChU0xz yZUCkDQK+bvC5IyRqiLrs9L+2O8cKmM= Date: Wed, 11 Mar 2026 17:24:48 +0300 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Subject: Re: [PATCH] mm: migrate: transfer large_rmappable flag in folio_migrate_flags() Content-Language: en-GB To: Zi Yan , "David Hildenbrand (Arm)" Cc: Andrew Morton , npache@redhat.com, willy@infradead.org, linux-mm@kvack.org, matthew.brost@intel.com, joshua.hahnjy@gmail.com, hannes@cmpxchg.org, rakie.kim@sk.com, byungchul@sk.com, gourry@gourry.net, ying.huang@linux.alibaba.com, apopple@nvidia.com, linux-kernel@vger.kernel.org, kernel-team@meta.com References: <20260311132342.3193160-1-usama.arif@linux.dev> <46edc7f1-f97e-4ff3-bf11-a56feb8e33b4@kernel.org> <1DA53E52-795E-4057-81F5-E39B85D7CF05@nvidia.com> X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. From: Usama Arif In-Reply-To: <1DA53E52-795E-4057-81F5-E39B85D7CF05@nvidia.com> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit X-Migadu-Flow: FLOW_OUT On 11/03/2026 16:38, Zi Yan wrote: > On 11 Mar 2026, at 9:33, David Hildenbrand (Arm) wrote: > >> On 3/11/26 14:23, Usama Arif wrote: >>> folio_migrate_flags() transfers folio state from source to destination >>> during migration, but does not transfer the large_rmappable flag. >>> >>> Migration allocators like alloc_migration_target() and >>> alloc_misplaced_dst_folio() use __folio_alloc() directly without >>> wrapping the result in page_rmappable_folio(), so the destination folio >>> never gets large_rmappable set. >>> >>> This becomes a problem when a folio on the deferred split queue is >>> migrated: the destination folio can be added to the deferred split queue >>> via deferred_split_folio() (which does not check large_rmappable), but >>> when the folio is later freed, folio_unqueue_deferred_split() bails out >>> early because large_rmappable is not set: >>> >>> if (folio_order(folio) <= 1 || !folio_test_large_rmappable(folio)) >>> return false; >>> >>> This leaves a stale entry on the deferred split queue, leading to >>> use-after-free when the shrinker walks the list. >>> >>> Fix this by transferring large_rmappable in folio_migrate_flags(), >>> consistent with how all other folio flags are handled. >>> >>> Fixes: dafff3f4c850 ("mm: split underused THPs") >>> Signed-off-by: Usama Arif >>> --- >>> mm/migrate.c | 3 +++ >>> 1 file changed, 3 insertions(+) >>> >>> diff --git a/mm/migrate.c b/mm/migrate.c >>> index 3380021fd3db..ee1c7bc851dd 100644 >>> --- a/mm/migrate.c >>> +++ b/mm/migrate.c >>> @@ -846,6 +846,9 @@ void folio_migrate_flags(struct folio *newfolio, struct folio *folio) >>> folio_copy_owner(newfolio, folio); >>> pgalloc_tag_swap(newfolio, folio); >>> >>> + if (folio_test_large_rmappable(folio)) >>> + folio_set_large_rmappable(newfolio); >>> + >>> mem_cgroup_migrate(folio, newfolio); >>> } >>> EXPORT_SYMBOL(folio_migrate_flags); >> >> compaction_alloc_noprof() does the page_rmappable_folio() at the end. >> >> I'd assume that all migration allocation functions must take care of that. >> >> It's a responsibility of the folio allocation code, not folio migration >> code. > > I agree. The migration allocation function needs to give a folio or other > types of page matching the original one. Do we want to turn this into > a WARN to make sure newfolio matches folio's large_rmappable state? > hmm its done in compaction_alloc() and alloc_migration_target_by_mpol() but I dont see this being done in alloc_migration_target() and alloc_misplaced_dst_folio(). I think alloc_misplaced_dst_folio() is used by NUMA balancing and alloc_migration_target() by hotplug and memory failure? I am not very familiar with migration code, so maybe I am missing where its being done in these paths?