diff --git a/sys/vm/vm_reserv.h b/sys/vm/vm_reserv.h --- a/sys/vm/vm_reserv.h +++ b/sys/vm/vm_reserv.h @@ -55,6 +55,7 @@ boolean_t vm_reserv_free_page(vm_page_t m); void vm_reserv_init(void); bool vm_reserv_is_page_free(vm_page_t m); +bool vm_reserv_is_populated(vm_page_t m, int npages); int vm_reserv_level(vm_page_t m); int vm_reserv_level_iffullpop(vm_page_t m); vm_page_t vm_reserv_reclaim_contig(int domain, u_long npages, diff --git a/sys/vm/vm_reserv.c b/sys/vm/vm_reserv.c --- a/sys/vm/vm_reserv.c +++ b/sys/vm/vm_reserv.c @@ -1058,6 +1058,27 @@ return (!bit_test(rv->popmap, m - rv->pages)); } +/* + * Returns true if the given page is part of a block of npages, starting at a + * multiple of npages, that are all allocated. Otherwise, returns false. + */ +bool +vm_reserv_is_populated(vm_page_t m, int npages) +{ + vm_reserv_t rv; + int index; + + KASSERT(npages <= VM_LEVEL_0_NPAGES, + ("%s: npages %d exceeds VM_LEVEL_0_NPAGES", __func__, npages)); + KASSERT(powerof2(npages), + ("%s: npages %d is not a power of 2", __func__, npages)); + rv = vm_reserv_from_page(m); + if (rv->object == NULL) + return (false); + index = rounddown2(m - rv->pages, npages); + return (bit_ntest(rv->popmap, index, index + npages - 1, 1)); +} + /* * If the given page belongs to a reservation, returns the level of that * reservation. Otherwise, returns -1.