--- Net2/vm/vm_kern.c 2018/04/24 18:04:49 1.1.1.2 +++ Net2/vm/vm_kern.c 2018/04/24 18:09:36 1.1.1.4 @@ -214,6 +214,7 @@ void kmem_free(map, addr, size) vm_size_t size; { (void) vm_map_remove(map, trunc_page(addr), round_page(addr + size)); + vm_map_simplify(map, addr); } /* @@ -369,9 +370,13 @@ kmem_malloc(map, size, canwait) if (vm_map_find(map, NULL, (vm_offset_t)0, &addr, size, TRUE) != KERN_SUCCESS) { - if (canwait) - panic("kmem_malloc: kmem_map too small"); - return(0); + if (canwait) { /* XXX -- then we should wait */ + if (map == kmem_map) + panic("kmem_malloc: kmem_map too small"); + else if (map == mb_map) + printf("kmem_malloc: mb_map too small (can't wait)\n"); + } + return 0; } /* @@ -511,6 +516,57 @@ thread_wakeup(&vm_pages_needed); /* XXX } /* + * kmem_alloc_wired_wait + * + * Allocates nonpageable memory from a sub-map of the kernel. If the submap + * has no room, the caller sleeps waiting for more memory in the submap. + * + */ +vm_offset_t kmem_alloc_wired_wait(map, size) + vm_map_t map; + vm_size_t size; +{ + vm_offset_t addr; + int result; + + size = round_page(size); + + do { + /* + * To make this work for more than one map, + * use the map's lock to lock out sleepers/wakers. + * Unfortunately, vm_map_find also grabs the map lock. + */ + vm_map_lock(map); + lock_set_recursive(&map->lock); + + addr = vm_map_min(map); + result = vm_map_find(map, NULL, (vm_offset_t) 0, + &addr, size, FALSE); + + lock_clear_recursive(&map->lock); + if (result != KERN_SUCCESS) { + + if ( (vm_map_max(map) - vm_map_min(map)) < size ) { + vm_map_unlock(map); + return(0); + } + + assert_wait((int)map, TRUE); + vm_map_unlock(map); +thread_wakeup(&vm_pages_needed); /* XXX */ + thread_block(); + } + else { + vm_map_unlock(map); + } + + } while (result != KERN_SUCCESS); + + return(addr); +} + +/* * kmem_free_wakeup * * Returns memory to a submap of the kernel, and wakes up any threads @@ -525,6 +581,7 @@ void kmem_free_wakeup(map, addr, size) (void) vm_map_delete(map, trunc_page(addr), round_page(addr + size)); thread_wakeup((int)map); vm_map_unlock(map); + vm_map_simplify(map, addr); } /*