linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/3] Fix boot problem with deferred meminit on machine with no node 0
@ 2016-07-08 20:00 Mel Gorman
  2016-07-08 20:00 ` [PATCH 1/3] mm, meminit: Remove early_page_nid_uninitialised Mel Gorman
                   ` (2 more replies)
  0 siblings, 3 replies; 7+ messages in thread
From: Mel Gorman @ 2016-07-08 20:00 UTC (permalink / raw)
  To: Andrew Morton; +Cc: Linux-MM, LKML, Mel Gorman

A machine with only node 1 was observed to crash very early in boot with
the following message

[    0.000000] BUG: unable to handle kernel paging request at 000000000002a3c8
[    0.000000] PGD 0
[    0.000000] Modules linked in:
[    0.000000] Hardware name: Supermicro H8DSP-8/H8DSP-8, BIOS 080011  06/30/2006
[    0.000000] task: ffffffff81c0d500 ti: ffffffff81c00000 task.ti: ffffffff81c00000
[    0.000000] RIP: 0010:[<ffffffff816dbd63>]  [<ffffffff816dbd63>] reserve_bootmem_region+0x6a/0xef
[    0.000000] RSP: 0000:ffffffff81c03eb0  EFLAGS: 00010086
[    0.000000] RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000000000
[    0.000000] RDX: ffffffff81c03ec0 RSI: ffffffff81d205c0 RDI: ffffffff8213ee60
[    0.000000] R13: ffffea0000000000 R14: ffffea0000000020 R15: ffffea0000000020
[    0.000000] FS:  0000000000000000(0000) GS:ffff8800fba00000(0000) knlGS:0000000000000000
[    0.000000] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[    0.000000] CR2: 000000000002a3c8 CR3: 0000000001c06000 CR4: 00000000000006b0
[    0.000000] Stack:
[    0.000000]  ffffffff81c03f00 0000000000000400 ffff8800fbfc3200 ffffffff81e2a2c0
[    0.000000]  ffffffff81c03fb0 ffffffff81c03f20 ffffffff81dadf7d ffffea0002000040
[    0.000000]  ffffea0000000000 0000000000000000 000000000000ffff 0000000000000001
[    0.000000] Call Trace:
[    0.000000]  [<ffffffff81dadf7d>] free_all_bootmem+0x4b/0x12a
[    0.000000]  [<ffffffff81d97122>] mem_init+0x70/0xa3
[    0.000000]  [<ffffffff81d78f21>] start_kernel+0x25b/0x49b

This series is the lowest-risk solution to the problem.

 mm/page_alloc.c | 17 +++--------------
 1 file changed, 3 insertions(+), 14 deletions(-)

-- 
2.6.4

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 1/3] mm, meminit: Remove early_page_nid_uninitialised
  2016-07-08 20:00 [PATCH 0/3] Fix boot problem with deferred meminit on machine with no node 0 Mel Gorman
@ 2016-07-08 20:00 ` Mel Gorman
  2016-07-08 20:00 ` [PATCH 2/3] mm, meminit: Always return a valid node from early_pfn_to_nid Mel Gorman
  2016-07-08 20:00 ` [PATCH 3/3] mm, meminit: Ensure node is online before checking whether pages are uninitialised Mel Gorman
  2 siblings, 0 replies; 7+ messages in thread
From: Mel Gorman @ 2016-07-08 20:00 UTC (permalink / raw)
  To: Andrew Morton; +Cc: Linux-MM, LKML, Mel Gorman

The helper early_page_nid_uninitialised() has been dead since commit
974a786e63c9 ("mm, page_alloc: remove MIGRATE_RESERVE") so remove the
dead code.

Signed-off-by: Mel Gorman <mgorman@techsingularity.net>
---
 mm/page_alloc.c | 13 -------------
 1 file changed, 13 deletions(-)

diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index c1069efcc4d7..a19527aa4243 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -292,14 +292,6 @@ static inline bool __meminit early_page_uninitialised(unsigned long pfn)
 	return false;
 }
 
-static inline bool early_page_nid_uninitialised(unsigned long pfn, int nid)
-{
-	if (pfn >= NODE_DATA(nid)->first_deferred_pfn)
-		return true;
-
-	return false;
-}
-
 /*
  * Returns false when the remaining initialisation should be deferred until
  * later in the boot cycle when it can be parallelised.
@@ -339,11 +331,6 @@ static inline bool early_page_uninitialised(unsigned long pfn)
 	return false;
 }
 
-static inline bool early_page_nid_uninitialised(unsigned long pfn, int nid)
-{
-	return false;
-}
-
 static inline bool update_defer_init(pg_data_t *pgdat,
 				unsigned long pfn, unsigned long zone_end,
 				unsigned long *nr_initialised)
-- 
2.6.4

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 2/3] mm, meminit: Always return a valid node from early_pfn_to_nid
  2016-07-08 20:00 [PATCH 0/3] Fix boot problem with deferred meminit on machine with no node 0 Mel Gorman
  2016-07-08 20:00 ` [PATCH 1/3] mm, meminit: Remove early_page_nid_uninitialised Mel Gorman
