From patchwork Tue Feb 4 15:14:40 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stewart Hildebrand X-Patchwork-Id: 11364831 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id A6DA41395 for ; Tue, 4 Feb 2020 15:16:13 +0000 (UTC) Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 8D73E20730 for ; Tue, 4 Feb 2020 15:16:13 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 8D73E20730 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=dornerworks.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1iyzuc-0007bP-LK; Tue, 04 Feb 2020 15:14:50 +0000 Received: from us1-rack-iad1.inumbo.com ([172.99.69.81]) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1iyzub-0007bE-D0 for xen-devel@lists.xenproject.org; Tue, 04 Feb 2020 15:14:49 +0000 X-Inumbo-ID: 1459e4e6-4761-11ea-b211-bc764e2007e4 Received: from webmail.dornerworks.com (unknown [12.207.209.150]) by us1-rack-iad1.inumbo.com (Halon) with ESMTP id 1459e4e6-4761-11ea-b211-bc764e2007e4; Tue, 04 Feb 2020 15:14:48 +0000 (UTC) From: Stewart Hildebrand To: Date: Tue, 4 Feb 2020 10:14:40 -0500 Message-ID: <20200204151441.10626-1-stewart.hildebrand@dornerworks.com> X-Mailer: git-send-email 2.25.0 MIME-Version: 1.0 X-Originating-IP: [172.27.13.130] X-ClientProxiedBy: Mcbain.dw.local (172.27.1.45) To Mcbain.dw.local (172.27.1.45) X-spam-status: No, score=-2.9 required=3.5 tests=ALL_TRUSTED, BAYES_00, MAILSHELL_SCORE_0_4 X-Spam-Flag: NO Subject: [Xen-devel] [XEN PATCH v2 1/2] Check zone before merging adjacent blocks in heap X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Cc: Stefano Stabellini , Julien Grall , Wei Liu , Konrad Rzeszutek Wilk , George Dunlap , Andrew Cooper , Ian Jackson , Jeff Kubascik , Jan Beulich , David Woodhouse Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" From: Jeff Kubascik The Xen heap is split up into nodes and zones. Each node + zone is managed as a separate pool of memory. When returning pages to the heap, free_heap_pages will check adjacent blocks to see if they can be combined into a larger block. However, the zone of the adjacent block is not checked. This results in blocks that migrate from one zone to another. When a block migrates to the adjacent zone, the avail counters for the old and new node + zone is not updated accordingly. The avail counter is used when allocating pages to determine whether to skip over a zone. With this behavior, it is possible for free pages to collect in a zone with the avail counter smaller than the actual page count, resulting in free pages that are not allocable. This commit adds a check to compare the adjacent block's zone with the current zone before merging them. Signed-off-by: Jeff Kubascik Signed-off-by: Stewart Hildebrand --- v2: s/pg-mask/predecessor/ --- xen/common/page_alloc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/xen/common/page_alloc.c b/xen/common/page_alloc.c index 97902d42c1..735049fe3e 100644 --- a/xen/common/page_alloc.c +++ b/xen/common/page_alloc.c @@ -1462,6 +1462,7 @@ static void free_heap_pages( if ( !mfn_valid(page_to_mfn(predecessor)) || !page_state_is(predecessor, free) || (PFN_ORDER(predecessor) != order) || + (page_to_zone(predecessor) != zone) || (phys_to_nid(page_to_maddr(predecessor)) != node) ) break; @@ -1485,6 +1486,7 @@ static void free_heap_pages( if ( !mfn_valid(page_to_mfn(successor)) || !page_state_is(successor, free) || (PFN_ORDER(successor) != order) || + (page_to_zone(successor) != zone) || (phys_to_nid(page_to_maddr(successor)) != node) ) break; From patchwork Tue Feb 4 15:14:41 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stewart Hildebrand X-Patchwork-Id: 11364833 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 27188139A for ; Tue, 4 Feb 2020 15:16:19 +0000 (UTC) Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 0D76020730 for ; Tue, 4 Feb 2020 15:16:18 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 0D76020730 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=dornerworks.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1iyzuh-0007cP-W4; Tue, 04 Feb 2020 15:14:55 +0000 Received: from us1-rack-iad1.inumbo.com ([172.99.69.81]) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1iyzug-0007cB-Ar for xen-devel@lists.xenproject.org; Tue, 04 Feb 2020 15:14:54 +0000 X-Inumbo-ID: 15dbd4a0-4761-11ea-b211-bc764e2007e4 Received: from webmail.dornerworks.com (unknown [12.207.209.150]) by us1-rack-iad1.inumbo.com (Halon) with ESMTP id 15dbd4a0-4761-11ea-b211-bc764e2007e4; Tue, 04 Feb 2020 15:14:50 +0000 (UTC) From: Stewart Hildebrand To: Date: Tue, 4 Feb 2020 10:14:41 -0500 Message-ID: <20200204151441.10626-2-stewart.hildebrand@dornerworks.com> X-Mailer: git-send-email 2.25.0 In-Reply-To: <20200204151441.10626-1-stewart.hildebrand@dornerworks.com> References: <20200204151441.10626-1-stewart.hildebrand@dornerworks.com> MIME-Version: 1.0 X-Originating-IP: [172.27.13.130] X-ClientProxiedBy: Mcbain.dw.local (172.27.1.45) To Mcbain.dw.local (172.27.1.45) X-spam-status: No, score=-2.9 required=3.5 tests=ALL_TRUSTED, BAYES_00, MAILSHELL_SCORE_0_4 X-Spam-Flag: NO Subject: [Xen-devel] [DO NOT APPLY XEN PATCH v2 2/2] Test case for buddy allocator merging issue X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Cc: Stefano Stabellini , Julien Grall , Wei Liu , Konrad Rzeszutek Wilk , George Dunlap , Andrew Cooper , Ian Jackson , Jan Beulich , David Woodhouse Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" Do not apply this patch - it is intended as a test case to show how the problem presents itself. This was tested on a Xiling Zynq UltraScale+ MPSoC with CONFIG_DEBUG=y. Add an assert for merging pages across zones Revert "Check zone before merging adjacent blocks in heap" Revert "xen/page_alloc: Keep away MFN 0 from the buddy allocator" This reverts commit 762b9a2d990bba1f3aefe660cff0c37ad2e375bc. With this test case patch applied, Xen crashes very early in the boot process: - UART enabled - - Boot CPU booting - - Current EL 00000008 - - Initialize CPU - - Turning on paging - - Zero BSS - - Ready - (XEN) Checking for initrd in /chosen (XEN) RAM: 0000000000000000 - 000000007fffffff (XEN) (XEN) MODULE[0]: 0000000000080000 - 00000000001c28f0 Xen (XEN) MODULE[1]: 0000000000280000 - 0000000000288000 Device Tree (XEN) MODULE[2]: 0000000000300000 - 0000000001371200 Kernel (XEN) RESVD[0]: 0000000000280000 - 0000000000288000 (XEN) (XEN) (XEN) Command line: console=dtuart dtuart=/amba/serial@ff000000 dom0_mem=1024M bootscrub=0 loglvl=all/all guest_loglvl=info/all (XEN) Assertion 'page_to_zone(predecessor) == zone' failed at page_alloc.c:1468 (XEN) ----[ Xen-4.14-unstable arm64 debug=y Not tainted ]---- (XEN) CPU: 0 (XEN) PC: 000000000021b4dc page_alloc.c#free_heap_pages+0x34c/0x6a8 (XEN) LR: 000000000021b6cc (XEN) SP: 00000000002ffcd0 (XEN) CPSR: 200003c9 MODE:64-bit EL2h (Hypervisor, handler) (XEN) X0: 0000000000000040 X1: 0000000000000001 X2: 0180000000000000 (XEN) X3: ffffffffffffffff X4: 0000000000000000 X5: 0000000000000000 (XEN) X6: 0000000000000080 X7: 0000000000000001 X8: 0000000000000001 (XEN) X9: 0000000000000000 X10: 0000000000000001 X11: 0080000000000000 (XEN) X12: 0180000000000000 X13: 00000000002ad4b8 X14: 0000000000000000 (XEN) X15: 0000000047ffffff X16: 00000000002ad000 X17: 00000000002ad000 (XEN) X18: 00000000002ad000 X19: 0000000800000000 X20: 0000000000000001 (XEN) X21: 0000000800000070 X22: 0000000000000002 X23: 00000000002ad4b8 (XEN) X24: 6db6db6db6db6db7 X25: 00000000002ad000 X26: 0000000000200200 (XEN) X27: 0000000000100100 X28: 0000000000000000 FP: 00000000002ffcd0 (XEN) (XEN) VTCR_EL2: 80000210 (XEN) VTTBR_EL2: 0000000106044200 (XEN) (XEN) SCTLR_EL2: 30cd183d (XEN) HCR_EL2: 000000000000003a (XEN) TTBR0_EL2: 00000000001bc000 (XEN) (XEN) ESR_EL2: f2000001 (XEN) HPFAR_EL2: 00000000c8082a90 (XEN) FAR_EL2: 3238095901188162 (XEN) (XEN) Xen stack trace from sp=00000000002ffcd0: (XEN) 00000000002ffd40 000000000021db0c 000000000030ad08 00000008000000a8 (XEN) 0000000000000003 0000000000000080 00000000002ad488 0000000800000000 (XEN) 0000000000000000 0000000000000001 0000000000000000 6db6db6db6db6db7 (XEN) 00000000002ab0c8 00000000002c4030 00000000002ffdb0 00000000002b0c1c (XEN) 0000000000000000 0000000001371200 0000000080000000 00000000002e03c0 (XEN) ffffffffffffffff 00000000002e03d8 00000000002e03d0 0000000000000000 (XEN) 0000000080000000 0000000000000001 ffffffffffffffff 000000000030ad58 (XEN) 00000000002ffde0 00000000002c403c 0000000000080000 0000000001371200 (XEN) 0000000080000000 00000000002e03c0 000000007def3c00 00000000002001b8 (XEN) 0000000000080000 ffffffffffe80000 0000000000280000 0000000000000000 (XEN) 0000000000400000 000000007ff9c250 0000000000080040 0000000000000000 (XEN) 0000000000000400 0000000000080000 0000000000000000 0000000000008000 (XEN) 0000000000280000 0000000080000000 00000000002e03c0 00000000002b026c (XEN) 0000000000000000 0000000000000000 0000000000000000 0000000300000000 (XEN) 0000000000000000 00000040ffffffff 00000000ffffffff 0000000000000000 (XEN) 0000000000000000 0000000000000000 0000000000000000 0000000000000000 (XEN) 0000000000000000 0000000000000000 0000000000000000 0000000000000000 (XEN) 0000000000000000 0000000000000000 0000000000000000 0000000000000000 (XEN) 0000000000000000 0000000000000000 0000000000000000 0000000000000000 (XEN) 0000000000000000 0000000000000000 0000000000000000 0000000000000000 (XEN) 0000000000000000 0000000000000000 0000000000000000 0000000000000000 (XEN) 0000000000000000 0000000000000000 0000000000000000 0000000000000000 (XEN) 0000000000000000 0000000000000000 0000000000000000 0000000000000000 (XEN) 0000000000000000 0000000000000000 0000000000000000 0000000000000000 (XEN) 0000000000000000 0000000000000000 0000000000000000 0000000000000000 (XEN) 0000000000000000 0000000000000000 (XEN) Xen call trace: (XEN) [<000000000021b4dc>] page_alloc.c#free_heap_pages+0x34c/0x6a8 (PC) (XEN) [<000000000021b6cc>] page_alloc.c#free_heap_pages+0x53c/0x6a8 (LR) (XEN) [<000000000021db0c>] page_alloc.c#init_heap_pages+0x344/0x504 (XEN) [<00000000002b0c1c>] end_boot_allocator+0xa8/0x19c (XEN) [<00000000002c403c>] start_xen+0x3b4/0xc4c (XEN) [<00000000002001b8>] arm64/head.o#primary_switched+0x10/0x30 (XEN) (XEN) (XEN) **************************************** (XEN) Panic on CPU 0: (XEN) Assertion 'page_to_zone(predecessor) == zone' failed at page_alloc.c:1468 (XEN) **************************************** (XEN) (XEN) Reboot in five seconds... --- xen/common/page_alloc.c | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/xen/common/page_alloc.c b/xen/common/page_alloc.c index 735049fe3e..cb65668736 100644 --- a/xen/common/page_alloc.c +++ b/xen/common/page_alloc.c @@ -1462,10 +1462,11 @@ static void free_heap_pages( if ( !mfn_valid(page_to_mfn(predecessor)) || !page_state_is(predecessor, free) || (PFN_ORDER(predecessor) != order) || - (page_to_zone(predecessor) != zone) || (phys_to_nid(page_to_maddr(predecessor)) != node) ) break; + ASSERT(page_to_zone(predecessor) == zone); + check_and_stop_scrub(predecessor); page_list_del(predecessor, &heap(node, zone, order)); @@ -1486,10 +1487,11 @@ static void free_heap_pages( if ( !mfn_valid(page_to_mfn(successor)) || !page_state_is(successor, free) || (PFN_ORDER(successor) != order) || - (page_to_zone(successor) != zone) || (phys_to_nid(page_to_maddr(successor)) != node) ) break; + ASSERT(page_to_zone(successor) == zone); + check_and_stop_scrub(successor); /* Update pg's first_dirty if necessary. */ @@ -1773,18 +1775,6 @@ static void init_heap_pages( unsigned long i; bool idle_scrub = false; - /* - * Keep MFN 0 away from the buddy allocator to avoid crossing zone - * boundary when merging two buddies. - */ - if ( !mfn_x(page_to_mfn(pg)) ) - { - if ( nr_pages-- <= 1 ) - return; - pg++; - } - - /* * Some pages may not go through the boot allocator (e.g reserved * memory at boot but released just after --- kernel, initramfs,