* + mm-fix-memmap-init-to-initialize-valid-memmap-for-memory-hole.patch added to -mm tree
@ 2009-02-05 17:29 akpm
2009-02-06 8:17 ` KAMEZAWA Hiroyuki
0 siblings, 1 reply; 6+ messages in thread
From: akpm @ 2009-02-05 17:29 UTC (permalink / raw)
To: mm-commits; +Cc: kamezawa.hiroyu, davem, heiko.carstens, mel, stable
The patch titled
mm: fix memmap init to initialize valid memmap for memory hole
has been added to the -mm tree. Its filename is
mm-fix-memmap-init-to-initialize-valid-memmap-for-memory-hole.patch
Before you just go and hit "reply", please:
a) Consider who else should be cc'ed
b) Prefer to cc a suitable mailing list as well
c) Ideally: find the original patch on the mailing list and do a
reply-to-all to that, adding suitable additional cc's
*** Remember to use Documentation/SubmitChecklist when testing your code ***
See http://userweb.kernel.org/~akpm/stuff/added-to-mm.txt to find
out what to do about this
The current -mm tree may be found at http://userweb.kernel.org/~akpm/mmotm/
------------------------------------------------------
Subject: mm: fix memmap init to initialize valid memmap for memory hole
From: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
If PFN is not in early_node_map[] then struct page for it is not
initialized. If there are holes within a MAX_ORDER_NE_PAGES range of
pages, then PG_reserved will not be set. Code that walks PFNs within
MAX_ORDER_NR_PAGES will the use uninitialized struct pages.
To avoid any problems, this patch initializes holes within a
MAX_ORDER_NR_PAGES that valid memmap exists but is otherwise unused.
Sayeth davem:
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.
So I did a lot (and I do mean _A LOT_) of digging. And it seems that
unless you set HOLES_IN_ZONE you have to make sure that all of the
memmap regions of free space in a zone begin and end on an HPAGE_SIZE
boundary (the requirement used to be that it had to be MAX_ORDER
sized).
Well, this assumption enterred the tree back in 2005 (!!!) from
the following commit in the history-2.6 tree:
commit 69fba2dd0335abec0b0de9ac53d5bbb67c31fc60
Author: Kamezawa Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Date: Fri Jan 7 22:01:35 2005 -0800
[PATCH] no buddy bitmap patch revisit: for mm/page_alloc.c
Reported-by: David Miller <davem@davemlloft.net>
Acked-by: Mel Gorman <mel@csn.ul.ie>
Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
Cc: <stable@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
---
include/linux/mmzone.h | 6 ------
mm/page_alloc.c | 13 +++++++++++--
2 files changed, 11 insertions(+), 8 deletions(-)
diff -puN include/linux/mmzone.h~mm-fix-memmap-init-to-initialize-valid-memmap-for-memory-hole include/linux/mmzone.h
--- a/include/linux/mmzone.h~mm-fix-memmap-init-to-initialize-valid-memmap-for-memory-hole
+++ a/include/linux/mmzone.h
@@ -1070,12 +1070,6 @@ void sparse_init(void);
#define sparse_index_init(_sec, _nid) do {} while (0)
#endif /* CONFIG_SPARSEMEM */
-#ifdef CONFIG_NODES_SPAN_OTHER_NODES
-#define early_pfn_in_nid(pfn, nid) (early_pfn_to_nid(pfn) == (nid))
-#else
-#define early_pfn_in_nid(pfn, nid) (1)
-#endif
-
#ifndef early_pfn_valid
#define early_pfn_valid(pfn) (1)
#endif
diff -puN mm/page_alloc.c~mm-fix-memmap-init-to-initialize-valid-memmap-for-memory-hole mm/page_alloc.c
--- a/mm/page_alloc.c~mm-fix-memmap-init-to-initialize-valid-memmap-for-memory-hole
+++ a/mm/page_alloc.c
@@ -2633,9 +2633,18 @@ void __meminit memmap_init_zone(unsigned
* exist on hotplugged memory.
*/
if (context == MEMMAP_EARLY) {
+ int nid_from_node_memory_map;
+
if (!early_pfn_valid(pfn))
continue;
- if (!early_pfn_in_nid(pfn, nid))
+ /*
+ * early_pfn_to_nid() returns -1 if the page doesn't
+ * exist in early_node_map[]. Initialize it in force
+ * and set PG_reserved at el.
+ */
+ nid_from_node_memory_map = early_pfn_to_nid(pfn);
+ if (nid_from_node_memory_map > -1 &&
+ nid_from_node_memory_map != nid)
continue;
}
page = pfn_to_page(pfn);
@@ -3002,7 +3011,7 @@ int __meminit early_pfn_to_nid(unsigned
return early_node_map[i].nid;
}
- return 0;
+ return -1;
}
#endif /* CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID */
_
Patches currently in -mm which might be from kamezawa.hiroyu@jp.fujitsu.com are
origin.patch
linux-next.patch
mm-fix-memmap-init-to-initialize-valid-memmap-for-memory-hole.patch
proc-pid-maps-dont-show-pgoff-of-pure-anon-vmas.patch
proc-pid-maps-dont-show-pgoff-of-pure-anon-vmas-checkpatch-fixes.patch
cgroup-css-id-support.patch
cgroup-fix-frequent-ebusy-at-rmdir.patch
memcg-use-css-id.patch
memcg-hierarchical-stat.patch
memcg-fix-shrinking-memory-to-return-ebusy-by-fixing-retry-algorithm.patch
memcg-fix-oom-killer-under-memcg.patch
memcg-fix-oom-killer-under-memcg-fix2.patch
memcg-fix-oom-killer-under-memcg-fix.patch
memcg-show-memcg-information-during-oom.patch
memcg-show-memcg-information-during-oom-fix2.patch
memcg-show-memcg-information-during-oom-fix.patch
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: + mm-fix-memmap-init-to-initialize-valid-memmap-for-memory-hole.patch added to -mm tree
2009-02-05 17:29 + mm-fix-memmap-init-to-initialize-valid-memmap-for-memory-hole.patch added to -mm tree akpm
@ 2009-02-06 8:17 ` KAMEZAWA Hiroyuki
2009-02-06 9:55 ` [BUGFIX][PATCH] Aditional fix for memmap initalization KAMEZAWA Hiroyuki
0 siblings, 1 reply; 6+ messages in thread
From: KAMEZAWA Hiroyuki @ 2009-02-06 8:17 UTC (permalink / raw)
To: linux-kernel; +Cc: akpm, mm-commits, davem, heiko.carstens, mel, stable
On Thu, 05 Feb 2009 09:29:54 -0800
akpm@linux-foundation.org wrote:
>
> The patch titled
> mm: fix memmap init to initialize valid memmap for memory hole
> has been added to the -mm tree. Its filename is
> mm-fix-memmap-init-to-initialize-valid-memmap-for-memory-hole.patch
>
> Before you just go and hit "reply", please:
> a) Consider who else should be cc'ed
> b) Prefer to cc a suitable mailing list as well
> c) Ideally: find the original patch on the mailing list and do a
> reply-to-all to that, adding suitable additional cc's
>
> *** Remember to use Documentation/SubmitChecklist when testing your code ***
>
> See http://userweb.kernel.org/~akpm/stuff/added-to-mm.txt to find
> out what to do about this
>
> The current -mm tree may be found at http://userweb.kernel.org/~akpm/mmotm/
>
Sorry, Kosaki reported me that this patch breaks ia64 compile/boot.
So, I'm fixing the bug in cooperation with him, now.
I think I can send a fix soon. But I hope this patch set for BOOT will be
tested under various arch/configs before going up to.
Thanks,
-Kame
> ------------------------------------------------------
> Subject: mm: fix memmap init to initialize valid memmap for memory hole
> From: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
>
> If PFN is not in early_node_map[] then struct page for it is not
> initialized. If there are holes within a MAX_ORDER_NE_PAGES range of
> pages, then PG_reserved will not be set. Code that walks PFNs within
> MAX_ORDER_NR_PAGES will the use uninitialized struct pages.
>
> To avoid any problems, this patch initializes holes within a
> MAX_ORDER_NR_PAGES that valid memmap exists but is otherwise unused.
>
> Sayeth davem:
>
> 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.
>
> So I did a lot (and I do mean _A LOT_) of digging. And it seems that
> unless you set HOLES_IN_ZONE you have to make sure that all of the
> memmap regions of free space in a zone begin and end on an HPAGE_SIZE
> boundary (the requirement used to be that it had to be MAX_ORDER
> sized).
>
> Well, this assumption enterred the tree back in 2005 (!!!) from
> the following commit in the history-2.6 tree:
>
> commit 69fba2dd0335abec0b0de9ac53d5bbb67c31fc60
> Author: Kamezawa Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
> Date: Fri Jan 7 22:01:35 2005 -0800
>
> [PATCH] no buddy bitmap patch revisit: for mm/page_alloc.c
>
>
> Reported-by: David Miller <davem@davemlloft.net>
> Acked-by: Mel Gorman <mel@csn.ul.ie>
> Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
> Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
> Cc: <stable@kernel.org>
> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
> ---
>
> include/linux/mmzone.h | 6 ------
> mm/page_alloc.c | 13 +++++++++++--
> 2 files changed, 11 insertions(+), 8 deletions(-)
>
> diff -puN include/linux/mmzone.h~mm-fix-memmap-init-to-initialize-valid-memmap-for-memory-hole include/linux/mmzone.h
> --- a/include/linux/mmzone.h~mm-fix-memmap-init-to-initialize-valid-memmap-for-memory-hole
> +++ a/include/linux/mmzone.h
> @@ -1070,12 +1070,6 @@ void sparse_init(void);
> #define sparse_index_init(_sec, _nid) do {} while (0)
> #endif /* CONFIG_SPARSEMEM */
>
> -#ifdef CONFIG_NODES_SPAN_OTHER_NODES
> -#define early_pfn_in_nid(pfn, nid) (early_pfn_to_nid(pfn) == (nid))
> -#else
> -#define early_pfn_in_nid(pfn, nid) (1)
> -#endif
> -
> #ifndef early_pfn_valid
> #define early_pfn_valid(pfn) (1)
> #endif
> diff -puN mm/page_alloc.c~mm-fix-memmap-init-to-initialize-valid-memmap-for-memory-hole mm/page_alloc.c
> --- a/mm/page_alloc.c~mm-fix-memmap-init-to-initialize-valid-memmap-for-memory-hole
> +++ a/mm/page_alloc.c
> @@ -2633,9 +2633,18 @@ void __meminit memmap_init_zone(unsigned
> * exist on hotplugged memory.
> */
> if (context == MEMMAP_EARLY) {
> + int nid_from_node_memory_map;
> +
> if (!early_pfn_valid(pfn))
> continue;
> - if (!early_pfn_in_nid(pfn, nid))
> + /*
> + * early_pfn_to_nid() returns -1 if the page doesn't
> + * exist in early_node_map[]. Initialize it in force
> + * and set PG_reserved at el.
> + */
> + nid_from_node_memory_map = early_pfn_to_nid(pfn);
> + if (nid_from_node_memory_map > -1 &&
> + nid_from_node_memory_map != nid)
> continue;
> }
> page = pfn_to_page(pfn);
> @@ -3002,7 +3011,7 @@ int __meminit early_pfn_to_nid(unsigned
> return early_node_map[i].nid;
> }
>
> - return 0;
> + return -1;
> }
> #endif /* CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID */
>
> _
>
> Patches currently in -mm which might be from kamezawa.hiroyu@jp.fujitsu.com are
>
> origin.patch
> linux-next.patch
> mm-fix-memmap-init-to-initialize-valid-memmap-for-memory-hole.patch
> proc-pid-maps-dont-show-pgoff-of-pure-anon-vmas.patch
> proc-pid-maps-dont-show-pgoff-of-pure-anon-vmas-checkpatch-fixes.patch
> cgroup-css-id-support.patch
> cgroup-fix-frequent-ebusy-at-rmdir.patch
> memcg-use-css-id.patch
> memcg-hierarchical-stat.patch
> memcg-fix-shrinking-memory-to-return-ebusy-by-fixing-retry-algorithm.patch
> memcg-fix-oom-killer-under-memcg.patch
> memcg-fix-oom-killer-under-memcg-fix2.patch
> memcg-fix-oom-killer-under-memcg-fix.patch
> memcg-show-memcg-information-during-oom.patch
> memcg-show-memcg-information-during-oom-fix2.patch
> memcg-show-memcg-information-during-oom-fix.patch
>
> --
> To unsubscribe from this list: send the line "unsubscribe mm-commits" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
^ permalink raw reply [flat|nested] 6+ messages in thread
* [BUGFIX][PATCH] Aditional fix for memmap initalization
2009-02-06 8:17 ` KAMEZAWA Hiroyuki
@ 2009-02-06 9:55 ` KAMEZAWA Hiroyuki
2009-02-10 13:28 ` Mel Gorman
2009-02-10 13:33 ` Mel Gorman
0 siblings, 2 replies; 6+ messages in thread
From: KAMEZAWA Hiroyuki @ 2009-02-06 9:55 UTC (permalink / raw)
To: KAMEZAWA Hiroyuki
Cc: linux-kernel, akpm, mm-commits, davem, heiko.carstens, mel,
stable
On Fri, 6 Feb 2009 17:17:24 +0900
KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> wrote:
> On Thu, 05 Feb 2009 09:29:54 -0800
> akpm@linux-foundation.org wrote:
>
> >
> > The patch titled
> > mm: fix memmap init to initialize valid memmap for memory hole
> > has been added to the -mm tree. Its filename is
> > mm-fix-memmap-init-to-initialize-valid-memmap-for-memory-hole.patch
<snip>
> > The current -mm tree may be found at http://userweb.kernel.org/~akpm/mmotm/
> >
> Sorry, Kosaki reported me that this patch breaks ia64 compile/boot.
> So, I'm fixing the bug in cooperation with him, now.
> I think I can send a fix soon. But I hope this patch set for BOOT will be
> tested under various arch/configs before going up to.
>
This is an add-on fix. Tested on ia64 DISCONTIGMEM/SPARSEMEM, x86-64 fake-numa.
The patch mm-fix-memmap-init-to-initialize-valid-memmap-for-memory-hole.patch
breaks ia64's compile and boot.
After investigation, changing return value of early_pfn_to_nid() doesn't seem
to be very good. This patch adds early_pfn_to_nid_solid() for our purpose
(init memmap) and fixes all breakage.
Tested-by: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
---
arch/ia64/mm/numa.c | 12 ++++++++++--
arch/x86/mm/numa_64.c | 6 +++++-
include/linux/mm.h | 1 +
mm/page_alloc.c | 39 +++++++++++++++++++++++++++++----------
4 files changed, 45 insertions(+), 13 deletions(-)
Index: mmotm-2.6.29-Feb05/include/linux/mm.h
===================================================================
--- mmotm-2.6.29-Feb05.orig/include/linux/mm.h
+++ mmotm-2.6.29-Feb05/include/linux/mm.h
@@ -1049,6 +1049,7 @@ extern void work_with_active_regions(int
extern void sparse_memory_present_with_active_regions(int nid);
#ifndef CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID
extern int early_pfn_to_nid(unsigned long pfn);
+extern int early_pfn_to_solid(unsigned long pfn);
#endif /* CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID */
#endif /* CONFIG_ARCH_POPULATES_NODE_MAP */
extern void set_dma_reserve(unsigned long new_dma_reserve);
Index: mmotm-2.6.29-Feb05/arch/ia64/mm/numa.c
===================================================================
--- mmotm-2.6.29-Feb05.orig/arch/ia64/mm/numa.c
+++ mmotm-2.6.29-Feb05/arch/ia64/mm/numa.c
@@ -58,7 +58,7 @@ paddr_to_nid(unsigned long paddr)
* SPARSEMEM to allocate the SPARSEMEM sectionmap on the NUMA node where
* the section resides.
*/
-int early_pfn_to_nid(unsigned long pfn)
+int early_pfn_to_nid_solid(unsigned long pfn)
{
int i, section = pfn >> PFN_SECTION_SHIFT, ssec, esec;
@@ -70,9 +70,17 @@ int early_pfn_to_nid(unsigned long pfn)
return node_memblk[i].nid;
}
- return 0;
+ return -1;
}
+int early_pfn_to_nid(unsigned long pfn)
+{
+ int nid = early_pfn_to_nid_solid(pfn);
+
+ if (nid < 0) /* see page_alloc.c */
+ return 0;
+ return nid;
+}
#ifdef CONFIG_MEMORY_HOTPLUG
/*
* SRAT information is stored in node_memblk[], then we can use SRAT
Index: mmotm-2.6.29-Feb05/arch/x86/mm/numa_64.c
===================================================================
--- mmotm-2.6.29-Feb05.orig/arch/x86/mm/numa_64.c
+++ mmotm-2.6.29-Feb05/arch/x86/mm/numa_64.c
@@ -166,10 +166,14 @@ int __init compute_hash_shift(struct boo
return shift;
}
-int early_pfn_to_nid(unsigned long pfn)
+int early_pfn_to_nid_solid(unsigned long pfn)
{
return phys_to_nid(pfn << PAGE_SHIFT);
}
+int early_pfn_to_nid(unsigned long pfn)
+{
+ return early_pfn_to_nid_solid(pfn);
+}
static void * __init early_node_mem(int nodeid, unsigned long start,
unsigned long end, unsigned long size,
Index: mmotm-2.6.29-Feb05/mm/page_alloc.c
===================================================================
--- mmotm-2.6.29-Feb05.orig/mm/page_alloc.c
+++ mmotm-2.6.29-Feb05/mm/page_alloc.c
@@ -2554,6 +2554,21 @@ static inline unsigned long wait_table_b
* higher will lead to a bigger reserve which will get freed as contiguous
* blocks as reclaim kicks in
*/
+#ifdef CONFIG_NODE_SPAN_OTHER_NODE
+static inline bool init_pfn_under_nid(unsigned long pfn, int nid)
+{
+ int nid_in_map = early_pfn_to_nid_solid(pfn);
+
+ if (nid_in_map == -1)
+ return true;
+ return (nid_in_map == nid);
+}
+#else
+static inline bool init_pfn_under_nid(unsigned long pfn, int nid)
+{
+ return true;
+}
+#endif
static void setup_zone_migrate_reserve(struct zone *zone)
{
unsigned long start_pfn, pfn, end_pfn;
@@ -2630,18 +2645,13 @@ void __meminit memmap_init_zone(unsigned
* exist on hotplugged memory.
*/
if (context == MEMMAP_EARLY) {
- int nid_from_node_memory_map;
-
if (!early_pfn_valid(pfn))
continue;
/*
- * early_pfn_to_nid() returns -1 if the page doesn't
- * exist in early_node_map[]. Initialize it in force
- * and set PG_reserved at el.
+ * This returns false if the page exists and it's
+ * not under this node.
*/
- nid_from_node_memory_map = early_pfn_to_nid(pfn);
- if (nid_from_node_memory_map > -1 &&
- nid_from_node_memory_map != nid)
+ if (!init_pfn_under_nid(pfn, nid))
continue;
}
page = pfn_to_page(pfn);
@@ -2996,7 +3006,7 @@ static int __meminit next_active_region_
* was used and there are no special requirements, this is a convenient
* alternative
*/
-int __meminit early_pfn_to_nid(unsigned long pfn)
+int __meminit early_pfn_to_nid_solid(unsigned long pfn)
{
int i;
@@ -3007,9 +3017,18 @@ int __meminit early_pfn_to_nid(unsigned
if (start_pfn <= pfn && pfn < end_pfn)
return early_node_map[i].nid;
}
-
return -1;
}
+/* Allow fallback to 0 */
+int __meminit early_pfn_to_nid(unsigned long pfn)
+{
+ int nid;
+
+ nid = early_pfn_to_nid_solid(pfn);
+ if (nid < 0)
+ return 0;
+ return nid;
+}
#endif /* CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID */
/* Basic iterator support to walk early_node_map[] */
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [BUGFIX][PATCH] Aditional fix for memmap initalization
2009-02-06 9:55 ` [BUGFIX][PATCH] Aditional fix for memmap initalization KAMEZAWA Hiroyuki
@ 2009-02-10 13:28 ` Mel Gorman
2009-02-10 13:33 ` Mel Gorman
1 sibling, 0 replies; 6+ messages in thread
From: Mel Gorman @ 2009-02-10 13:28 UTC (permalink / raw)
To: KAMEZAWA Hiroyuki
Cc: linux-kernel, akpm, mm-commits, davem, heiko.carstens, stable
On Fri, Feb 06, 2009 at 06:55:14PM +0900, KAMEZAWA Hiroyuki wrote:
> On Fri, 6 Feb 2009 17:17:24 +0900
> KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> wrote:
>
> > On Thu, 05 Feb 2009 09:29:54 -0800
> > akpm@linux-foundation.org wrote:
> >
> > >
> > > The patch titled
> > > mm: fix memmap init to initialize valid memmap for memory hole
> > > has been added to the -mm tree. Its filename is
> > > mm-fix-memmap-init-to-initialize-valid-memmap-for-memory-hole.patch
> <snip>
> > > The current -mm tree may be found at http://userweb.kernel.org/~akpm/mmotm/
> > >
> > Sorry, Kosaki reported me that this patch breaks ia64 compile/boot.
> > So, I'm fixing the bug in cooperation with him, now.
> > I think I can send a fix soon. But I hope this patch set for BOOT will be
> > tested under various arch/configs before going up to.
> >
>
> This is an add-on fix. Tested on ia64 DISCONTIGMEM/SPARSEMEM, x86-64 fake-numa.
>
> The patch mm-fix-memmap-init-to-initialize-valid-memmap-for-memory-hole.patch
> breaks ia64's compile and boot.
>
> After investigation, changing return value of early_pfn_to_nid() doesn't seem
> to be very good.
Damn, I thought they looked ok at the time. Clearly I didn't look carefully
enough.
> This patch adds early_pfn_to_nid_solid() for our purpose
> (init memmap) and fixes all breakage.
>
> Tested-by: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
> Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
> ---
> arch/ia64/mm/numa.c | 12 ++++++++++--
> arch/x86/mm/numa_64.c | 6 +++++-
> include/linux/mm.h | 1 +
> mm/page_alloc.c | 39 +++++++++++++++++++++++++++++----------
> 4 files changed, 45 insertions(+), 13 deletions(-)
>
> Index: mmotm-2.6.29-Feb05/include/linux/mm.h
> ===================================================================
> --- mmotm-2.6.29-Feb05.orig/include/linux/mm.h
> +++ mmotm-2.6.29-Feb05/include/linux/mm.h
> @@ -1049,6 +1049,7 @@ extern void work_with_active_regions(int
> extern void sparse_memory_present_with_active_regions(int nid);
> #ifndef CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID
> extern int early_pfn_to_nid(unsigned long pfn);
> +extern int early_pfn_to_solid(unsigned long pfn);
I don't understand for sure what _solid means. I think you might mean the
opposite of "hole" but it's an unusual choice of words and I'm surprised
the boot-init API has to be expanded.
> #endif /* CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID */
> #endif /* CONFIG_ARCH_POPULATES_NODE_MAP */
> extern void set_dma_reserve(unsigned long new_dma_reserve);
> Index: mmotm-2.6.29-Feb05/arch/ia64/mm/numa.c
> ===================================================================
> --- mmotm-2.6.29-Feb05.orig/arch/ia64/mm/numa.c
> +++ mmotm-2.6.29-Feb05/arch/ia64/mm/numa.c
> @@ -58,7 +58,7 @@ paddr_to_nid(unsigned long paddr)
> * SPARSEMEM to allocate the SPARSEMEM sectionmap on the NUMA node where
> * the section resides.
> */
> -int early_pfn_to_nid(unsigned long pfn)
> +int early_pfn_to_nid_solid(unsigned long pfn)
> {
> int i, section = pfn >> PFN_SECTION_SHIFT, ssec, esec;
>
> @@ -70,9 +70,17 @@ int early_pfn_to_nid(unsigned long pfn)
> return node_memblk[i].nid;
> }
>
> - return 0;
> + return -1;
> }
>
> +int early_pfn_to_nid(unsigned long pfn)
> +{
> + int nid = early_pfn_to_nid_solid(pfn);
> +
> + if (nid < 0) /* see page_alloc.c */
> + return 0;
> + return nid;
> +}
> #ifdef CONFIG_MEMORY_HOTPLUG
> /*
> * SRAT information is stored in node_memblk[], then we can use SRAT
> Index: mmotm-2.6.29-Feb05/arch/x86/mm/numa_64.c
> ===================================================================
> --- mmotm-2.6.29-Feb05.orig/arch/x86/mm/numa_64.c
> +++ mmotm-2.6.29-Feb05/arch/x86/mm/numa_64.c
> @@ -166,10 +166,14 @@ int __init compute_hash_shift(struct boo
> return shift;
> }
>
> -int early_pfn_to_nid(unsigned long pfn)
> +int early_pfn_to_nid_solid(unsigned long pfn)
> {
> return phys_to_nid(pfn << PAGE_SHIFT);
> }
> +int early_pfn_to_nid(unsigned long pfn)
> +{
> + return early_pfn_to_nid_solid(pfn);
> +}
>
> static void * __init early_node_mem(int nodeid, unsigned long start,
> unsigned long end, unsigned long size,
> Index: mmotm-2.6.29-Feb05/mm/page_alloc.c
> ===================================================================
> --- mmotm-2.6.29-Feb05.orig/mm/page_alloc.c
> +++ mmotm-2.6.29-Feb05/mm/page_alloc.c
> @@ -2554,6 +2554,21 @@ static inline unsigned long wait_table_b
> * higher will lead to a bigger reserve which will get freed as contiguous
> * blocks as reclaim kicks in
> */
> +#ifdef CONFIG_NODE_SPAN_OTHER_NODE
This is a typo of CONFIG_NODES_SPAN_OTHER_NODES, right?. In other words, it
would appear we are now unconditionally returning true and on systems where
nodes are spanning, we are going to initialise the PFNs twice and have PFNs
belonging to the wrong nodes.
> +static inline bool init_pfn_under_nid(unsigned long pfn, int nid)
This function name is confusing because it doesn't actually init
anything.
> +{
> + int nid_in_map = early_pfn_to_nid_solid(pfn);
> +
> + if (nid_in_map == -1)
> + return true;
> + return (nid_in_map == nid);
> +}
> +#else
> +static inline bool init_pfn_under_nid(unsigned long pfn, int nid)
> +{
> + return true;
> +}
> +#endif
> static void setup_zone_migrate_reserve(struct zone *zone)
> {
> unsigned long start_pfn, pfn, end_pfn;
> @@ -2630,18 +2645,13 @@ void __meminit memmap_init_zone(unsigned
> * exist on hotplugged memory.
> */
> if (context == MEMMAP_EARLY) {
> - int nid_from_node_memory_map;
> -
> if (!early_pfn_valid(pfn))
> continue;
> /*
> - * early_pfn_to_nid() returns -1 if the page doesn't
> - * exist in early_node_map[]. Initialize it in force
> - * and set PG_reserved at el.
> + * This returns false if the page exists and it's
> + * not under this node.
> */
> - nid_from_node_memory_map = early_pfn_to_nid(pfn);
> - if (nid_from_node_memory_map > -1 &&
> - nid_from_node_memory_map != nid)
> + if (!init_pfn_under_nid(pfn, nid))
> continue;
> }
> page = pfn_to_page(pfn);
> @@ -2996,7 +3006,7 @@ static int __meminit next_active_region_
> * was used and there are no special requirements, this is a convenient
> * alternative
> */
> -int __meminit early_pfn_to_nid(unsigned long pfn)
> +int __meminit early_pfn_to_nid_solid(unsigned long pfn)
> {
> int i;
>
> @@ -3007,9 +3017,18 @@ int __meminit early_pfn_to_nid(unsigned
> if (start_pfn <= pfn && pfn < end_pfn)
> return early_node_map[i].nid;
> }
> -
> return -1;
> }
> +/* Allow fallback to 0 */
> +int __meminit early_pfn_to_nid(unsigned long pfn)
> +{
> + int nid;
> +
> + nid = early_pfn_to_nid_solid(pfn);
> + if (nid < 0)
> + return 0;
> + return nid;
> +}
> #endif /* CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID */
>
> /* Basic iterator support to walk early_node_map[] */
>
It feels like we are changing more than we need to. Could we achieve the same
fix by just altering early_pfn_in_nid() to return true if the PFN matches
the NID or is in a hole and ok to initialise. Something like this patch maybe?
=====
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index 09c14e2..c3140df 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -1070,11 +1070,7 @@ void sparse_init(void);
#define sparse_index_init(_sec, _nid) do {} while (0)
#endif /* CONFIG_SPARSEMEM */
-#ifdef CONFIG_NODES_SPAN_OTHER_NODES
-#define early_pfn_in_nid(pfn, nid) (early_pfn_to_nid(pfn) == (nid))
-#else
-#define early_pfn_in_nid(pfn, nid) (1)
-#endif
+int __meminit early_pfn_in_nid(unsigned long pfn, int nid);
#ifndef early_pfn_valid
#define early_pfn_valid(pfn) (1)
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 5675b30..708837e 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -3005,6 +3005,34 @@ int __meminit early_pfn_to_nid(unsigned long pfn)
}
#endif /* CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID */
+#ifdef CONFIG_NODES_SPAN_OTHER_NODES
+/*
+ * Returns true if the PFN is within the NID or it is within a hole.
+ * If the PFN is in a hole, we still initialise the memmap so that
+ * walkers of the memmap do not get confused
+ */
+int __meminit early_pfn_in_nid(unsigned long pfn, int nid)
+{
+ int i;
+
+ for (i = 0; i < nr_nodemap_entries; i++) {
+ unsigned long start_pfn = early_node_map[i].start_pfn;
+ unsigned long end_pfn = early_node_map[i].end_pfn;
+
+ if (start_pfn <= pfn && pfn < end_pfn)
+ return early_node_map[i].nid == nid;
+ }
+
+ /* The PFN is within a hole so it'll be ok to initialise */
+ return 1;
+}
+#else
+int __meminit early_pfn_in_nid(unsigned long pfn, int nid)
+{
+ return 1;
+}
+#endif
+
/* Basic iterator support to walk early_node_map[] */
#define for_each_active_range_index_in_nid(i, nid) \
for (i = first_active_region_index_in_nid(nid); i != -1; \
--
Mel Gorman
Part-time Phd Student Linux Technology Center
University of Limerick IBM Dublin Software Lab
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [BUGFIX][PATCH] Aditional fix for memmap initalization
2009-02-06 9:55 ` [BUGFIX][PATCH] Aditional fix for memmap initalization KAMEZAWA Hiroyuki
2009-02-10 13:28 ` Mel Gorman
@ 2009-02-10 13:33 ` Mel Gorman
2009-02-10 14:27 ` KAMEZAWA Hiroyuki
1 sibling, 1 reply; 6+ messages in thread
From: Mel Gorman @ 2009-02-10 13:33 UTC (permalink / raw)
To: KAMEZAWA Hiroyuki
Cc: linux-kernel, akpm, mm-commits, davem, heiko.carstens, stable
(Resending with David Millers email corrected)
On Fri, Feb 06, 2009 at 06:55:14PM +0900, KAMEZAWA Hiroyuki wrote:
> On Fri, 6 Feb 2009 17:17:24 +0900
> KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> wrote:
>
> > On Thu, 05 Feb 2009 09:29:54 -0800
> > akpm@linux-foundation.org wrote:
> >
> > >
> > > The patch titled
> > > mm: fix memmap init to initialize valid memmap for memory hole
> > > has been added to the -mm tree. Its filename is
> > > mm-fix-memmap-init-to-initialize-valid-memmap-for-memory-hole.patch
> <snip>
> > > The current -mm tree may be found at http://userweb.kernel.org/~akpm/mmotm/
> > >
> > Sorry, Kosaki reported me that this patch breaks ia64 compile/boot.
> > So, I'm fixing the bug in cooperation with him, now.
> > I think I can send a fix soon. But I hope this patch set for BOOT will be
> > tested under various arch/configs before going up to.
> >
>
> This is an add-on fix. Tested on ia64 DISCONTIGMEM/SPARSEMEM, x86-64 fake-numa.
>
> The patch mm-fix-memmap-init-to-initialize-valid-memmap-for-memory-hole.patch
> breaks ia64's compile and boot.
>
> After investigation, changing return value of early_pfn_to_nid() doesn't seem
> to be very good.
Damn, I thought they looked ok at the time. Clearly I didn't look carefully
enough.
> This patch adds early_pfn_to_nid_solid() for our purpose
> (init memmap) and fixes all breakage.
>
> Tested-by: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com>
> Signed-off-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
> ---
> arch/ia64/mm/numa.c | 12 ++++++++++--
> arch/x86/mm/numa_64.c | 6 +++++-
> include/linux/mm.h | 1 +
> mm/page_alloc.c | 39 +++++++++++++++++++++++++++++----------
> 4 files changed, 45 insertions(+), 13 deletions(-)
>
> Index: mmotm-2.6.29-Feb05/include/linux/mm.h
> ===================================================================
> --- mmotm-2.6.29-Feb05.orig/include/linux/mm.h
> +++ mmotm-2.6.29-Feb05/include/linux/mm.h
> @@ -1049,6 +1049,7 @@ extern void work_with_active_regions(int
> extern void sparse_memory_present_with_active_regions(int nid);
> #ifndef CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID
> extern int early_pfn_to_nid(unsigned long pfn);
> +extern int early_pfn_to_solid(unsigned long pfn);
I don't understand for sure what _solid means. I think you might mean the
opposite of "hole" but it's an unusual choice of words and I'm surprised
the boot-init API has to be expanded.
> #endif /* CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID */
> #endif /* CONFIG_ARCH_POPULATES_NODE_MAP */
> extern void set_dma_reserve(unsigned long new_dma_reserve);
> Index: mmotm-2.6.29-Feb05/arch/ia64/mm/numa.c
> ===================================================================
> --- mmotm-2.6.29-Feb05.orig/arch/ia64/mm/numa.c
> +++ mmotm-2.6.29-Feb05/arch/ia64/mm/numa.c
> @@ -58,7 +58,7 @@ paddr_to_nid(unsigned long paddr)
> * SPARSEMEM to allocate the SPARSEMEM sectionmap on the NUMA node where
> * the section resides.
> */
> -int early_pfn_to_nid(unsigned long pfn)
> +int early_pfn_to_nid_solid(unsigned long pfn)
> {
> int i, section = pfn >> PFN_SECTION_SHIFT, ssec, esec;
>
> @@ -70,9 +70,17 @@ int early_pfn_to_nid(unsigned long pfn)
> return node_memblk[i].nid;
> }
>
> - return 0;
> + return -1;
> }
>
> +int early_pfn_to_nid(unsigned long pfn)
> +{
> + int nid = early_pfn_to_nid_solid(pfn);
> +
> + if (nid < 0) /* see page_alloc.c */
> + return 0;
> + return nid;
> +}
> #ifdef CONFIG_MEMORY_HOTPLUG
> /*
> * SRAT information is stored in node_memblk[], then we can use SRAT
> Index: mmotm-2.6.29-Feb05/arch/x86/mm/numa_64.c
> ===================================================================
> --- mmotm-2.6.29-Feb05.orig/arch/x86/mm/numa_64.c
> +++ mmotm-2.6.29-Feb05/arch/x86/mm/numa_64.c
> @@ -166,10 +166,14 @@ int __init compute_hash_shift(struct boo
> return shift;
> }
>
> -int early_pfn_to_nid(unsigned long pfn)
> +int early_pfn_to_nid_solid(unsigned long pfn)
> {
> return phys_to_nid(pfn << PAGE_SHIFT);
> }
> +int early_pfn_to_nid(unsigned long pfn)
> +{
> + return early_pfn_to_nid_solid(pfn);
> +}
>
> static void * __init early_node_mem(int nodeid, unsigned long start,
> unsigned long end, unsigned long size,
> Index: mmotm-2.6.29-Feb05/mm/page_alloc.c
> ===================================================================
> --- mmotm-2.6.29-Feb05.orig/mm/page_alloc.c
> +++ mmotm-2.6.29-Feb05/mm/page_alloc.c
> @@ -2554,6 +2554,21 @@ static inline unsigned long wait_table_b
> * higher will lead to a bigger reserve which will get freed as contiguous
> * blocks as reclaim kicks in
> */
> +#ifdef CONFIG_NODE_SPAN_OTHER_NODE
This is a typo of CONFIG_NODES_SPAN_OTHER_NODES, right?. In other words, it
would appear we are now unconditionally returning true and on systems where
nodes are spanning, we are going to initialise the PFNs twice and have PFNs
belonging to the wrong nodes.
> +static inline bool init_pfn_under_nid(unsigned long pfn, int nid)
This function name is confusing because it doesn't actually init
anything.
> +{
> + int nid_in_map = early_pfn_to_nid_solid(pfn);
> +
> + if (nid_in_map == -1)
> + return true;
> + return (nid_in_map == nid);
> +}
> +#else
> +static inline bool init_pfn_under_nid(unsigned long pfn, int nid)
> +{
> + return true;
> +}
> +#endif
> static void setup_zone_migrate_reserve(struct zone *zone)
> {
> unsigned long start_pfn, pfn, end_pfn;
> @@ -2630,18 +2645,13 @@ void __meminit memmap_init_zone(unsigned
> * exist on hotplugged memory.
> */
> if (context == MEMMAP_EARLY) {
> - int nid_from_node_memory_map;
> -
> if (!early_pfn_valid(pfn))
> continue;
> /*
> - * early_pfn_to_nid() returns -1 if the page doesn't
> - * exist in early_node_map[]. Initialize it in force
> - * and set PG_reserved at el.
> + * This returns false if the page exists and it's
> + * not under this node.
> */
> - nid_from_node_memory_map = early_pfn_to_nid(pfn);
> - if (nid_from_node_memory_map > -1 &&
> - nid_from_node_memory_map != nid)
> + if (!init_pfn_under_nid(pfn, nid))
> continue;
> }
> page = pfn_to_page(pfn);
> @@ -2996,7 +3006,7 @@ static int __meminit next_active_region_
> * was used and there are no special requirements, this is a convenient
> * alternative
> */
> -int __meminit early_pfn_to_nid(unsigned long pfn)
> +int __meminit early_pfn_to_nid_solid(unsigned long pfn)
> {
> int i;
>
> @@ -3007,9 +3017,18 @@ int __meminit early_pfn_to_nid(unsigned
> if (start_pfn <= pfn && pfn < end_pfn)
> return early_node_map[i].nid;
> }
> -
> return -1;
> }
> +/* Allow fallback to 0 */
> +int __meminit early_pfn_to_nid(unsigned long pfn)
> +{
> + int nid;
> +
> + nid = early_pfn_to_nid_solid(pfn);
> + if (nid < 0)
> + return 0;
> + return nid;
> +}
> #endif /* CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID */
>
> /* Basic iterator support to walk early_node_map[] */
>
It feels like we are changing more than we need to. Could we achieve the same
fix by just altering early_pfn_in_nid() to return true if the PFN matches
the NID or is in a hole and ok to initialise. Something like this patch maybe?
=====
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index 09c14e2..c3140df 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -1070,11 +1070,7 @@ void sparse_init(void);
#define sparse_index_init(_sec, _nid) do {} while (0)
#endif /* CONFIG_SPARSEMEM */
-#ifdef CONFIG_NODES_SPAN_OTHER_NODES
-#define early_pfn_in_nid(pfn, nid) (early_pfn_to_nid(pfn) == (nid))
-#else
-#define early_pfn_in_nid(pfn, nid) (1)
-#endif
+int __meminit early_pfn_in_nid(unsigned long pfn, int nid);
#ifndef early_pfn_valid
#define early_pfn_valid(pfn) (1)
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 5675b30..708837e 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -3005,6 +3005,34 @@ int __meminit early_pfn_to_nid(unsigned long pfn)
}
#endif /* CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID */
+#ifdef CONFIG_NODES_SPAN_OTHER_NODES
+/*
+ * Returns true if the PFN is within the NID or it is within a hole.
+ * If the PFN is in a hole, we still initialise the memmap so that
+ * walkers of the memmap do not get confused
+ */
+int __meminit early_pfn_in_nid(unsigned long pfn, int nid)
+{
+ int i;
+
+ for (i = 0; i < nr_nodemap_entries; i++) {
+ unsigned long start_pfn = early_node_map[i].start_pfn;
+ unsigned long end_pfn = early_node_map[i].end_pfn;
+
+ if (start_pfn <= pfn && pfn < end_pfn)
+ return early_node_map[i].nid == nid;
+ }
+
+ /* The PFN is within a hole so it'll be ok to initialise */
+ return 1;
+}
+#else
+int __meminit early_pfn_in_nid(unsigned long pfn, int nid)
+{
+ return 1;
+}
+#endif
+
/* Basic iterator support to walk early_node_map[] */
#define for_each_active_range_index_in_nid(i, nid) \
for (i = first_active_region_index_in_nid(nid); i != -1; \
--
Mel Gorman
Part-time Phd Student Linux Technology Center
University of Limerick IBM Dublin Software Lab
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [BUGFIX][PATCH] Aditional fix for memmap initalization
2009-02-10 13:33 ` Mel Gorman
@ 2009-02-10 14:27 ` KAMEZAWA Hiroyuki
0 siblings, 0 replies; 6+ messages in thread
From: KAMEZAWA Hiroyuki @ 2009-02-10 14:27 UTC (permalink / raw)
To: Mel Gorman
Cc: KAMEZAWA Hiroyuki, linux-kernel, akpm, mm-commits, davem,
heiko.carstens, stable
Mel Gorman wrote:
> It feels like we are changing more than we need to.
agreed.
> Could we achieve the same
> fix by just altering early_pfn_in_nid() to return true if the PFN matches
> the NID or is in a hole and ok to initialise. Something like this patch
> maybe?
>
yes, maybe.
It seems there is no additional bug report and it seems good to write
simpler patch. I'll try a replacement in this week.
Regards,
-Kame
> =====
> diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
> index 09c14e2..c3140df 100644
> --- a/include/linux/mmzone.h
> +++ b/include/linux/mmzone.h
> @@ -1070,11 +1070,7 @@ void sparse_init(void);
> #define sparse_index_init(_sec, _nid) do {} while (0)
> #endif /* CONFIG_SPARSEMEM */
>
> -#ifdef CONFIG_NODES_SPAN_OTHER_NODES
> -#define early_pfn_in_nid(pfn, nid) (early_pfn_to_nid(pfn) == (nid))
> -#else
> -#define early_pfn_in_nid(pfn, nid) (1)
> -#endif
> +int __meminit early_pfn_in_nid(unsigned long pfn, int nid);
>
> #ifndef early_pfn_valid
> #define early_pfn_valid(pfn) (1)
> diff --git a/mm/page_alloc.c b/mm/page_alloc.c
> index 5675b30..708837e 100644
> --- a/mm/page_alloc.c
> +++ b/mm/page_alloc.c
> @@ -3005,6 +3005,34 @@ int __meminit early_pfn_to_nid(unsigned long pfn)
> }
> #endif /* CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID */
>
> +#ifdef CONFIG_NODES_SPAN_OTHER_NODES
> +/*
> + * Returns true if the PFN is within the NID or it is within a hole.
> + * If the PFN is in a hole, we still initialise the memmap so that
> + * walkers of the memmap do not get confused
> + */
> +int __meminit early_pfn_in_nid(unsigned long pfn, int nid)
> +{
> + int i;
> +
> + for (i = 0; i < nr_nodemap_entries; i++) {
> + unsigned long start_pfn = early_node_map[i].start_pfn;
> + unsigned long end_pfn = early_node_map[i].end_pfn;
> +
> + if (start_pfn <= pfn && pfn < end_pfn)
> + return early_node_map[i].nid == nid;
> + }
> +
> + /* The PFN is within a hole so it'll be ok to initialise */
> + return 1;
> +}
> +#else
> +int __meminit early_pfn_in_nid(unsigned long pfn, int nid)
> +{
> + return 1;
> +}
> +#endif
> +
> /* Basic iterator support to walk early_node_map[] */
> #define for_each_active_range_index_in_nid(i, nid) \
> for (i = first_active_region_index_in_nid(nid); i != -1; \
>
> --
> Mel Gorman
> Part-time Phd Student Linux Technology Center
> University of Limerick IBM Dublin Software Lab
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
>
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2009-02-10 14:27 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-02-05 17:29 + mm-fix-memmap-init-to-initialize-valid-memmap-for-memory-hole.patch added to -mm tree akpm
2009-02-06 8:17 ` KAMEZAWA Hiroyuki
2009-02-06 9:55 ` [BUGFIX][PATCH] Aditional fix for memmap initalization KAMEZAWA Hiroyuki
2009-02-10 13:28 ` Mel Gorman
2009-02-10 13:33 ` Mel Gorman
2009-02-10 14:27 ` KAMEZAWA Hiroyuki
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.