diff mbox series

[DO,NOT,APPLY,XEN,v2,2/2] Test case for buddy allocator merging issue

Message ID 20200204151441.10626-2-stewart.hildebrand@dornerworks.com (mailing list archive)
State New, archived
Headers show
Series [XEN,v2,1/2] Check zone before merging adjacent blocks in heap | expand

Commit Message

Stewart Hildebrand Feb. 4, 2020, 3:14 p.m. UTC
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 mbox series

Patch

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,