[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] Linux 4.4 boot crash on xen 4.5.3 with dom0_mem == max



I added some more instrumentation and discovered that the result of
xen_count_remap_pages() (0x85dea) is one less than the actual number
of pages remapped by xen_set_identity_and_remap() (0x85deb).

The two functions differ in their handling of a xen_e820_map entry
whose size is not a multiple of the page size.  The entry starting at
0x68000 has size 0x33400.  xen_count_remap_pages() rounds up when
computing the end_pfn (to 0x9c), while xen_set_identity_and_remap()
rounds down (to 0x9b).  Thus xen_count_remap_pages() counts the
remapped space following the entry as one page smaller than the other
function does.

(Confusingly, the "BIOS-provided physical RAM map" shows both the
start and end addresses rounded down to page boundaries, rather than
the addresses actually provided by the BIOS.)

[    0.000000] xen_count_remap_pages i=0 addr=0x0 size=0x60000 start_pfn=0x0 
end_pfn=0x0
[    0.000000] xen_count_remap_pages i=0 plus end_pfn=0x60 type=0x1
[    0.000000] xen_count_remap_pages i=1 addr=0x60000 size=0x8000 
start_pfn=0x60 end_pfn=0x60
[    0.000000] xen_count_remap_pages i=1 plus end_pfn=0x68 type=0x2
[    0.000000] xen_count_remap_pages i=2 addr=0x68000 size=0x33400 
start_pfn=0x68 end_pfn=0x68
[    0.000000] xen_count_remap_pages i=2 plus end_pfn=0x9c type=0x1
[    0.000000] xen_count_remap_pages i=3 addr=0x100000 size=0x759fe000 
start_pfn=0x100 end_pfn=0x9c
[    0.000000] xen_count_remap_pages i=3 plus end_pfn=0x75afe type=0x1
[    0.000000] xen_count_remap_pages i=4 addr=0x75bab000 size=0x464b000 
start_pfn=0x75bab end_pfn=0x75afe
[    0.000000] xen_count_remap_pages i=4 plus end_pfn=0x7a1f6 type=0x1
[    0.000000] xen_count_remap_pages i=5 addr=0x7b7d7000 size=0x29000 
start_pfn=0x7b7d7 end_pfn=0x7a1f6
[    0.000000] xen_count_remap_pages i=5 plus end_pfn=0x7b800 type=0x1
[    0.000000] xen_count_remap_pages i=6 addr=0x7bf00000 size=0x100000 
start_pfn=0x7bf00 end_pfn=0x7b800
[    0.000000] xen_count_remap_pages i=6 plus end_pfn=0x7c000 type=0x1
[    0.000000] xen_count_remap_pages i=7 addr=0xc7ffc000 size=0x1000 
start_pfn=0xc7ffc end_pfn=0x7c000
[    0.000000] xen_count_remap_pages i=7 plus end_pfn=0xc7ffd type=0x2
[    0.000000] xen_count_remap_pages i=8 addr=0xfbffc000 size=0x1000 
start_pfn=0xfbffc end_pfn=0xc7ffd
[    0.000000] xen_count_remap_pages i=8 plus end_pfn=0xfbffd type=0x2
[    0.000000] xen_count_remap_pages i=9 addr=0xfec00000 size=0x2000 
start_pfn=0xfec00 end_pfn=0xfbffd
[    0.000000] xen_count_remap_pages i=9 plus end_pfn=0xfec02 type=0x2
[    0.000000] xen_count_remap_pages i=10 addr=0xfec40000 size=0x1000 
start_pfn=0xfec40 end_pfn=0xfec02
[    0.000000] xen_count_remap_pages i=10 plus end_pfn=0xfec41 type=0x2
[    0.000000] xen_count_remap_pages i=11 addr=0xfed20000 size=0x10000 
start_pfn=0xfed20 end_pfn=0xfec41
[    0.000000] xen_count_remap_pages i=11 plus end_pfn=0xfed30 type=0x1
[    0.000000] xen_count_remap_pages i=12 addr=0xfee00000 size=0x100000 
start_pfn=0xfee00 end_pfn=0xfed30
[    0.000000] xen_count_remap_pages i=12 plus end_pfn=0xfef00 type=0x2
[    0.000000] xen_count_remap_pages i=13 addr=0x100000000 size=0x1f80000000 
start_pfn=0x100000 end_pfn=0xfef00
[    0.000000] xen_count_remap_pages i=13 plus end_pfn=0x480000 type=0x1
[    0.000000] xen_count_remap_pages(max_pfn=0x480000) == 0x85dea
[    0.000000] max_pages 0x505dea
[    0.000000] xen_add_extra_mem(480000, 85dea)
[    0.000000] memblock_reserve(0x480000000, 0x85dea000)
[    0.000000] xen_set_identity_and_remap i=0 addr=0x0 size=0x60000 type=0x1
[    0.000000] xen_set_identity_and_remap i=1 addr=0x60000 size=0x8000 type=0x2
[    0.000000] xen_set_identity_and_remap i=2 addr=0x68000 size=0x33400 type=0x1
[    0.000000] xen_set_identity_and_remap_chunk start_pfn=0x60 end_pfn=0x68 
nr_pages=0x480000 remap_pfn=0x480000
[    0.000000] xen_set_identity_and_remap_chunk i=0x0 cur_pfn=0x60 left=0x8 
size=0x8 remap_range_size=0x1c00000
[    0.000000] xen_set_identity_and_remap i=3 addr=0x100000 size=0x759fe000 
type=0x1
[    0.000000] xen_set_identity_and_remap_chunk start_pfn=0x9b end_pfn=0x100 
nr_pages=0x480000 remap_pfn=0x480008
[    0.000000] xen_set_identity_and_remap_chunk i=0x0 cur_pfn=0x9b left=0x65 
size=0x65 remap_range_size=0x1bffff8
[    0.000000] xen_set_identity_and_remap i=4 addr=0x75bab000 size=0x464b000 
type=0x1
[    0.000000] xen_set_identity_and_remap_chunk start_pfn=0x75afe 
end_pfn=0x75bab nr_pages=0x480000 remap_pfn=0x48006d
[    0.000000] xen_set_identity_and_remap_chunk i=0x0 cur_pfn=0x75afe left=0xad 
size=0xad remap_range_size=0x1bfff93
[    0.000000] xen_set_identity_and_remap i=5 addr=0x7b7d7000 size=0x29000 
type=0x1
[    0.000000] xen_set_identity_and_remap_chunk start_pfn=0x7a1f6 
end_pfn=0x7b7d7 nr_pages=0x480000 remap_pfn=0x48011a
[    0.000000] xen_set_identity_and_remap_chunk i=0x0 cur_pfn=0x7a1f6 
left=0x15e1 size=0x15e1 remap_range_size=0x1bffee6
[    0.000000] xen_set_identity_and_remap i=6 addr=0x7bf00000 size=0x100000 
type=0x1
[    0.000000] xen_set_identity_and_remap_chunk start_pfn=0x7b800 
end_pfn=0x7bf00 nr_pages=0x480000 remap_pfn=0x4816fb
[    0.000000] xen_set_identity_and_remap_chunk i=0x0 cur_pfn=0x7b800 
left=0x700 size=0x700 remap_range_size=0x1bfe905
[    0.000000] xen_set_identity_and_remap i=7 addr=0xc7ffc000 size=0x1000 
type=0x2
[    0.000000] xen_set_identity_and_remap i=8 addr=0xfbffc000 size=0x1000 
type=0x2
[    0.000000] xen_set_identity_and_remap i=9 addr=0xfec00000 size=0x2000 
type=0x2
[    0.000000] xen_set_identity_and_remap i=10 addr=0xfec40000 size=0x1000 
type=0x2
[    0.000000] xen_set_identity_and_remap i=11 addr=0xfed20000 size=0x10000 
type=0x1
[    0.000000] xen_set_identity_and_remap_chunk start_pfn=0x7c000 
end_pfn=0xfed20 nr_pages=0x480000 remap_pfn=0x481dfb
[    0.000000] xen_set_identity_and_remap_chunk i=0x0 cur_pfn=0x7c000 
left=0x82d20 size=0x82d20 remap_range_size=0x1bfe205
[    0.000000] xen_set_identity_and_remap i=12 addr=0xfee00000 size=0x100000 
type=0x2
[    0.000000] xen_set_identity_and_remap i=13 addr=0x100000000 
size=0x1f80000000 type=0x1
[    0.000000] xen_set_identity_and_remap_chunk start_pfn=0xfed30 
end_pfn=0x100000 nr_pages=0x480000 remap_pfn=0x504b1b
[    0.000000] xen_set_identity_and_remap_chunk i=0x0 cur_pfn=0xfed30 
left=0x12d0 size=0x12d0 remap_range_size=0x1b7b4e5
[    0.000000] Released 0 page(s)
[    0.000000] e820: BIOS-provided physical RAM map:
[    0.000000] Xen: [mem 0x0000000000000000-0x000000000005ffff] usable
[    0.000000] Xen: [mem 0x0000000000060000-0x0000000000067fff] reserved
[    0.000000] Xen: [mem 0x0000000000068000-0x000000000009afff] usable
[    0.000000] Xen: [mem 0x00000000000a0000-0x00000000000fffff] reserved
[    0.000000] Xen: [mem 0x0000000000100000-0x0000000075afdfff] usable
[    0.000000] Xen: [mem 0x0000000075bab000-0x000000007a1f5fff] usable
[    0.000000] Xen: [mem 0x000000007b7d7000-0x000000007b7fffff] usable
[    0.000000] Xen: [mem 0x000000007bf00000-0x000000007bffffff] usable
[    0.000000] Xen: [mem 0x00000000c7ffc000-0x00000000c7ffcfff] reserved
[    0.000000] Xen: [mem 0x00000000fbffc000-0x00000000fbffcfff] reserved
[    0.000000] Xen: [mem 0x00000000fec00000-0x00000000fec01fff] reserved
[    0.000000] Xen: [mem 0x00000000fec40000-0x00000000fec40fff] reserved
[    0.000000] Xen: [mem 0x00000000fed20000-0x00000000fed2ffff] usable
[    0.000000] Xen: [mem 0x00000000fee00000-0x00000000feefffff] reserved
[    0.000000] Xen: [mem 0x0000000100000000-0x0000000505de9fff] usable
[    0.000000] bootconsole [xenboot0] enabled
[    0.000000] debug: ignoring loglevel setting.
[    0.000000] NX (Execute Disable) protection: active
[    0.000000] e820: user-defined physical RAM map:
[    0.000000] user: [mem 0x0000000000000000-0x000000000005ffff] usable
[    0.000000] user: [mem 0x0000000000060000-0x0000000000067fff] reserved
[    0.000000] user: [mem 0x0000000000068000-0x000000000009afff] usable
[    0.000000] user: [mem 0x00000000000a0000-0x00000000000fffff] reserved
[    0.000000] user: [mem 0x0000000000100000-0x0000000075afdfff] usable
[    0.000000] user: [mem 0x0000000075bab000-0x000000007a1f5fff] usable
[    0.000000] user: [mem 0x000000007b7d7000-0x000000007b7fffff] usable
[    0.000000] user: [mem 0x000000007bf00000-0x000000007bffffff] usable
[    0.000000] user: [mem 0x0000000080000000-0x000000008fffffff] reserved
[    0.000000] user: [mem 0x00000000c7ffc000-0x00000000c7ffcfff] reserved
[    0.000000] user: [mem 0x00000000fbffc000-0x00000000fbffcfff] reserved
[    0.000000] user: [mem 0x00000000fec00000-0x00000000fec01fff] reserved
[    0.000000] user: [mem 0x00000000fec40000-0x00000000fec40fff] reserved
[    0.000000] user: [mem 0x00000000fed20000-0x00000000fed2ffff] usable
[    0.000000] user: [mem 0x00000000fee00000-0x00000000feefffff] reserved
[    0.000000] user: [mem 0x0000000100000000-0x0000000505de9fff] usable

