All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ingo Molnar <mingo@elte.hu>
To: Denys Fedoryshchenko <denys@visp.net.lb>
Cc: linux-kernel@vger.kernel.org,
	Andrew Morton <akpm@linux-foundation.org>,
	Thomas Gleixner <tglx@linutronix.de>,
	"H. Peter Anvin" <hpa@zytor.com>, Mel Gorman <mel@csn.ul.ie>
Subject: Re: bugreport kernel panic on early stage, with HIGHMEM4G:
Date: Tue, 15 Jan 2008 12:39:47 +0100	[thread overview]
Message-ID: <20080115113947.GA14603@elte.hu> (raw)
In-Reply-To: <20080107053908.M5584@visp.net.lb>


* 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);
 	}
 }
 


  reply	other threads:[~2008-01-15 11:40 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-01-07  5:47 bugreport kernel panic on early stage, with HIGHMEM4G: Denys Fedoryshchenko
2008-01-15 11:39 ` Ingo Molnar [this message]
2008-01-15 13:13   ` Ingo Molnar
2008-01-17 12:26     ` Mel Gorman
2008-01-17 13:31   ` Denys Fedoryshchenko
  -- strict thread matches above, loose matches on Subject: below --
2008-01-07  6:30 Denys Fedoryshchenko

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20080115113947.GA14603@elte.hu \
    --to=mingo@elte.hu \
    --cc=akpm@linux-foundation.org \
    --cc=denys@visp.net.lb \
    --cc=hpa@zytor.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mel@csn.ul.ie \
    --cc=tglx@linutronix.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.