Index: vm/vm_radix.c =================================================================== --- vm/vm_radix.c (revision 227754) +++ vm/vm_radix.c (working copy) @@ -54,11 +54,19 @@ #include +#define VM_RADIX_MAXVAL ((vm_pindex_t)-1) + +#ifndef UMA_MD_SMALL_ALLOC +#define VM_RADIX_RNODE_MAP_SCALE (1024 * 1024 / 2) +#endif + CTASSERT(sizeof(struct vm_radix_node) < PAGE_SIZE); static uma_zone_t vm_radix_node_zone; #ifndef UMA_MD_SMALL_ALLOC +static vm_map_t rnode_map; + static void * vm_radix_node_zone_allocf(uma_zone_t zone, int size, uint8_t *flags, int wait) { @@ -66,7 +74,7 @@ vm_page_t m; int pflags; - /* Inform UMA that this allocator uses kernel_map. */ + /* Inform UMA that this allocator uses rnode_map. */ *flags = UMA_SLAB_KERNEL; pflags = VM_ALLOC_WIRED | VM_ALLOC_NOOBJ; @@ -79,7 +87,7 @@ VM_ALLOC_SYSTEM; if ((wait & M_ZERO) != 0) pflags |= VM_ALLOC_ZERO; - addr = kmem_alloc_nofault(kernel_map, size); + addr = kmem_alloc_nofault(rnode_map, size); if (addr == 0) return (NULL); @@ -87,7 +95,7 @@ m = vm_page_alloc(NULL, OFF_TO_IDX(addr - VM_MIN_KERNEL_ADDRESS), pflags); if (m == NULL) { - kmem_free(kernel_map, addr, size); + kmem_free(rnode_map, addr, size); return (NULL); } if ((wait & M_ZERO) != 0 && (m->flags & PG_ZERO) == 0) @@ -109,7 +117,7 @@ m = PHYS_TO_VM_PAGE(pmap_kextract(voitem)); pmap_qremove(voitem, 1); vm_page_free(m); - kmem_free(kernel_map, voitem, size); + kmem_free(rnode_map, voitem, size); } static void @@ -171,7 +179,16 @@ void vm_radix_init(void) { +#ifndef UMA_MD_SMALL_ALLOC + vm_offset_t maxaddr, minaddr; + int rnode_map_scale; + rnode_map_scale = VM_RADIX_RNODE_MAP_SCALE; + TUNABLE_INT_FETCH("machdep.rnode_map_scale", &rnode_map_scale); + rnode_map = kmem_suballoc(kernel_map, &minaddr, &maxaddr, + rnode_map_scale * sizeof(struct vm_radix_node), FALSE); +#endif + vm_radix_node_zone = uma_zcreate("RADIX NODE", sizeof(struct vm_radix_node), NULL, #ifdef INVARIANTS @@ -445,6 +462,11 @@ */ inc = 1LL << (level * VM_RADIX_WIDTH); start &= ~VM_RADIX_MAX(level); + /* Avoid start address wrapping up. */ + if ((VM_RADIX_MAXVAL - start) < inc) { + rnode = NULL; + goto out; + } start += inc; slot++; CTR5(KTR_VM, @@ -460,6 +482,10 @@ rnode = rnode->rn_child[slot]; break; } + if ((VM_RADIX_MAXVAL - start) < inc) { + rnode = NULL; + goto out; + } } if (slot == VM_RADIX_COUNT) goto restart;