Re: PROBLEM: kernel 2.3.21 cannot boot with large memory.

kumon@flab.fujitsu.co.jp
Thu, 14 Oct 1999 14:20:58 +0900


Andrea Arcangeli writes:
> On Wed, 13 Oct 1999 kumon@flab.fujitsu.co.jp wrote:
>
> > free -= (page_cache.min_percent + buffer_mem.min_percent + 2)*num_physpages/100;
>
> IMHO we could kill the above two lines (the min_percent on the buffer
> cache is not preserved anymore in 2.3.x btw).

I see, this can prevent the value free from being negative, but
shortage of nr_free_pages is still exist.
After my previous posting, we found the fundamental reason which
cause the trouble.

About weeks ago, I posted the memory page initialization bug in
mem_init() of linux-2.3.21/arch/i386/mm/init.c.

It had been fixed in 2.3.19. But 2^32 wraparound bug exists in
mem_init() function.

The following patch will fix it. This patch also prevents miss
recognition of blocks with start address overflowed. which will
happens if a memory block starting at physical address 0x40000000
(1GB), the resulting 'PAGE_ OFFSET + addr' wraps around to lower
address.

diff -urN linux-2.3.21/arch/i386/mm/init.c linux-2.3.21-new/arch/i386/mm/init.c
--- linux-2.3.21/arch/i386/mm/init.c Wed Sep 29 23:02:59 1999
+++ linux-2.3.21-new/arch/i386/mm/init.c Thu Oct 14 12:45:50 1999
@@ -429,7 +429,19 @@
end = PAGE_OFFSET + ((addr + size) & PAGE_MASK);
addr= PAGE_OFFSET + PAGE_ALIGN(addr);

- for ( ; addr < end; addr += PAGE_SIZE) {
+ /* if we have start address beyond 4GB, then ignore
+ the block */
+ if (addr < PAGE_OFFSET)
+ continue;
+
+ /* end address should be limited in the 4GB region */
+ if (end < PAGE_OFFSET)
+ end = 0UL;
+
+ /* don't use less-than operator for exit cheking.
+ if the end equals to 2^32 = 0UL, it fails to work */
+
+ for ( ; addr != end; addr += PAGE_SIZE) {

/* this little bit of grossness is for dealing
* with memory borrowing for system bookkeeping

In our original situation, our machine has a block starting at 64MB
which ends at 2GB. The original for statement is not executed because:
addr= PAGE_OFFSET+64MB
end= PAGE_OFFSET+2GB
With PAGE_OFFSET = 0xc0000000, end overflows and the condition (addr
< end) is always false. Being ignored this block causes the shotage
of memory.

This problem may happen, if 1GB config option is used with more than
1GB physical memory, or 2GB with more than 2GB.

--
Computer Systems Laboratory, Fujitsu Labs.
kumon@flab.fujitsu.co.jp

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