Hello Tony, On 02/09/15 23:25, Alexander Sverdlin wrote: >> Commit a6335fa11 (MIPS: bootmem: Don't use memory holes for page bitmap) >> > crashes kernel with a initramfs unpacking error when initrd is enabled. >> > >> > ---- error message ---- >> > Unpacking initramfs... >> > Initramfs unpacking failed: junk in compressed archive >> > BUG: Bad page state in process swapper pfn:00261 >> > page:81004c20 count:0 mapcount:-127 mapping: (null) index:0x2 >> > flags: 0x0() >> > page dumped because: nonzero mapcount >> > CPU: 0 PID: 1 Comm: swapper Not tainted 4.2.0+ #1782 >> > ----------------------- >> > >> > The modified logic in bootmem_init does not guarantee mapstart to be placed >> > after initrd_end. mapstart is set to the maximum of reserved_end and >> > start. In case initrd_end is greater than reserved_end, mapstart is placed >> > before initrd_end, and causes initramfs unpacking error. > Indeed, seems that there are two problems with the patch. First, "<=" is wrong > in the condition. This will fail if initrd and next zone are separated (in > boot_mem_map), but have not gap in between. Second, without gap, initrd and PFN Oh, "<=" is indeed correct. Could you please test this patch instead of the previously proposed: --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c @@ -338,7 +338,7 @@ static void __init bootmem_init(void) if (end <= reserved_end) continue; #ifdef CONFIG_BLK_DEV_INITRD - /* mapstart should be after initrd_end */ + /* Skip zones before initrd and initrd itself */ if (initrd_end && end <= (unsigned long)PFN_UP(__pa(initrd_end))) continue; #endif @@ -371,6 +371,14 @@ static void __init bootmem_init(void) max_low_pfn = PFN_DOWN(HIGHMEM_START); } +#ifdef CONFIG_BLK_DEV_INITRD + /* + * mapstart should be after initrd_end + */ + if (initrd_end) + mapstart = max(mapstart, (unsigned long)PFN_UP(__pa(initrd_end))); +#endif + /* * Initialize the boot-time allocator with low memory only. */