@ 2016-07-08 20:00 ` Mel Gorman
  2016-07-12 23:26   ` David Rientjes
  2016-07-08 20:00 ` [PATCH 3/3] mm, meminit: Ensure node is online before checking whether pages are uninitialised Mel Gorman
  2 siblings, 1 reply; 7+ messages in thread
From: Mel Gorman @ 2016-07-08 20:00 UTC (permalink / raw)
  To: Andrew Morton; +Cc: Linux-MM, LKML, Mel Gorman

early_pfn_to_nid can return node 0 if a PFN is invalid on machines
that has no node 0. A machine with only node 1 was observed to crash
with the following message

 BUG: unable to handle kernel paging request at 000000000002a3c8
 PGD 0
 Modules linked in:
 Hardware name: Supermicro H8DSP-8/H8DSP-8, BIOS 080011  06/30/2006
 task: ffffffff81c0d500 ti: ffffffff81c00000 task.ti: ffffffff81c00000
 RIP: 0010:[<ffffffff816dbd63>]  [<ffffffff816dbd63>] reserve_bootmem_region+0x6a/0xef
 RSP: 0000:ffffffff81c03eb0  EFLAGS: 00010086
 RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000000000
 RDX: ffffffff81c03ec0 RSI: ffffffff81d205c0 RDI: ffffffff8213ee60
 R13: ffffea0000000000 R14: ffffea0000000020 R15: ffffea0000000020
 FS:  0000000000000000(0000) GS:ffff8800fba00000(0000) knlGS:0000000000000000
 CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
 CR2: 000000000002a3c8 CR3: 0000000001c06000 CR4: 00000000000006b0
 Stack:
  ffffffff81c03f00 0000000000000400 ffff8800fbfc3200 ffffffff81e2a2c0
  ffffffff81c03fb0 ffffffff81c03f20 ffffffff81dadf7d ffffea0002000040
  ffffea0000000000 0000000000000000 000000000000ffff 0000000000000001
 Call Trace:
  [<ffffffff81dadf7d>] free_all_bootmem+0x4b/0x12a
  [<ffffffff81d97122>] mem_init+0x70/0xa3
  [<ffffffff81d78f21>] start_kernel+0x25b/0x49b

The problem is that early_page_uninitialised uses the early_pfn_to_nid
helper which returns node 0 for invalid PFNs. No caller of early_pfn_to_nid
cares except early_page_uninitialised. This patch has early_pfn_to_nid
always return a valid node.

Signed-off-by: Mel Gorman <mgorman@techsingularity.net>
Cc: <stable@vger.kernel.org> # 4.2+
---
 mm/page_alloc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index a19527aa4243..5a616de1adca 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -1097,7 +1097,7 @@ int __meminit early_pfn_to_nid(unsigned long pfn)
 	spin_lock(&early_pfn_lock);
 	nid = __early_pfn_to_nid(pfn, &early_pfnnid_cache);
 	if (nid < 0)
-		nid = 0;
+		nid = first_online_node;
 	spin_unlock(&early_pfn_lock);
 
 	return nid;
-- 
2.6.4

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 3/3] mm, meminit: Ensure node is online before checking whether pages are uninitialised
  2016-07-08 20:00 [PATCH 0/3] Fix boot problem with deferred meminit on machine with no node 0 Mel Gorman
  2016-07-08 20:00 ` [PATCH 1/3] mm, meminit: Remove early_page_nid_uninitialised Mel Gorman
  2016-07-08 20:00 ` [PATCH 2/3] mm, meminit: Always return a valid node from early_pfn_to_nid Mel Gorman
@ 2016-07-08 20:00 ` Mel Gorman
  2016-07-12 23:28   ` David Rientjes
  2 siblings, 1 reply; 7+ messages in thread
From: Mel Gorman @ 2016-07-08 20:00 UTC (permalink / raw)
  To: Andrew Morton; +Cc: Linux-MM, LKML, Mel Gorman

early_page_uninitialised looks up an arbitrary PFN. While a machine without
node 0 will boot with "mm, page_alloc: Always return a valid node from
early_pfn_to_nid", it works because it assumes that nodes are always in
PFN order. This is not guaranteed so this patch adds robustness by always
checking if the node being checked is online.

Signed-off-by: Mel Gorman <mgorman@techsingularity.net>
Cc: <stable@vger.kernel.org> # 4.2+
---
 mm/page_alloc.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 5a616de1adca..03c9322da942 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -286,7 +286,9 @@ static inline void reset_deferred_meminit(pg_data_t *pgdat)
 /* Returns true if the struct page for the pfn is uninitialised */
 static inline bool __meminit early_page_uninitialised(unsigned long pfn)
 {
-	if (pfn >= NODE_DATA(early_pfn_to_nid(pfn))->first_deferred_pfn)
+	int nid = early_pfn_to_nid(pfn);
+
+	if (node_online(nid) && pfn >= NODE_DATA(nid)->first_deferred_pfn)
 		return true;
 
 	return false;
-- 
2.6.4

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH 2/3] mm, meminit: Always return a valid node from early_pfn_to_nid
  2016-07-08 20:00 ` [PATCH 2/3] mm, meminit: Always return a valid node from early_pfn_to_nid Mel Gorman
