From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 73908C54EE9 for ; Wed, 14 Sep 2022 00:59:51 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id CDEB16B0071; Tue, 13 Sep 2022 20:59:50 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id C8D7D6B0073; Tue, 13 Sep 2022 20:59:50 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id B2DF78D0001; Tue, 13 Sep 2022 20:59:50 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0013.hostedemail.com [216.40.44.13]) by kanga.kvack.org (Postfix) with ESMTP id A3F2F6B0071 for ; Tue, 13 Sep 2022 20:59:50 -0400 (EDT) Received: from smtpin15.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay09.hostedemail.com (Postfix) with ESMTP id 581DB80D71 for ; Wed, 14 Sep 2022 00:59:50 +0000 (UTC) X-FDA: 79908883740.15.5671C8D Received: from mail-qk1-f178.google.com (mail-qk1-f178.google.com [209.85.222.178]) by imf10.hostedemail.com (Postfix) with ESMTP id 18AD4C0085 for ; Wed, 14 Sep 2022 00:59:49 +0000 (UTC) Received: by mail-qk1-f178.google.com with SMTP id k12so9799511qkj.8 for ; Tue, 13 Sep 2022 17:59:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:in-reply-to:from:content-language :references:cc:to:subject:user-agent:mime-version:date:message-id :from:to:cc:subject:date; bh=7Ygc2a7zFUOpTRr5fFVTb8yN9D9ZfZYmNOPFpvUHUuQ=; b=lKEY2q7aar6XrlZKbMIH4phInaENFrHa/YSCJMCVoQzEjsT1ha6NBBahCldNIhKBg4 wv0rE9xxFElY9UOciw0vh2x1IadY5l/UsfM285e044N65AdVPKTpbHSspLiUG+icLVNu syzXtky3e4G/wtKhPUaEEvsVbAgsMJXsrRF1HZ+J5DHfu4WD7/p+9xjWkuMwxU5BBcuX mQNx+cHcsVyGmw5nDhHekXil1IlNaZpy/DSUwLoO4+54ajKFSQZp/1ZJDlfPWChfzl7d FVVTNAFbX0Y1xTCA8DpRL1Qm6gFb2VU8eqJAxGVX0qHUVZMq7aGNqUJ0hKqKwdxbkoxK 6Jdw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:in-reply-to:from:content-language :references:cc:to:subject:user-agent:mime-version:date:message-id :x-gm-message-state:from:to:cc:subject:date; bh=7Ygc2a7zFUOpTRr5fFVTb8yN9D9ZfZYmNOPFpvUHUuQ=; b=j4fSqMuEiCsco7JXu5OanAEtGAWcQhZLFjBuvlB5U3JW1g8OzChsf7Ba0f7OX2U/7G S6pvYyXlOivGCfKANwo8Jzuvb6AekXCThu64bhZiIVAT4gkQ5/uLGSPiacbaP/w/as6O 0syNC4CpqdINUPkh6OEHTP0Ts5ild1Y8Owh8A9GRYKXRltVMqiaRoRLhRz+uQb7U0QNF 3sZMBGVd5XcvZtscXi1tMTAy3cSHOVXOezLcCj1Yb6SMlNPPcJVKvgs5Mdv3IIzEim+G R92nhsD3E4PSiJwGlvEMkh3/uaSlHTOxcP0Rtb11foG1M2XqEoettGUKfRkytVjlSPmM RV9Q== X-Gm-Message-State: ACgBeo1uqQ4YmLF2m3m+pOyGIjx5NAi1mhNFvQy8p7Fv5R+tP8ND2WQo WOxcVcn9JXtrcE5O+IHKobk= X-Google-Smtp-Source: AA6agR7dMWGP0iSvZ0sXq9Rz8YJoklcIXN65K7aCsyYoukqmr7ac1lgNLDoGTHUroAxGyFnrlIvjFQ== X-Received: by 2002:a05:620a:2685:b0:6bc:374a:8f44 with SMTP id c5-20020a05620a268500b006bc374a8f44mr24790219qkp.165.1663117189214; Tue, 13 Sep 2022 17:59:49 -0700 (PDT) Received: from [10.69.40.226] ([192.19.223.252]) by smtp.gmail.com with ESMTPSA id h3-20020a05620a244300b006ce3fcee2bdsm865004qkn.50.2022.09.13.17.59.45 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Tue, 13 Sep 2022 17:59:48 -0700 (PDT) Message-ID: Date: Tue, 13 Sep 2022 17:59:43 -0700 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:102.0) Gecko/20100101 Thunderbird/102.1.2 Subject: Re: [PATCH 01/21] mm/page_isolation: protect cma from isolate_single_pageblock To: Zi Yan Cc: Andrew Morton , Jonathan Corbet , Rob Herring , Krzysztof Kozlowski , Frank Rowand , Mike Kravetz , Muchun Song , Mike Rapoport , Christoph Hellwig , Marek Szyprowski , Robin Murphy , Borislav Petkov , "Paul E. McKenney" , Neeraj Upadhyay , Randy Dunlap , Damien Le Moal , Florian Fainelli , David Hildenbrand , Oscar Salvador , Hari Bathini , Kees Cook , - , KOSAKI Motohiro , Mel Gorman , linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, linux-mm@kvack.org, iommu@lists.linux.dev References: <20220913195508.3511038-1-opendmb@gmail.com> <20220913195508.3511038-2-opendmb@gmail.com> <36E322BF-F052-4A8B-9FA5-4E0AA84E4AAF@nvidia.com> Content-Language: en-US From: Doug Berger In-Reply-To: <36E322BF-F052-4A8B-9FA5-4E0AA84E4AAF@nvidia.com> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit ARC-Authentication-Results: i=1; imf10.hostedemail.com; dkim=pass header.d=gmail.com header.s=20210112 header.b=lKEY2q7a; spf=pass (imf10.hostedemail.com: domain of opendmb@gmail.com designates 209.85.222.178 as permitted sender) smtp.mailfrom=opendmb@gmail.com; dmarc=pass (policy=none) header.from=gmail.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1663117190; a=rsa-sha256; cv=none; b=368RSqALmc4MxuX47cBGqtZM4MVrSAAfUrwSLBJCr+BzWAL4EoVvIB0FS4QdEr/zgWkWTM HWGRB2uXPBaGOnv0HNhBiNBPmvhOSEW4abH49LNYskg6B82hHltMKoi1Z2aRZEFwCr7/Z5 3YNDzyRWOp1NWQKE+87L8TnlSzpPEAU= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1663117190; h=from:from:sender: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:dkim-signature; bh=7Ygc2a7zFUOpTRr5fFVTb8yN9D9ZfZYmNOPFpvUHUuQ=; b=HEtKgVfjGwdpqAXjG2MHyhy+utl3jB4/PsGeEXhcp+hzasHenhqzcyUV8owsUuDOaSWBhw 0xJR+YPgXUJL0qerNTLosKnJh0KF5siQluWefS0/KdtfjtOxh3emp79w1o2WfU/ghg4CaH 0uFx2N0bE4mVlSU0jjV8Ciy7iFnqCaE= X-Stat-Signature: o7456wnpquof5tc18jhxqikcuz8wdm3u X-Rspamd-Queue-Id: 18AD4C0085 X-Rspam-User: Authentication-Results: imf10.hostedemail.com; dkim=pass header.d=gmail.com header.s=20210112 header.b=lKEY2q7a; spf=pass (imf10.hostedemail.com: domain of opendmb@gmail.com designates 209.85.222.178 as permitted sender) smtp.mailfrom=opendmb@gmail.com; dmarc=pass (policy=none) header.from=gmail.com X-Rspamd-Server: rspam12 X-HE-Tag: 1663117189-39449 X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: On 9/13/2022 5:02 PM, Zi Yan wrote: > On 13 Sep 2022, at 15:54, Doug Berger wrote: > >> The function set_migratetype_isolate() has special handling for >> pageblocks of MIGRATE_CMA type that protects them from being >> isolated for MIGRATE_MOVABLE requests. >> >> Since isolate_single_pageblock() doesn't receive the migratetype >> argument of start_isolate_page_range() it used the migratetype >> of the pageblock instead of the requested migratetype which >> defeats this MIGRATE_CMA check. >> >> This allows an attempt to create a gigantic page within a CMA >> region to change the migratetype of the first and last pageblocks >> from MIGRATE_CMA to MIGRATE_MOVABLE when they are restored after >> failure, which corrupts the CMA region. >> >> The calls to (un)set_migratetype_isolate() for the first and last >> pageblocks of the start_isolate_page_range() are moved back into >> that function to allow access to its migratetype argument and make >> it easier to see how all of the pageblocks in the range are >> isolated. >> >> Fixes: b2c9e2fbba32 ("mm: make alloc_contig_range work at pageblock granularity") >> Signed-off-by: Doug Berger >> --- >> mm/page_isolation.c | 75 +++++++++++++++++++++------------------------ >> 1 file changed, 35 insertions(+), 40 deletions(-) > > Thanks for the fix. Thanks for the review. > > Why not just pass migratetype into isolate_single_pageblock() and use > it when set_migratetype_isolate() is used? That would have much > fewer changes. What is the reason of pulling skip isolation logic out? I found the skip_isolation logic confusing and thought that setting and restoring the migratetype within the same function and consolidating the error recovery paths also within that function was easier to understand and less prone to accidental breakage. In particular, setting MIGRATE_ISOLATE in isolate_single_pageblock() and having to remember to unset it in start_isolate_page_range() differently on different error paths was troublesome for me. It could certainly be done differently, but this was my preference. > > Ultimately, I would like to make MIGRATE_ISOLATE a separate bit, > so that migratetype will not be overwritten during page isolation. > Then, set_migratetype_isolate() and start_isolate_page_range() > will not have migratetype to set in error recovery any more. > That is on my TODO. > >> >> diff --git a/mm/page_isolation.c b/mm/page_isolation.c >> index 9d73dc38e3d7..8e16aa22cb61 100644 >> --- a/mm/page_isolation.c >> +++ b/mm/page_isolation.c >> @@ -286,8 +286,6 @@ __first_valid_page(unsigned long pfn, unsigned long nr_pages) >> * @flags: isolation flags >> * @gfp_flags: GFP flags used for migrating pages >> * @isolate_before: isolate the pageblock before the boundary_pfn >> - * @skip_isolation: the flag to skip the pageblock isolation in second >> - * isolate_single_pageblock() >> * >> * Free and in-use pages can be as big as MAX_ORDER-1 and contain more than one >> * pageblock. When not all pageblocks within a page are isolated at the same >> @@ -302,9 +300,8 @@ __first_valid_page(unsigned long pfn, unsigned long nr_pages) >> * the in-use page then splitting the free page. >> */ >> static int isolate_single_pageblock(unsigned long boundary_pfn, int flags, >> - gfp_t gfp_flags, bool isolate_before, bool skip_isolation) >> + gfp_t gfp_flags, bool isolate_before) >> { >> - unsigned char saved_mt; >> unsigned long start_pfn; >> unsigned long isolate_pageblock; >> unsigned long pfn; >> @@ -328,18 +325,6 @@ static int isolate_single_pageblock(unsigned long boundary_pfn, int flags, >> start_pfn = max(ALIGN_DOWN(isolate_pageblock, MAX_ORDER_NR_PAGES), >> zone->zone_start_pfn); >> >> - saved_mt = get_pageblock_migratetype(pfn_to_page(isolate_pageblock)); >> - >> - if (skip_isolation) >> - VM_BUG_ON(!is_migrate_isolate(saved_mt)); >> - else { >> - ret = set_migratetype_isolate(pfn_to_page(isolate_pageblock), saved_mt, flags, >> - isolate_pageblock, isolate_pageblock + pageblock_nr_pages); >> - >> - if (ret) >> - return ret; >> - } >> - >> /* >> * Bail out early when the to-be-isolated pageblock does not form >> * a free or in-use page across boundary_pfn: >> @@ -428,7 +413,7 @@ static int isolate_single_pageblock(unsigned long boundary_pfn, int flags, >> ret = set_migratetype_isolate(page, page_mt, >> flags, head_pfn, head_pfn + nr_pages); >> if (ret) >> - goto failed; >> + return ret; >> } >> >> ret = __alloc_contig_migrate_range(&cc, head_pfn, >> @@ -443,7 +428,7 @@ static int isolate_single_pageblock(unsigned long boundary_pfn, int flags, >> unset_migratetype_isolate(page, page_mt); >> >> if (ret) >> - goto failed; >> + return -EBUSY; >> /* >> * reset pfn to the head of the free page, so >> * that the free page handling code above can split >> @@ -459,24 +444,19 @@ static int isolate_single_pageblock(unsigned long boundary_pfn, int flags, >> while (!PageBuddy(pfn_to_page(outer_pfn))) { >> /* stop if we cannot find the free page */ >> if (++order >= MAX_ORDER) >> - goto failed; >> + return -EBUSY; >> outer_pfn &= ~0UL << order; >> } >> pfn = outer_pfn; >> continue; >> } else >> #endif >> - goto failed; >> + return -EBUSY; >> } >> >> pfn++; >> } >> return 0; >> -failed: >> - /* restore the original migratetype */ >> - if (!skip_isolation) >> - unset_migratetype_isolate(pfn_to_page(isolate_pageblock), saved_mt); >> - return -EBUSY; >> } >> >> /** >> @@ -534,21 +514,30 @@ int start_isolate_page_range(unsigned long start_pfn, unsigned long end_pfn, >> unsigned long isolate_start = ALIGN_DOWN(start_pfn, pageblock_nr_pages); >> unsigned long isolate_end = ALIGN(end_pfn, pageblock_nr_pages); >> int ret; >> - bool skip_isolation = false; >> >> /* isolate [isolate_start, isolate_start + pageblock_nr_pages) pageblock */ >> - ret = isolate_single_pageblock(isolate_start, flags, gfp_flags, false, skip_isolation); >> + ret = set_migratetype_isolate(pfn_to_page(isolate_start), migratetype, >> + flags, isolate_start, isolate_start + pageblock_nr_pages); >> if (ret) >> return ret; >> - >> - if (isolate_start == isolate_end - pageblock_nr_pages) >> - skip_isolation = true; >> + ret = isolate_single_pageblock(isolate_start, flags, gfp_flags, false); >> + if (ret) >> + goto unset_start_block; >> >> /* isolate [isolate_end - pageblock_nr_pages, isolate_end) pageblock */ >> - ret = isolate_single_pageblock(isolate_end, flags, gfp_flags, true, skip_isolation); >> + pfn = isolate_end - pageblock_nr_pages; >> + if (isolate_start != pfn) { >> + ret = set_migratetype_isolate(pfn_to_page(pfn), migratetype, >> + flags, pfn, pfn + pageblock_nr_pages); >> + if (ret) >> + goto unset_start_block; >> + } >> + ret = isolate_single_pageblock(isolate_end, flags, gfp_flags, true); >> if (ret) { >> - unset_migratetype_isolate(pfn_to_page(isolate_start), migratetype); >> - return ret; >> + if (isolate_start != pfn) >> + goto unset_end_block; >> + else >> + goto unset_start_block; >> } >> >> /* skip isolated pageblocks at the beginning and end */ >> @@ -557,15 +546,21 @@ int start_isolate_page_range(unsigned long start_pfn, unsigned long end_pfn, >> pfn += pageblock_nr_pages) { >> page = __first_valid_page(pfn, pageblock_nr_pages); >> if (page && set_migratetype_isolate(page, migratetype, flags, >> - start_pfn, end_pfn)) { >> - undo_isolate_page_range(isolate_start, pfn, migratetype); >> - unset_migratetype_isolate( >> - pfn_to_page(isolate_end - pageblock_nr_pages), >> - migratetype); >> - return -EBUSY; >> - } >> + start_pfn, end_pfn)) >> + goto unset_isolated_blocks; >> } >> return 0; >> + >> +unset_isolated_blocks: >> + ret = -EBUSY; >> + undo_isolate_page_range(isolate_start + pageblock_nr_pages, pfn, >> + migratetype); >> +unset_end_block: >> + unset_migratetype_isolate(pfn_to_page(isolate_end - pageblock_nr_pages), >> + migratetype); >> +unset_start_block: >> + unset_migratetype_isolate(pfn_to_page(isolate_start), migratetype); >> + return ret; >> } >> >> /* >> -- >> 2.25.1 > > > -- > Best Regards, > Yan, Zi