mm: clean up for early_pfn_to_nid()
authorKAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Wed, 18 Feb 2009 22:48:32 +0000 (14:48 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 18 Feb 2009 23:37:55 +0000 (15:37 -0800)
commitf2dbcfa738368c8a40d4a5f0b65dc9879577cb21
treebdea32c637fa572a9c356cddd202a57530b2a45c
parentada723dcd681e2dffd7d73345cc8fda0eb0df9bd
mm: clean up for early_pfn_to_nid()

What's happening is that the assertion in mm/page_alloc.c:move_freepages()
is triggering:

BUG_ON(page_zone(start_page) != page_zone(end_page));

Once I knew this is what was happening, I added some annotations:

if (unlikely(page_zone(start_page) != page_zone(end_page))) {
printk(KERN_ERR "move_freepages: Bogus zones: "
       "start_page[%p] end_page[%p] zone[%p]\n",
       start_page, end_page, zone);
printk(KERN_ERR "move_freepages: "
       "start_zone[%p] end_zone[%p]\n",
       page_zone(start_page), page_zone(end_page));
printk(KERN_ERR "move_freepages: "
       "start_pfn[0x%lx] end_pfn[0x%lx]\n",
       page_to_pfn(start_page), page_to_pfn(end_page));
printk(KERN_ERR "move_freepages: "
       "start_nid[%d] end_nid[%d]\n",
       page_to_nid(start_page), page_to_nid(end_page));
 ...

And here's what I got:

move_freepages: Bogus zones: start_page[2207d0000] end_page[2207dffc0] zone[fffff8103effcb00]
move_freepages: start_zone[fffff8103effcb00] end_zone[fffff8003fffeb00]
move_freepages: start_pfn[0x81f600] end_pfn[0x81f7ff]
move_freepages: start_nid[1] end_nid[0]

My memory layout on this box is:

[    0.000000] Zone PFN ranges:
[    0.000000]   Normal   0x00000000 -> 0x0081ff5d
[    0.000000] Movable zone start PFN for each node
[    0.000000] early_node_map[8] active PFN ranges
[    0.000000]     0: 0x00000000 -> 0x00020000
[    0.000000]     1: 0x00800000 -> 0x0081f7ff
[    0.000000]     1: 0x0081f800 -> 0x0081fe50
[    0.000000]     1: 0x0081fed1 -> 0x0081fed8
[    0.000000]     1: 0x0081feda -> 0x0081fedb
[    0.000000]     1: 0x0081fedd -> 0x0081fee5
[    0.000000]     1: 0x0081fee7 -> 0x0081ff51
[    0.000000]     1: 0x0081ff59 -> 0x0081ff5d

So it's a block move in that 0x81f600-->0x81f7ff region which triggers
the problem.

This patch:

Declaration of early_pfn_to_nid() is scattered over per-arch include
files, and it seems it's complicated to know when the declaration is used.
 I think it makes fix-for-memmap-init not easy.

This patch moves all declaration to include/linux/mm.h

After this,
  if !CONFIG_NODES_POPULATES_NODE_MAP && !CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID
     -> Use static definition in include/linux/mm.h
  else if !CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID
     -> Use generic definition in mm/page_alloc.c
  else
     -> per-arch back end function will be called.

Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Tested-by: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
Reported-by: David Miller <davem@davemlloft.net>
Cc: Mel Gorman <mel@csn.ul.ie>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: <stable@kernel.org> [2.6.25.x, 2.6.26.x, 2.6.27.x, 2.6.28.x]
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
arch/ia64/include/asm/mmzone.h
arch/ia64/mm/numa.c
arch/x86/include/asm/mmzone_32.h
arch/x86/include/asm/mmzone_64.h
arch/x86/mm/numa_64.c
include/linux/mm.h
mm/page_alloc.c