@ 2016-07-12 23:26   ` David Rientjes
  2016-07-13 10:34     ` Mel Gorman
  0 siblings, 1 reply; 7+ messages in thread
From: David Rientjes @ 2016-07-12 23:26 UTC (permalink / raw)
  To: Mel Gorman; +Cc: Andrew Morton, Linux-MM, LKML

On Fri, 8 Jul 2016, Mel Gorman wrote:

> early_pfn_to_nid can return node 0 if a PFN is invalid on machines
> that has no node 0. A machine with only node 1 was observed to crash
> with the following message
> 
>  BUG: unable to handle kernel paging request at 000000000002a3c8
>  PGD 0
>  Modules linked in:
>  Hardware name: Supermicro H8DSP-8/H8DSP-8, BIOS 080011  06/30/2006
>  task: ffffffff81c0d500 ti: ffffffff81c00000 task.ti: ffffffff81c00000
>  RIP: 0010:[<ffffffff816dbd63>]  [<ffffffff816dbd63>] reserve_bootmem_region+0x6a/0xef
>  RSP: 0000:ffffffff81c03eb0  EFLAGS: 00010086
>  RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000000000
>  RDX: ffffffff81c03ec0 RSI: ffffffff81d205c0 RDI: ffffffff8213ee60
>  R13: ffffea0000000000 R14: ffffea0000000020 R15: ffffea0000000020
>  FS:  0000000000000000(0000) GS:ffff8800fba00000(0000) knlGS:0000000000000000
>  CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
>  CR2: 000000000002a3c8 CR3: 0000000001c06000 CR4: 00000000000006b0
>  Stack:
>   ffffffff81c03f00 0000000000000400 ffff8800fbfc3200 ffffffff81e2a2c0
>   ffffffff81c03fb0 ffffffff81c03f20 ffffffff81dadf7d ffffea0002000040
>   ffffea0000000000 0000000000000000 000000000000ffff 0000000000000001
>  Call Trace:
>   [<ffffffff81dadf7d>] free_all_bootmem+0x4b/0x12a
>   [<ffffffff81d97122>] mem_init+0x70/0xa3
>   [<ffffffff81d78f21>] start_kernel+0x25b/0x49b
> 
> The problem is that early_page_uninitialised uses the early_pfn_to_nid
> helper which returns node 0 for invalid PFNs. No caller of early_pfn_to_nid
> cares except early_page_uninitialised. This patch has early_pfn_to_nid
> always return a valid node.
> 
> Signed-off-by: Mel Gorman <mgorman@techsingularity.net>
> Cc: <stable@vger.kernel.org> # 4.2+

Acked-by: David Rientjes <rientjes@google.com>

This makes me wonder about meminit_pfn_in_nid(), however, since if 
__early_pfn_to_nid() returns -1, which is the case in this bug, 
meminit_pfn_in_nid() will return true for any passed node.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 3/3] mm, meminit: Ensure node is online before checking whether pages are uninitialised
  2016-07-08 20:00 ` [PATCH 3/3] mm, meminit: Ensure node is online before checking whether pages are uninitialised Mel Gorman
@ 2016-07-12 23:28   ` David Rientjes
  0 siblings, 0 replies; 7+ messages in thread
From: David Rientjes @ 2016-07-12 23:28 UTC (permalink / raw)
  To: Mel Gorman; +Cc: Andrew Morton, Linux-MM, LKML

On Fri, 8 Jul 2016, Mel Gorman wrote:

