* kmap_alloc_wait: * * Allocates pageable memory from a sub-map of the kernel. If the submap * has no room, the caller sleeps waiting for more memory in the submap. * * This routine may block. */
| 622 | * This routine may block. |
| 623 | */ |
| 624 | vm_offset_t |
| 625 | kmap_alloc_wait(vm_map_t map, vm_size_t size) |
| 626 | { |
| 627 | vm_offset_t addr; |
| 628 | |
| 629 | size = round_page(size); |
| 630 | if (!swap_reserve(size)) |
| 631 | return (0); |
| 632 | |
| 633 | for (;;) { |
| 634 | /* |
| 635 | * To make this work for more than one map, use the map's lock |
| 636 | * to lock out sleepers/wakers. |
| 637 | */ |
| 638 | vm_map_lock(map); |
| 639 | addr = vm_map_findspace(map, vm_map_min(map), size); |
| 640 | if (addr + size <= vm_map_max(map)) |
| 641 | break; |
| 642 | /* no space now; see if we can ever get space */ |
| 643 | if (vm_map_max(map) - vm_map_min(map) < size) { |
| 644 | vm_map_unlock(map); |
| 645 | swap_release(size); |
| 646 | return (0); |
| 647 | } |
| 648 | map->needs_wakeup = TRUE; |
| 649 | vm_map_unlock_and_wait(map, 0); |
| 650 | } |
| 651 | vm_map_insert(map, NULL, 0, addr, addr + size, VM_PROT_RW, VM_PROT_RW, |
| 652 | MAP_ACC_CHARGED); |
| 653 | vm_map_unlock(map); |
| 654 | return (addr); |
| 655 | } |
| 656 | |
| 657 | /* |
| 658 | * kmap_free_wakeup: |
no test coverage detected