Module Name: src Committed By: para Date: Fri Sep 7 06:45:05 UTC 2012
Modified Files: src/sys/uvm: uvm_km.c Log Message: call pmap_growkernel once after the kmem_arena is created to make the pmap cover it's address space assert on the growth in uvm_km_kmem_alloc for the 3rd uvm_map_entry uvm_map_prepare will grow the kernel, but we might call into uvm_km_kmem_alloc through imports to the kmem_meta_arena earlier while here guard uvm_km_va_starved_p from kmem_arena not yet created thanks for tracking this down to everyone involved To generate a diff of this commit: cvs rdiff -u -r1.134 -r1.135 src/sys/uvm/uvm_km.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/uvm/uvm_km.c diff -u src/sys/uvm/uvm_km.c:1.134 src/sys/uvm/uvm_km.c:1.135 --- src/sys/uvm/uvm_km.c:1.134 Tue Sep 4 13:37:41 2012 +++ src/sys/uvm/uvm_km.c Fri Sep 7 06:45:04 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: uvm_km.c,v 1.134 2012/09/04 13:37:41 matt Exp $ */ +/* $NetBSD: uvm_km.c,v 1.135 2012/09/07 06:45:04 para Exp $ */ /* * Copyright (c) 1997 Charles D. Cranor and Washington University. @@ -152,7 +152,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: uvm_km.c,v 1.134 2012/09/04 13:37:41 matt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: uvm_km.c,v 1.135 2012/09/07 06:45:04 para Exp $"); #include "opt_uvmhist.h" @@ -202,7 +202,7 @@ int nkmempages = 0; vaddr_t kmembase; vsize_t kmemsize; -vmem_t *kmem_arena; +vmem_t *kmem_arena = NULL; vmem_t *kmem_va_arena; /* @@ -329,6 +329,18 @@ uvm_km_bootstrap(vaddr_t start, vaddr_t kmem_arena = vmem_create("kmem", kmembase, kmemsize, PAGE_SIZE, NULL, NULL, NULL, 0, VM_NOSLEEP | VM_BOOTSTRAP, IPL_VM); +#ifdef PMAP_GROWKERNEL + /* + * kmem_arena VA allocations happen independently of uvm_map. + * grow kernel to accommodate the kmem_arena. + */ + if (uvm_maxkaddr < kmembase + kmemsize) { + uvm_maxkaddr = pmap_growkernel(kmembase + kmemsize); + KASSERTMSG(uvm_maxkaddr >= kmembase + kmemsize, + "%#"PRIxVADDR" %#"PRIxVADDR" %#"PRIxVSIZE, + uvm_maxkaddr, kmembase, kmemsize); + } +#endif vmem_init(kmem_arena); @@ -782,18 +794,12 @@ again: #ifdef PMAP_GROWKERNEL /* - * These VA allocations happen independently of uvm_map so if this allocation - * extends beyond the current limit, then allocate more resources for it. - * This can only happen while the kmem_map is the only map entry in the - * kernel_map because as soon as another map entry is created, uvm_map_prepare - * will set uvm_maxkaddr to an address beyond the kmem_map. - */ - if (uvm_maxkaddr < va + size) { - uvm_maxkaddr = pmap_growkernel(va + size); - KASSERTMSG(uvm_maxkaddr >= va + size, - "%#"PRIxVADDR" %#"PRIxPTR" %#zx", - uvm_maxkaddr, va, size); - } + * These VA allocations happen independently of uvm_map + * so this allocation must not extend beyond the current limit. + */ + KASSERTMSG(uvm_maxkaddr >= va + size, + "%#"PRIxVADDR" %#"PRIxPTR" %#zx", + uvm_maxkaddr, va, size); #endif loopva = va; @@ -864,6 +870,9 @@ uvm_km_va_starved_p(void) vmem_size_t total; vmem_size_t free; + if (kmem_arena == NULL) + return false; + total = vmem_size(kmem_arena, VMEM_ALLOC|VMEM_FREE); free = vmem_size(kmem_arena, VMEM_FREE);