* Allocate a new slab for kernel map entries. The kernel map may be locked or * unlocked, depending on whether the request is coming from the kernel map or a * submap. This function allocates a virtual address range directly from the * kernel map instead of the kmem_* layer to avoid recursion on the kernel map * lock and also to avoid triggering allocator recursion in the vmem boundary * ta
| 186 | * tag allocator. |
| 187 | */ |
| 188 | static void * |
| 189 | kmapent_alloc(uma_zone_t zone, vm_size_t bytes, int domain, uint8_t *pflag, |
| 190 | int wait) |
| 191 | { |
| 192 | vm_offset_t addr; |
| 193 | int error, locked; |
| 194 | |
| 195 | *pflag = UMA_SLAB_PRIV; |
| 196 | |
| 197 | if (!(locked = vm_map_locked(kernel_map))) |
| 198 | vm_map_lock(kernel_map); |
| 199 | addr = vm_map_findspace(kernel_map, vm_map_min(kernel_map), bytes); |
| 200 | if (addr + bytes < addr || addr + bytes > vm_map_max(kernel_map)) |
| 201 | panic("%s: kernel map is exhausted", __func__); |
| 202 | error = vm_map_insert(kernel_map, NULL, 0, addr, addr + bytes, |
| 203 | VM_PROT_RW, VM_PROT_RW, MAP_NOFAULT); |
| 204 | if (error != KERN_SUCCESS) |
| 205 | panic("%s: vm_map_insert() failed: %d", __func__, error); |
| 206 | if (!locked) |
| 207 | vm_map_unlock(kernel_map); |
| 208 | error = kmem_back_domain(domain, kernel_object, addr, bytes, M_NOWAIT | |
| 209 | M_USE_RESERVE | (wait & M_ZERO)); |
| 210 | if (error == KERN_SUCCESS) { |
| 211 | return ((void *)addr); |
| 212 | } else { |
| 213 | if (!locked) |
| 214 | vm_map_lock(kernel_map); |
| 215 | vm_map_delete(kernel_map, addr, bytes); |
| 216 | if (!locked) |
| 217 | vm_map_unlock(kernel_map); |
| 218 | return (NULL); |
| 219 | } |
| 220 | } |
| 221 | |
| 222 | static void |
| 223 | kmapent_free(void *item, vm_size_t size, uint8_t pflag) |
nothing calls this directly
no test coverage detected