lkml.org 
[lkml]   [2008]   [Jan]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    SubjectRe: bugreport kernel panic on early stage, with HIGHMEM4G:

    * Denys Fedoryshchenko <denys@visp.net.lb> wrote:

    > Hi
    >
    > After physical memory upgrade from 3GB to 4GB (also it happens on 5GB)
    > got kernel panic.
    >
    > Because it is happening on early stage and my machine doesn't contain
    > serial port, i had to take photo. Kernel boots fine with 64GB highmem,
    > no highmem, or highmem4G with limited memory by mem=3G. All dmesg
    > attached. Also i attach dmidecode and lspci -vvv output, probably it
    > will be useful.

    thanks for the detailed report, i think i know what's going on. Could
    you try the patch below, does it fix your problem?

    this seems to be a SPARSEMEM bug which is present in v2.6.23 as well and
    has probably been present ever since SPARSEMEM was added to 32-bit x86.

    There's a ~256MB hole in your e820 memory map (the pci aperture), which
    causes the last 4 sparsemem sections (each covering 64MB of RAM) to be
    not present - and they are thus missing from the sparsemem mem_map[]
    too. The highmem init code on the other hand assumes that all pages are
    in the mem_map[]:

    static void __init set_highmem_pages_init(int bad_ppro)
    {
    int pfn;
    for (pfn = highstart_pfn; pfn < highend_pfn; pfn++)
    add_one_highpage_init(pfn_to_page(pfn), pfn, bad_ppro);

    the pfn_to_page() is unconditional and dereferences to a NULL-ish
    pointer which crashes your box. highend_pfn is what got miscalculated by
    256 MB, so set_highmem_pages_init() tried to reference a non-existing
    struct page - but it should still be robust enough against non-existent
    pages.

    The patch below fixes this bug. Please also send a dmesg if you manage
    to boot the box up fine, i've added a few debug printouts to confirm
    this theory. (i'll figure out whether we need to clip highend_pfn as
    well - but this patch alone should be good enough to fix the crash on
    your box.)

    Ingo

    ------------->
    Subject: x86: fix CONFIG_SPARSEMEM highmem init bug
    From: Ingo Molnar <mingo@elte.hu>

    fix CONFIG_SPARSEMEM highmem init bug.

    Signed-off-by: Ingo Molnar <mingo@elte.hu>
    ---
    arch/x86/mm/init_32.c | 43 ++++++++++++++++++++++++++++++++++++++++---
    mm/sparse.c | 8 +++++++-
    2 files changed, 47 insertions(+), 4 deletions(-)

    Index: linux/arch/x86/mm/init_32.c
    ===================================================================
    --- linux.orig/arch/x86/mm/init_32.c
    +++ linux/arch/x86/mm/init_32.c
    @@ -321,11 +321,48 @@ extern void set_highmem_pages_init(int);
    static void __init set_highmem_pages_init(int bad_ppro)
    {
    int pfn;
    - for (pfn = highstart_pfn; pfn < highend_pfn; pfn++)
    - add_one_highpage_init(pfn_to_page(pfn), pfn, bad_ppro);
    +
    + printk("set_highmem_pages_init(bad_ppro:%d)\n", bad_ppro);
    + printk("sizeof(struct page): %d\n", sizeof(struct page));
    + printk("sizeof(struct mem_section): %d\n", sizeof(struct mem_section));
    + printk("PFN_SECTION_SHIFT: %d\n", PFN_SECTION_SHIFT);
    +
    + printk("mem_map: %p\n", mem_map);
    + printk(" highstart_pfn: %9ld [page: %p]\n",
    + highstart_pfn, pfn_to_page(highstart_pfn));
    + printk(" highend_pfn: %9ld [page: %p]\n",
    + highend_pfn, pfn_to_page(highend_pfn));
    + printk(" highend_pfn-1: %9ld [page: %p]\n",
    + highend_pfn-1, pfn_to_page(highend_pfn-1));
    +
    + printk("NR_MEM_SECTIONS: %ld\n", NR_MEM_SECTIONS);
    + printk("pfn_to_section_nr(highstart_pfn): %9ld\n",
    + pfn_to_section_nr(highstart_pfn));
    + printk("pfn_to_section_nr(highend_pfn): %9ld\n",
    + pfn_to_section_nr(highend_pfn));
    + printk("pfn_to_section_nr(highend_pfn-1): %9ld\n",
    + pfn_to_section_nr(highend_pfn-1));
    +
    + printk("totalhigh_pages: %9ld\n", totalhigh_pages);
    + printk(" totalram_pages: %9ld\n", totalram_pages);
    +
    + for (pfn = highstart_pfn; pfn < highend_pfn; pfn++) {
    + if (pfn_valid(pfn))
    + add_one_highpage_init(pfn_to_page(pfn), pfn, bad_ppro);
    + else {
    + if (WARN_ON_ONCE(1)) {
    + printk("bad pfn: %d\n", pfn);
    + break;
    + }
    + }
    + }
    + printk("totalhigh_pages: %9ld\n", totalhigh_pages);
    + printk(" totalram_pages: %9ld\n", totalram_pages);
    +
    +
    totalram_pages += totalhigh_pages;
    }
    -#endif /* CONFIG_FLATMEM */
    +#endif /* CONFIG_NUMA */

    #else
    #define kmap_init() do { } while (0)
    Index: linux/mm/sparse.c
    ===================================================================
    --- linux.orig/mm/sparse.c
    +++ linux/mm/sparse.c
    @@ -295,9 +295,13 @@ void __init sparse_init(void)
    struct page *map;
    unsigned long *usemap;

    + printk("sparse_init()\n");
    for (pnum = 0; pnum < NR_MEM_SECTIONS; pnum++) {
    - if (!present_section_nr(pnum))
    + printk("section %2ld: ", pnum);
    + if (!present_section_nr(pnum)) {
    + printk("!present\n");
    continue;
    + }

    map = sparse_early_mem_map_alloc(pnum);
    if (!map)
    @@ -309,6 +313,8 @@ void __init sparse_init(void)

    sparse_init_one_section(__nr_to_section(pnum), pnum, map,
    usemap);
    + printk("map: %p, usemap: %p [content: %08lx]\n",
    + map, usemap, __nr_to_section(pnum)->section_mem_map);
    }
    }



    \
     
     \ /
      Last update: 2008-01-15 12:43    [W:0.036 / U:0.320 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site