It seems to me we'd be better off with just one function counting
remapped pages rather than two, so as an experiment I tried combining
them.  The patch below adds a do_remap argument to
xen_set_identity_and_remap() that tells it whether to do the actual
remapping or just return the number pages that would be remapped.
This change fixes the crash on my system.

diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c
index 7ab2951..2746b7b 100644
--- a/arch/x86/xen/setup.c
+++ b/arch/x86/xen/setup.c
@@ -438,11 +438,13 @@ static unsigned long __init 
xen_set_identity_and_remap_chunk(
        return remap_pfn;
 }
 
-static void __init xen_set_identity_and_remap(unsigned long nr_pages)
+static unsigned long __init xen_set_identity_and_remap(unsigned long nr_pages,
+                                             int do_remap)
 {
        phys_addr_t start = 0;
        unsigned long last_pfn = nr_pages;
        const struct e820entry *entry = xen_e820_map;
+       unsigned long remap_pages = 0;
        int i;
 
        /*
@@ -465,15 +467,21 @@ static void __init xen_set_identity_and_remap(unsigned 
long nr_pages)
                        if (entry->type == E820_RAM)
                                end_pfn = PFN_UP(entry->addr);
 
-                       if (start_pfn < end_pfn)
-                               last_pfn = xen_set_identity_and_remap_chunk(
-                                               start_pfn, end_pfn, nr_pages,
-                                               last_pfn);
+                       if (start_pfn < end_pfn) {
+                               if (do_remap)
+                                       last_pfn = 
xen_set_identity_and_remap_chunk(
+                                                       start_pfn, end_pfn, 
nr_pages,
+                                                       last_pfn);
+                               remap_pages += end_pfn - start_pfn;
+                       }
                        start = end;
                }
        }
 
-       pr_info("Released %ld page(s)\n", xen_released_pages);
+       if (do_remap)
+               pr_info("Released %ld page(s)\n", xen_released_pages);
+
+       return remap_pages;
 }
 
 /*
@@ -596,35 +604,6 @@ static void __init xen_ignore_unusable(void)
        }
 }
 
-static unsigned long __init xen_count_remap_pages(unsigned long max_pfn)
-{
-       unsigned long extra = 0;
-       unsigned long start_pfn, end_pfn;
-       const struct e820entry *entry = xen_e820_map;
-       int i;
-
-       end_pfn = 0;
-       for (i = 0; i < xen_e820_map_entries; i++, entry++) {
-               start_pfn = PFN_DOWN(entry->addr);
-               /* Adjacent regions on non-page boundaries handling! */
-               end_pfn = min(end_pfn, start_pfn);
-
-               if (start_pfn >= max_pfn)
-                       return extra + max_pfn - end_pfn;
-
-               /* Add any holes in map to result. */
-               extra += start_pfn - end_pfn;
-
-               end_pfn = PFN_UP(entry->addr + entry->size);
-               end_pfn = min(end_pfn, max_pfn);
-
-               if (entry->type != E820_RAM)
-                       extra += end_pfn - start_pfn;
-       }
-
-       return extra;
-}
-
 bool __init xen_is_e820_reserved(phys_addr_t start, phys_addr_t size)
 {
        struct e820entry *entry;
@@ -804,7 +783,7 @@ char * __init xen_memory_setup(void)
        max_pages = xen_get_max_pages();
 
        /* How many extra pages do we need due to remapping? */
-       max_pages += xen_count_remap_pages(max_pfn);
+       max_pages += xen_set_identity_and_remap(max_pfn, 0);
 
        if (max_pages > max_pfn)
                extra_pages += max_pages - max_pfn;
@@ -922,7 +901,7 @@ char * __init xen_memory_setup(void)
         * Set identity map on non-RAM pages and prepare remapping the
         * underlying RAM.
         */
-       xen_set_identity_and_remap(max_pfn);
+       xen_set_identity_and_remap(max_pfn, 1);
 
        return "Xen";
 }

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.