* Allocate a physical page from an existing or newly created reservation. * * The page "mpred" must immediately precede the offset "pindex" within the * specified object. * * The object must be locked. */
| 823 | * The object must be locked. |
| 824 | */ |
| 825 | vm_page_t |
| 826 | vm_reserv_alloc_page(vm_object_t object, vm_pindex_t pindex, int domain, |
| 827 | int req, vm_page_t mpred) |
| 828 | { |
| 829 | struct vm_domain *vmd; |
| 830 | vm_page_t m, msucc; |
| 831 | vm_pindex_t first, leftcap, rightcap; |
| 832 | vm_reserv_t rv; |
| 833 | int index; |
| 834 | |
| 835 | VM_OBJECT_ASSERT_WLOCKED(object); |
| 836 | |
| 837 | /* |
| 838 | * Is a reservation fundamentally impossible? |
| 839 | */ |
| 840 | if (pindex < VM_RESERV_INDEX(object, pindex) || |
| 841 | pindex >= object->size) |
| 842 | return (NULL); |
| 843 | |
| 844 | /* |
| 845 | * Look for an existing reservation. |
| 846 | */ |
| 847 | rv = vm_reserv_from_object(object, pindex, mpred, &msucc); |
| 848 | if (rv != NULL) { |
| 849 | KASSERT(object != kernel_object || rv->domain == domain, |
| 850 | ("vm_reserv_alloc_page: domain mismatch")); |
| 851 | domain = rv->domain; |
| 852 | vmd = VM_DOMAIN(domain); |
| 853 | index = VM_RESERV_INDEX(object, pindex); |
| 854 | m = &rv->pages[index]; |
| 855 | vm_reserv_lock(rv); |
| 856 | /* Handle reclaim race. */ |
| 857 | if (rv->object != object || |
| 858 | /* Handle vm_page_rename(m, new_object, ...). */ |
| 859 | popmap_is_set(rv->popmap, index)) { |
| 860 | m = NULL; |
| 861 | goto out; |
| 862 | } |
| 863 | if (vm_domain_allocate(vmd, req, 1) == 0) |
| 864 | m = NULL; |
| 865 | else |
| 866 | vm_reserv_populate(rv, index); |
| 867 | out: |
| 868 | vm_reserv_unlock(rv); |
| 869 | return (m); |
| 870 | } |
| 871 | |
| 872 | /* |
| 873 | * Could a reservation fit between the first index to the left that |
| 874 | * can be used and the first index to the right that cannot be used? |
| 875 | * |
| 876 | * We must synchronize with the reserv object lock to protect the |
| 877 | * pindex/object of the resulting reservations against rename while |
| 878 | * we are inspecting. |
| 879 | */ |
| 880 | first = pindex - VM_RESERV_INDEX(object, pindex); |
| 881 | vm_reserv_object_lock(object); |
| 882 | if (mpred != NULL) { |
no test coverage detected