Subject: kern/21307: System crash with too much memory
To: None <gnats-bugs@gnats.netbsd.org>
From: None <darcy@druid.net>
List: netbsd-bugs
Date: 04/24/2003 11:27:35
>Number:         21307
>Category:       kern
>Synopsis:       System crashes on boot if 4GB memory installed
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Thu Apr 24 15:28:01 UTC 2003
>Closed-Date:
>Last-Modified:
>Originator:     D'Arcy J.M. Cain
>Release:        NetBSD 1.6.1
>Organization:
D'Arcy J.M. Cain <darcy@{druid|vex}.net>   |  Democracy is three wolves
http://www.druid.net/darcy/                |  and a sheep voting on
+1 416 425 1212     (DoD#0082)    (eNTP)   |  what's for dinner.
>Environment:
	NetBSD valkyrie.givex.com 1.6.1 NetBSD 1.6.1 (VAULTS) #9: Wed Apr 23 16:48:33 EDT 2003     door@greenroom.givex.com:/usr/src/sys/arch/i386/compile/VAULTS i386
Machine: i386
>Description:
If the machine has 4GB of memory the following error occurs during boot.
cpu0: serial number 0000-068a-0000-d683-c4b9-1876
total memory = 3967 MB
panic: cpu_startup: cannot allocate VM for buffers
Stopped in pid 0 ( ) at cpu_debugger +0x4: leave
db>
>How-To-Repeat:
Put 4GB into system and reboot.
>Fix:
I have been discussing this on tech-kern and private email.  Here is the result of those discussions so far.

In sys/kern/kern_allocsys.c there is the following code.

    /*
     * Ensure a minimum of 16 buffers.
     */
    if (nbuf == 0) {
        nbuf = bufpages;
        if (nbuf < 16)
            nbuf = 16;
    }

#ifdef VM_MAX_KERNEL_BUF
    /*
     * XXX stopgap measure to prevent wasting too much KVM on
     * the sparsely filled buffer cache.
     */
    if (nbuf * MAXBSIZE > VM_MAX_KERNEL_BUF)
        nbuf = VM_MAX_KERNEL_BUF / MAXBSIZE;
#endif

The problem seems to be that if bufpages is too high then the expression
(nbuf * MAXBSIZE > VM_MAX_KERNEL_BUF) will be false anyway since the number
will go negative.  I fixed it by adding the following line at the end of
the first 'if' block:

        if (nbuf > 8000) nbuf = 8000;

This fixed it for me but it is probably not correct.  The number 8000 was
somewhat arbitrary and I need to know how to get the proper number.  The
#ifdef block corrects it to the proper value but I understand that the
constant VM_MAX_KERNEL_BUF is not available on every port so that cannot
be relied on.

>Release-Note:
>Audit-Trail:
>Unformatted: