Skip to contentSkip to conversation

Fix boot failure with less than 17 MB RAM

PATCH In review Darren Hart 2 participants 3 messages Jul 14, 2011 – Jul 15, 2011

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

cover Fix boot failure with less than 17 MB RAM

From: Darren Hart <[email protected]>

The following patch from mainline addresses an issues that prevented my qemu testing from booting in less than 17M of memory. With this page, the kernel can boot to init in 8M of memory.

Apply to yocto/standard/base

The following changes since commit bb8e31f2c99f5e007660d4540df246fb7ecfa746:

USB: ehci: remove structure packing from ehci_def (2011-06-22 14:23:26 -0400)

are available in the git repository at:
git://git.yoctoproject.org/linux-yocto-2.6.37-contrib dvhart/mm
http://git.yoctoproject.org/cgit.cgi/linux-yocto-2.6.37-contrib/log/?h=dvhart/mm

Yinghai Lu (1):
mm: use alloc_bootmem_node_nopanic() on really needed path

 include/linux/bootmem.h |    2 ++
 mm/page_alloc.c         |    7 ++++---
 2 files changed, 6 insertions(+), 3 deletions(-)
author Applied
#1 lore raw

PATCH 1/1 mm: use alloc_bootmem_node_nopanic() on really needed path

From: Yinghai Lu <[email protected]>

commit 8f389a99b652aab5b42297280bd94d95933ad12f upstream.

Stefan found nobootmem does not work on his system that has only 8M of RAM. This causes an early panic:

BIOS-provided physical RAM map:
BIOS-88: 0000000000000000 - 000000000009f000 (usable)
BIOS-88: 0000000000100000 - 0000000000840000 (usable)
bootconsole [earlyser0] enabled
Notice: NX (Execute Disable) protection missing in CPU or disabled in BIOS! DMI not present or invalid.
last_pfn = 0x840 max_arch_pfn = 0x100000
init_memory_mapping: 0000000000000000-0000000000840000
8MB LOWMEM available.

    mapped low ram: 0 - 00840000
    low ram: 0 - 00840000
  Zone PFN ranges:
    DMA      0x00000001 -> 0x00001000
    Normal   empty
  Movable zone start PFN for each node
  early_node_map[2] active PFN ranges
      0: 0x00000001 -> 0x0000009f
      0: 0x00000100 -> 0x00000840
  BUG: Int 6: CR2 (null)
       EDI c034663c  ESI (null)  EBP c0329f38  ESP c0329ef4
       EBX c0346380  EDX 00000006  ECX ffffffff  EAX fffffff4
       err (null)  EIP c0353191   CS c0320060  flg 00010082
  Stack: (null) c030c533 000007cd (null) c030c533 00000001 (null) (null)
         00000003 0000083f 00000018 00000002 00000002 c0329f6c c03534d6 (null)
         (null) 00000100 00000840 (null) c0329f64 00000001 00001000 (null)
  Pid: 0, comm: swapper Not tainted 2.6.36 #5
  Call Trace:
   [<c02e3707>] ? 0xc02e3707
   [<c035e6e5>] 0xc035e6e5
   [<c0353191>] ? 0xc0353191
   [<c03534d6>] 0xc03534d6
   [<c034f1cd>] 0xc034f1cd
   [<c034a824>] 0xc034a824
   [<c03513cb>] ? 0xc03513cb
   [<c0349432>] 0xc0349432
   [<c0349066>] 0xc0349066

It turns out that we should ignore the low limit of 16M.

Use alloc_bootmem_node_nopanic() in this case.

Applied to linux-yocto-2.6.37

---
 include/linux/bootmem.h |    2 ++
 mm/page_alloc.c         |    7 ++++---
 2 files changed, 6 insertions(+), 3 deletions(-)
include/linux/bootmem.h +2 -0
index 499dfe9..552875f 100644
@@ -115,6 +115,8 @@ extern void *__alloc_bootmem_low_node(pg_data_t *pgdat,
 	__alloc_bootmem_nopanic(x, PAGE_SIZE, __pa(MAX_DMA_ADDRESS))
 #define alloc_bootmem_node(pgdat, x) \
 	__alloc_bootmem_node(pgdat, x, SMP_CACHE_BYTES, __pa(MAX_DMA_ADDRESS))
+#define alloc_bootmem_node_nopanic(pgdat, x) \
+	__alloc_bootmem_node_nopanic(pgdat, x, SMP_CACHE_BYTES, __pa(MAX_DMA_ADDRESS))
 #define alloc_bootmem_pages_node(pgdat, x) \
 	__alloc_bootmem_node(pgdat, x, PAGE_SIZE, __pa(MAX_DMA_ADDRESS))
 #define alloc_bootmem_pages_node_nopanic(pgdat, x) \
mm/page_alloc.c +4 -3
index b8b32aa..1c28e48 100644
@@ -3464,7 +3464,7 @@ int zone_wait_table_init(struct zone *zone, unsigned long zone_size_pages)
 
 	if (!slab_is_available()) {
 		zone->wait_table = (wait_queue_head_t *)
-			alloc_bootmem_node(pgdat, alloc_size);
+			alloc_bootmem_node_nopanic(pgdat, alloc_size);
 	} else {
 		/*
 		 * This case means that a zone whose size was 0 gets new memory
@@ -4037,7 +4037,8 @@ static void __init setup_usemap(struct pglist_data *pgdat,
 	unsigned long usemapsize = usemap_size(zonesize);
 	zone->pageblock_flags = NULL;
 	if (usemapsize)
-		zone->pageblock_flags = alloc_bootmem_node(pgdat, usemapsize);
+		zone->pageblock_flags = alloc_bootmem_node_nopanic(pgdat,
+								   usemapsize);
 }
 #else
 static void inline setup_usemap(struct pglist_data *pgdat,
@@ -4203,7 +4204,7 @@ static void __init_refok alloc_node_mem_map(struct pglist_data *pgdat)
 		size =  (end - start) * sizeof(struct page);
 		map = alloc_remap(pgdat->node_id, size);
 		if (!map)
-			map = alloc_bootmem_node(pgdat, size);
+			map = alloc_bootmem_node_nopanic(pgdat, size);
 		pgdat->node_mem_map = map + (pgdat->node_start_pfn - start);
 	}
 #ifndef CONFIG_NEED_MULTIPLE_NODES
Signature · 1 line
1.7.1
#2 lore raw
In reply to Darren Hart
Quoted 8 lines · Darren Hart

From: Darren Hart<[email protected]>

The following patch from mainline addresses an issues that prevented my qemu testing from booting in less than 17M of memory. With this page, the kernel can boot to init in 8M of memory.

Apply to yocto/standard/base

Quoted 7 lines

The following changes since commit bb8e31f2c99f5e007660d4540df246fb7ecfa746:

USB: ehci: remove structure packing from ehci_def (2011-06-22 14:23:26 -0400)

are available in the git repository at:

   git://git.yoctoproject.org/linux-yocto-2.6.37-contrib dvhart/mm
   http://git.yoctoproject.org/cgit.cgi/linux-yocto-2.6.37-contrib/log/?h=dvhart/mm

This has been merged and pushed to the kernel repos, the SRCREV updates are pending.

Cheers,

Bruce

Quoted 8 lines

Yinghai Lu (1):
mm: use alloc_bootmem_node_nopanic() on really needed path

  include/linux/bootmem.h |    2 ++
  mm/page_alloc.c         |    7 ++++---
  2 files changed, 6 insertions(+), 3 deletions(-)