> early_page_uninitialised looks up an arbitrary PFN. While a machine without
> node 0 will boot with "mm, page_alloc: Always return a valid node from
> early_pfn_to_nid", it works because it assumes that nodes are always in
> PFN order. This is not guaranteed so this patch adds robustness by always
> checking if the node being checked is online.
> 
> Signed-off-by: Mel Gorman <mgorman@techsingularity.net>
> Cc: <stable@vger.kernel.org> # 4.2+

Acked-by: David Rientjes <rientjes@google.com>

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 2/3] mm, meminit: Always return a valid node from early_pfn_to_nid
  2016-07-12 23:26   ` David Rientjes
@ 2016-07-13 10:34     ` Mel Gorman
  0 siblings, 0 replies; 7+ messages in thread
From: Mel Gorman @ 2016-07-13 10:34 UTC (permalink / raw)
  To: David Rientjes; +Cc: Andrew Morton, Linux-MM, LKML

On Tue, Jul 12, 2016 at 04:26:02PM -0700, David Rientjes wrote:
> On Fri, 8 Jul 2016, Mel Gorman wrote:
> 
> > early_pfn_to_nid can return node 0 if a PFN is invalid on machines
> > that has no node 0. A machine with only node 1 was observed to crash
> > with the following message
> > 
> >  BUG: unable to handle kernel paging request at 000000000002a3c8
> >  PGD 0
> >  Modules linked in:
> >  Hardware name: Supermicro H8DSP-8/H8DSP-8, BIOS 080011  06/30/2006
> >  task: ffffffff81c0d500 ti: ffffffff81c00000 task.ti: ffffffff81c00000
> >  RIP: 0010:[<ffffffff816dbd63>]  [<ffffffff816dbd63>] reserve_bootmem_region+0x6a/0xef
> >  RSP: 0000:ffffffff81c03eb0  EFLAGS: 00010086
> >  RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000000000
> >  RDX: ffffffff81c03ec0 RSI: ffffffff81d205c0 RDI: ffffffff8213ee60
> >  R13: ffffea0000000000 R14: ffffea0000000020 R15: ffffea0000000020
> >  FS:  0000000000000000(0000) GS:ffff8800fba00000(0000) knlGS:0000000000000000
> >  CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> >  CR2: 000000000002a3c8 CR3: 0000000001c06000 CR4: 00000000000006b0
> >  Stack:
> >   ffffffff81c03f00 0000000000000400 ffff8800fbfc3200 ffffffff81e2a2c0
> >   ffffffff81c03fb0 ffffffff81c03f20 ffffffff81dadf7d ffffea0002000040
> >   ffffea0000000000 0000000000000000 000000000000ffff 0000000000000001
> >  Call Trace:
> >   [<ffffffff81dadf7d>] free_all_bootmem+0x4b/0x12a
> >   [<ffffffff81d97122>] mem_init+0x70/0xa3
> >   [<ffffffff81d78f21>] start_kernel+0x25b/0x49b
> > 
> > The problem is that early_page_uninitialised uses the early_pfn_to_nid
> > helper which returns node 0 for invalid PFNs. No caller of early_pfn_to_nid
> > cares except early_page_uninitialised. This patch has early_pfn_to_nid
> > always return a valid node.
> > 
> > Signed-off-by: Mel Gorman <mgorman@techsingularity.net>
> > Cc: <stable@vger.kernel.org> # 4.2+
> 
> Acked-by: David Rientjes <rientjes@google.com>
> 
> This makes me wonder about meminit_pfn_in_nid(), however, since if 
> __early_pfn_to_nid() returns -1, which is the case in this bug, 
> meminit_pfn_in_nid() will return true for any passed node.

I felt it was ok because it's checking for overlapping nodes primarily.
If there is a hole, the pfn_valid check should fail for sparsemem. For
flatmem, there is no concern with overlapping nodes. Technically the
meminit_pfn_in_nid() call can return true for a hole but for sparsemem,
that is checked for by pfn_valid and for flatmem, it doesn't matter.

-- 
Mel Gorman
SUSE Labs

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2016-07-13 10:34 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-07-08 20:00 [PATCH 0/3] Fix boot problem with deferred meminit on machine with no node 0 Mel Gorman
2016-07-08 20:00 ` [PATCH 1/3] mm, meminit: Remove early_page_nid_uninitialised Mel Gorman
2016-07-08 20:00 ` [PATCH 2/3] mm, meminit: Always return a valid node from early_pfn_to_nid Mel Gorman
2016-07-12 23:26   ` David Rientjes
2016-07-13 10:34     ` Mel Gorman
2016-07-08 20:00 ` [PATCH 3/3] mm, meminit: Ensure node is online before checking whether pages are uninitialised Mel Gorman
2016-07-12 23:28   ` David Rientjes

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).