Re: Crash while mapping memory in pagetable_init() (Was: Re: .config)

From: Zachary Amsden
Date: Fri Apr 13 2007 - 16:12:27 EST


Jeremy Fitzhardinge wrote:
It seems to me that the problem is simply that it runs out of space. head.S maps 8Mbytes of memory. The kernel takes ~6.8M of that, and
there simply isn't enough remaining space to fit the pagetables to map
all memory into the kernel address space. Here's my dump of all pte
allocations. Notice the jump at c070b000 where skips over the kernel,
and then it just runs into the 8M limit. This is with CONFIG_PARAVIRT,
but no CONFIG_XEN.

I don't see why this doesn't happen all the time; I can't see anything
about this which is PARAVIRT-specific. But I think only specific
combinations of memory size and kernel size can trigger the problem,
because the code in head.S will often end up mapping enough memory to
fit everything in. It tries to map kernelsize+initial_pagetables+128k
of space; in this case it happens to map 8M, but if the kernel were much
larger it would map 12M.

But surely this must have been seen before? Or is there something
subtle I'm missing?

Wow, that is a huge kernel. No wonder I've never seen this. Seems when you go over 6meg there will be a problem. For PAE, this requires page tables to map up to about 896 of lowmem - each page table can map 2 meg of memory, so you need up to 448 page tables, or 1792k of page table memory - adding 16k for pmd tables, this comes to 1808k. With 6.24M kernel, you simply will run out of space to map all of lowmem in 8M.

With 6.8M PAE kernel, 608M of lowmem mappings will cause you to go beyond 8M of initially mapped space. Non-PAE kernels will be ok until you get to a kernel size of about 7.04M.

Note you can always run out of space; to ensure safety, the init code needs to not use a fixed mapping size, it needs to map end_kernel_address + pae ? 1808k : 896k, assuming 128M vmalloc hole. This could cause problems like running into initrd, however, so might require loader changes, or perhaps relocating the initrd. Is the solution to just cap the kernel size at some fixed maximum? 6.2M appears to be the safe limit for all configurations.

I'm pulling this back onto lkml; seems this is a serious bug which needs attention. I've also cc'd some parties that might have relevant knowledge. Why do I seem to recall head.S mapping 128M of mappings at one point in time?

Zach
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/