--- Net2/vm/vm_kern.c 2018/04/24 18:04:49 1.1.1.2 +++ Net2/vm/vm_kern.c 2018/04/24 18:15:14 1.1.1.5 @@ -33,7 +33,8 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)vm_kern.c 7.4 (Berkeley) 5/7/91 + * from: @(#)vm_kern.c 7.4 (Berkeley) 5/7/91 + * vm_kern.c,v 1.6 1993/07/15 13:33:46 cgd Exp * * * Copyright (c) 1987, 1990 Carnegie-Mellon University. @@ -214,6 +215,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 +371,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 (should wait)"); + else if (map == mb_map) + panic("kmem_malloc: mb_map too small (should wait)"); + } + return 0; } /* @@ -511,6 +517,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 +582,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); } /*