Subject: kern/33688: panic when NKMEMPAGES set to certain large number
To: None <kern-bug-people@netbsd.org, gnats-admin@netbsd.org,>
From: None <chenpeng@semptian.com>
List: netbsd-bugs
Date: 06/10/2006 12:55:02
>Number: 33688
>Category: kern
>Synopsis: panic when NKMEMPAGES set to certain large number
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: kern-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Sat Jun 10 12:55:02 +0000 2006
>Originator: Ricardo Chen
>Release: 3.0
>Organization:
>Environment:
NetBSD 3.0 i386
>Description:
Firstly I'm sorry for my bad English, I wish I could descibe the problem and fix clearly...
When I tuning my kernel, and setting the NKMEMPAGES to any number larger than ((384 * 1024 * 1024) >> PAGE_SHIFT) and rebuilding and the new system will go to panic soon after boot.
>How-To-Repeat:
Use i386 PC(with 1G memory), add
options NKMEMPAGES ((768* 1024 * 1024) >> PAGE_SHIFT)
to the kernel config file, config and build and reboot, panic will happen.
>Fix:
I checked and traced the source code, found the following code:
sys/kern/kern_malloc.c, from line 845:
kmemusage = (struct kmemusage *) uvm_km_zalloc(kernel_map,
(vsize_t)(nkmempages * sizeof(struct kmemusage)));
kmb = 0;
kmem_map = uvm_km_suballoc(kernel_map, &kmb,
&kml, ((vsize_t)nkmempages << PAGE_SHIFT),
VM_MAP_INTRSAFE, FALSE, &kmem_map_store);
uvm_km_vacache_init(kmem_map, "kvakmem", 0);
I'm not familiar the code, but I guess since the size of kmemusage becoming very large, it isn't possible to be allocated "directly", then finally the function pmap_alloc_pvpage been called, then
pv_cachedva = uvm_km_kmemalloc(kmem_map, NULL, PAGE_SIZE,
UVM_KMF_TRYLOCK|UVM_KMF_VALLOC);
been called (line 1303 at sys/arch/i386/i386/pmap.c), but at the time, the kmem_map is still not initialized, then panic happens.
So I swich the calling sequence of the two functions:
kmb = 0;
kmem_map = uvm_km_suballoc(kernel_map, &kmb,
&kml, ((vsize_t)nkmempages << PAGE_SHIFT),
VM_MAP_INTRSAFE, FALSE, &kmem_map_store);
kmemusage = (struct kmemusage *) uvm_km_zalloc(kernel_map,
(vsize_t)(nkmempages * sizeof(struct kmemusage)));
uvm_km_vacache_init(kmem_map, "kvakmem", 0);
and now the system seems working OK.