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 X-Spam-Level: X-Spam-Status: No, score=-16.7 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id C13CDC433DB for ; Wed, 17 Feb 2021 17:33:12 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id 4C34464E4A for ; Wed, 17 Feb 2021 17:33:12 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 4C34464E4A Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=suse.cz Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=owner-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix) id CE54A6B0071; Wed, 17 Feb 2021 12:33:11 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id C6F3F8D0001; Wed, 17 Feb 2021 12:33:11 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id B38556B0073; Wed, 17 Feb 2021 12:33:11 -0500 (EST) X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0010.hostedemail.com [216.40.44.10]) by kanga.kvack.org (Postfix) with ESMTP id 969EB6B0071 for ; Wed, 17 Feb 2021 12:33:11 -0500 (EST) Received: from smtpin12.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay05.hostedemail.com (Postfix) with ESMTP id 61EED1801C19C for ; Wed, 17 Feb 2021 17:33:11 +0000 (UTC) X-FDA: 77828455782.12.35B2F2B Received: from mx2.suse.de (mx2.suse.de [195.135.220.15]) by imf04.hostedemail.com (Postfix) with ESMTP id 91808138 for ; Wed, 17 Feb 2021 17:33:09 +0000 (UTC) X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.221.27]) by mx2.suse.de (Postfix) with ESMTP id 40991B7C4; Wed, 17 Feb 2021 17:33:09 +0000 (UTC) From: Vlastimil Babka To: linux-mm@kvack.org, Mel Gorman Cc: Andrew Morton , linux-kernel@vger.kernel.org, Andrea Arcangeli , David Hildenbrand , Michal Hocko , Mike Rapoport , Vlastimil Babka , stable@vger.kernel.org Subject: [PATCH] mm, compaction: make fast_isolate_freepages() stay within zone Date: Wed, 17 Feb 2021 18:33:00 +0100 Message-Id: <20210217173300.6394-1-vbabka@suse.cz> X-Mailer: git-send-email 2.30.0 MIME-Version: 1.0 X-Rspamd-Server: rspam04 X-Rspamd-Queue-Id: 91808138 X-Stat-Signature: qcp79xxcrnsk9k9kx3ig3cde31rd43id Received-SPF: none (suse.cz>: No applicable sender policy available) receiver=imf04; identity=mailfrom; envelope-from=""; helo=mx2.suse.de; client-ip=195.135.220.15 X-HE-DKIM-Result: none/none X-HE-Tag: 1613583189-546223 Content-Transfer-Encoding: quoted-printable 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: Compaction always operates on pages from a single given zone when isolati= ng both pages to migrate and freepages. Pageblock boundaries are intersected= with zone boundaries to be safe in case zone starts or ends in the middle of pageblock. The use of pageblock_pfn_to_page() protects against non-contig= uous pageblocks. The functions fast_isolate_freepages() and fast_isolate_around() don't currently protect the fast freepage isolation thoroughly enough against t= hese corner cases, and can result in freepage isolation operate outside of zon= e boundaries: - in fast_isolate_freepages() if we get a pfn from the first pageblock of= a zone that starts in the middle of that pageblock, 'highest' can be a pf= n outside of the zone. If we fail to isolate anything in this function, w= e may then call fast_isolate_around() on a pfn outside of the zone and th= ere effectively do a set_pageblock_skip(page_to_pfn(highest)) which may cur= rently hit a VM_BUG_ON() in some configurations - fast_isolate_around() checks only the zone end boundary and not beginni= ng, nor that the pageblock is contiguous (with pageblock_pfn_to_page()) so = it's possible that we end up calling isolate_freepages_block() on a range of= pfn's from two different zones and end up e.g. isolating freepages under the = wrong zone's lock. This patch should fix the above issues. Fixes: 5a811889de10 ("mm, compaction: use free lists to quickly locate a = migration target") Cc: Signed-off-by: Vlastimil Babka --- mm/compaction.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) Hi, as promised here's a fix for issues that I think exist regardless of = the memblock stuff, but were partially exposed by that. I will see if I can m= anage to test that it does prevent the known symptoms (it should if I didn't mi= ss anything). diff --git a/mm/compaction.c b/mm/compaction.c index 190ccdaa6c19..22a35521e358 100644 --- a/mm/compaction.c +++ b/mm/compaction.c @@ -1288,7 +1288,7 @@ static void fast_isolate_around(struct compact_control *cc, unsigned long pfn, unsig= ned long nr_isolated) { unsigned long start_pfn, end_pfn; - struct page *page =3D pfn_to_page(pfn); + struct page *page; =20 /* Do not search around if there are enough pages already */ if (cc->nr_freepages >=3D cc->nr_migratepages) @@ -1299,8 +1299,12 @@ fast_isolate_around(struct compact_control *cc, un= signed long pfn, unsigned long return; =20 /* Pageblock boundaries */ - start_pfn =3D pageblock_start_pfn(pfn); - end_pfn =3D min(pageblock_end_pfn(pfn), zone_end_pfn(cc->zone)) - 1; + start_pfn =3D max(pageblock_start_pfn(pfn), cc->zone->zone_start_pfn); + end_pfn =3D min(pageblock_end_pfn(pfn), zone_end_pfn(cc->zone)); + + page =3D pageblock_pfn_to_page(start_pfn, end_pfn, cc->zone); + if (!page) + return; =20 /* Scan before */ if (start_pfn !=3D pfn) { @@ -1402,7 +1406,8 @@ fast_isolate_freepages(struct compact_control *cc) pfn =3D page_to_pfn(freepage); =20 if (pfn >=3D highest) - highest =3D pageblock_start_pfn(pfn); + highest =3D max(pageblock_start_pfn(pfn), + cc->zone->zone_start_pfn); =20 if (pfn >=3D low_pfn) { cc->fast_search_fail =3D 0; @@ -1472,7 +1477,8 @@ fast_isolate_freepages(struct compact_control *cc) } else { if (cc->direct_compaction && pfn_valid(min_pfn)) { page =3D pageblock_pfn_to_page(min_pfn, - pageblock_end_pfn(min_pfn), + min(pageblock_end_pfn(min_pfn), + zone_end_pfn(cc->zone)), cc->zone); cc->free_pfn =3D min_pfn; } --=20 2.30.0