* vmem_bt_alloc: Allocate a new page of boundary tags. * * On architectures with uma_small_alloc there is no recursion; no address * space need be allocated to allocate boundary tags. For the others, we * must handle recursion. Boundary tags are necessary to allocate new * boundary tags. * * UMA guarantees that enough tags are held in reserve to allocate a new * page of kva. We dip int
| 657 | * we are really out of KVA. |
| 658 | */ |
| 659 | static void * |
| 660 | vmem_bt_alloc(uma_zone_t zone, vm_size_t bytes, int domain, uint8_t *pflag, |
| 661 | int wait) |
| 662 | { |
| 663 | vmem_addr_t addr; |
| 664 | |
| 665 | *pflag = UMA_SLAB_KERNEL; |
| 666 | |
| 667 | /* |
| 668 | * Single thread boundary tag allocation so that the address space |
| 669 | * and memory are added in one atomic operation. |
| 670 | */ |
| 671 | mtx_lock(&vmem_bt_lock); |
| 672 | if (vmem_xalloc(vm_dom[domain].vmd_kernel_arena, bytes, 0, 0, 0, |
| 673 | VMEM_ADDR_MIN, VMEM_ADDR_MAX, |
| 674 | M_NOWAIT | M_NOVM | M_USE_RESERVE | M_BESTFIT, &addr) == 0) { |
| 675 | if (kmem_back_domain(domain, kernel_object, addr, bytes, |
| 676 | M_NOWAIT | M_USE_RESERVE) == 0) { |
| 677 | mtx_unlock(&vmem_bt_lock); |
| 678 | return ((void *)addr); |
| 679 | } |
| 680 | vmem_xfree(vm_dom[domain].vmd_kernel_arena, addr, bytes); |
| 681 | mtx_unlock(&vmem_bt_lock); |
| 682 | /* |
| 683 | * Out of memory, not address space. This may not even be |
| 684 | * possible due to M_USE_RESERVE page allocation. |
| 685 | */ |
| 686 | if (wait & M_WAITOK) |
| 687 | vm_wait_domain(domain); |
| 688 | return (NULL); |
| 689 | } |
| 690 | mtx_unlock(&vmem_bt_lock); |
| 691 | /* |
| 692 | * We're either out of address space or lost a fill race. |
| 693 | */ |
| 694 | if (wait & M_WAITOK) |
| 695 | pause("btalloc", 1); |
| 696 | |
| 697 | return (NULL); |
| 698 | } |
| 699 | #endif |
| 700 | |
| 701 | void |
nothing calls this directly
no test coverage detected