aboutsummaryrefslogtreecommitdiff
path: root/sys/vm/vm_reserv.c
diff options
context:
space:
mode:
authorAlan Cox <alc@FreeBSD.org>2019-06-03 05:15:36 +0000
committerAlan Cox <alc@FreeBSD.org>2019-06-03 05:15:36 +0000
commit2d5039db182b096ae9293141aabbc17ca2c69638 (patch)
treecedc5d81403bdd4c9b00da65f4f26108c068d23d /sys/vm/vm_reserv.c
parent5ec57af4b22f3fcfa3e93c00590f7b5f9348cd64 (diff)
downloadsrc-2d5039db182b096ae9293141aabbc17ca2c69638.tar.gz
src-2d5039db182b096ae9293141aabbc17ca2c69638.zip
Retire vm_reserv_extend_{contig,page}(). These functions were introduced
as part of a false start toward fine-grained reservation locking. In the end, they were not needed, so eliminate them. Order the parameters to vm_reserv_alloc_{contig,page}() consistently with the vm_page functions that call them. Update the comments about the locking requirements for vm_reserv_alloc_{contig,page}(). They no longer require a free page queues lock. Wrap several lines that became too long after the "req" and "domain" parameters were added to vm_reserv_alloc_{contig,page}(). Reviewed by: kib, markj MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D20492
Notes
Notes: svn path=/head/; revision=348525
Diffstat (limited to 'sys/vm/vm_reserv.c')
-rw-r--r--sys/vm/vm_reserv.c232
1 files changed, 65 insertions, 167 deletions
diff --git a/sys/vm/vm_reserv.c b/sys/vm/vm_reserv.c
index 12e26246a8a9..02188a64cc2d 100644
--- a/sys/vm/vm_reserv.c
+++ b/sys/vm/vm_reserv.c
@@ -576,95 +576,8 @@ vm_reserv_populate(vm_reserv_t rv, int index)
}
/*
- * Attempts to allocate a contiguous set of physical pages from existing
- * reservations. See vm_reserv_alloc_contig() for a description of the
- * function's parameters.
- *
- * The page "mpred" must immediately precede the offset "pindex" within the
- * specified object.
- *
- * The object must be locked.
- */
-vm_page_t
-vm_reserv_extend_contig(int req, vm_object_t object, vm_pindex_t pindex,
- int domain, u_long npages, vm_paddr_t low, vm_paddr_t high,
- u_long alignment, vm_paddr_t boundary, vm_page_t mpred)
-{
- struct vm_domain *vmd;
- vm_paddr_t pa, size;
- vm_page_t m, msucc;
- vm_reserv_t rv;
- int i, index;
-
- VM_OBJECT_ASSERT_WLOCKED(object);
- KASSERT(npages != 0, ("vm_reserv_alloc_contig: npages is 0"));
-
- /*
- * Is a reservation fundamentally impossible?
- */
- if (pindex < VM_RESERV_INDEX(object, pindex) ||
- pindex + npages > object->size || object->resident_page_count == 0)
- return (NULL);
-
- /*
- * All reservations of a particular size have the same alignment.
- * Assuming that the first page is allocated from a reservation, the
- * least significant bits of its physical address can be determined
- * from its offset from the beginning of the reservation and the size
- * of the reservation.
- *
- * Could the specified index within a reservation of the smallest
- * possible size satisfy the alignment and boundary requirements?
- */
- pa = VM_RESERV_INDEX(object, pindex) << PAGE_SHIFT;
- if ((pa & (alignment - 1)) != 0)
- return (NULL);
- size = npages << PAGE_SHIFT;
- if (((pa ^ (pa + size - 1)) & ~(boundary - 1)) != 0)
- return (NULL);
-
- /*
- * Look for an existing reservation.
- */
- rv = vm_reserv_from_object(object, pindex, mpred, &msucc);
- if (rv == NULL)
- return (NULL);
- KASSERT(object != kernel_object || rv->domain == domain,
- ("vm_reserv_extend_contig: Domain mismatch from reservation."));
- index = VM_RESERV_INDEX(object, pindex);
- /* Does the allocation fit within the reservation? */
- if (index + npages > VM_LEVEL_0_NPAGES)
- return (NULL);
- domain = rv->domain;
- vmd = VM_DOMAIN(domain);
- vm_reserv_lock(rv);
- if (rv->object != object)
- goto out;
- m = &rv->pages[index];
- pa = VM_PAGE_TO_PHYS(m);
- if (pa < low || pa + size > high || (pa & (alignment - 1)) != 0 ||
- ((pa ^ (pa + size - 1)) & ~(boundary - 1)) != 0)
- goto out;
- /* Handle vm_page_rename(m, new_object, ...). */
- for (i = 0; i < npages; i++) {
- if (popmap_is_set(rv->popmap, index + i))
- goto out;
- }
- if (!vm_domain_allocate(vmd, req, npages))
- goto out;
- for (i = 0; i < npages; i++)
- vm_reserv_populate(rv, index + i);
- vm_reserv_unlock(rv);
- return (m);
-
-out:
- vm_reserv_unlock(rv);
- return (NULL);
-}
-
-/*
* Allocates a contiguous set of physical pages of the given size "npages"
- * from newly created reservations. All of the physical pages
+ * from existing or newly created reservations. All of the physical pages
* must be at or above the given physical address "low" and below the given
* physical address "high". The given value "alignment" determines the
* alignment of the first physical page in the set. If the given value
@@ -672,18 +585,15 @@ out:
* physical address boundary that is a multiple of that value. Both
* "alignment" and "boundary" must be a power of two.
*
- * Callers should first invoke vm_reserv_extend_contig() to attempt an
- * allocation from existing reservations.
- *
* The page "mpred" must immediately precede the offset "pindex" within the
* specified object.
*
- * The object and free page queue must be locked.
+ * The object must be locked.
*/
vm_page_t
-vm_reserv_alloc_contig(int req, vm_object_t object, vm_pindex_t pindex, int domain,
- u_long npages, vm_paddr_t low, vm_paddr_t high, u_long alignment,
- vm_paddr_t boundary, vm_page_t mpred)
+vm_reserv_alloc_contig(vm_object_t object, vm_pindex_t pindex, int domain,
+ int req, vm_page_t mpred, u_long npages, vm_paddr_t low, vm_paddr_t high,
+ u_long alignment, vm_paddr_t boundary)
{
struct vm_domain *vmd;
vm_paddr_t pa, size;
@@ -721,13 +631,42 @@ vm_reserv_alloc_contig(int req, vm_object_t object, vm_pindex_t pindex, int doma
return (NULL);
/*
- * Callers should've extended an existing reservation prior to
- * calling this function. If a reservation exists it is
- * incompatible with the allocation.
+ * Look for an existing reservation.
*/
rv = vm_reserv_from_object(object, pindex, mpred, &msucc);
- if (rv != NULL)
+ if (rv != NULL) {
+ KASSERT(object != kernel_object || rv->domain == domain,
+ ("vm_reserv_alloc_contig: domain mismatch"));
+ index = VM_RESERV_INDEX(object, pindex);
+ /* Does the allocation fit within the reservation? */
+ if (index + npages > VM_LEVEL_0_NPAGES)
+ return (NULL);
+ domain = rv->domain;
+ vmd = VM_DOMAIN(domain);
+ vm_reserv_lock(rv);
+ /* Handle reclaim race. */
+ if (rv->object != object)
+ goto out;
+ m = &rv->pages[index];
+ pa = VM_PAGE_TO_PHYS(m);
+ if (pa < low || pa + size > high ||
+ (pa & (alignment - 1)) != 0 ||
+ ((pa ^ (pa + size - 1)) & ~(boundary - 1)) != 0)
+ goto out;
+ /* Handle vm_page_rename(m, new_object, ...). */
+ for (i = 0; i < npages; i++)
+ if (popmap_is_set(rv->popmap, index + i))
+ goto out;
+ if (!vm_domain_allocate(vmd, req, npages))
+ goto out;
+ for (i = 0; i < npages; i++)
+ vm_reserv_populate(rv, index + i);
+ vm_reserv_unlock(rv);
+ return (m);
+out:
+ vm_reserv_unlock(rv);
return (NULL);
+ }
/*
* Could at least one reservation fit between the first index to the
@@ -849,8 +788,7 @@ vm_reserv_alloc_contig(int req, vm_object_t object, vm_pindex_t pindex, int doma
}
/*
- * Attempts to extend an existing reservation and allocate the page to the
- * object.
+ * Allocate a physical page from an existing or newly created reservation.
*
* The page "mpred" must immediately precede the offset "pindex" within the
* specified object.
@@ -858,67 +796,8 @@ vm_reserv_alloc_contig(int req, vm_object_t object, vm_pindex_t pindex, int doma
* The object must be locked.
*/
vm_page_t
-vm_reserv_extend(int req, vm_object_t object, vm_pindex_t pindex, int domain,
- vm_page_t mpred)
-{
- struct vm_domain *vmd;
- vm_page_t m, msucc;
- vm_reserv_t rv;
- int index;
-
- VM_OBJECT_ASSERT_WLOCKED(object);
-
- /*
- * Could a reservation currently exist?
- */
- if (pindex < VM_RESERV_INDEX(object, pindex) ||
- pindex >= object->size || object->resident_page_count == 0)
- return (NULL);
-
- /*
- * Look for an existing reservation.
- */
- rv = vm_reserv_from_object(object, pindex, mpred, &msucc);
- if (rv == NULL)
- return (NULL);
-
- KASSERT(object != kernel_object || rv->domain == domain,
- ("vm_reserv_extend: Domain mismatch from reservation."));
- domain = rv->domain;
- vmd = VM_DOMAIN(domain);
- index = VM_RESERV_INDEX(object, pindex);
- m = &rv->pages[index];
- vm_reserv_lock(rv);
- /* Handle reclaim race. */
- if (rv->object != object ||
- /* Handle vm_page_rename(m, new_object, ...). */
- popmap_is_set(rv->popmap, index)) {
- m = NULL;
- goto out;
- }
- if (vm_domain_allocate(vmd, req, 1) == 0)
- m = NULL;
- else
- vm_reserv_populate(rv, index);
-out:
- vm_reserv_unlock(rv);
-
- return (m);
-}
-
-/*
- * Attempts to allocate a new reservation for the object, and allocates a
- * page from that reservation. Callers should first invoke vm_reserv_extend()
- * to attempt an allocation from an existing reservation.
- *
- * The page "mpred" must immediately precede the offset "pindex" within the
- * specified object.
- *
- * The object and free page queue must be locked.
- */
-vm_page_t
-vm_reserv_alloc_page(int req, vm_object_t object, vm_pindex_t pindex, int domain,
- vm_page_t mpred)
+vm_reserv_alloc_page(vm_object_t object, vm_pindex_t pindex, int domain,
+ int req, vm_page_t mpred)
{
struct vm_domain *vmd;
vm_page_t m, msucc;
@@ -936,13 +815,32 @@ vm_reserv_alloc_page(int req, vm_object_t object, vm_pindex_t pindex, int domain
return (NULL);
/*
- * Callers should've extended an existing reservation prior to
- * calling this function. If a reservation exists it is
- * incompatible with the allocation.
+ * Look for an existing reservation.
*/
rv = vm_reserv_from_object(object, pindex, mpred, &msucc);
- if (rv != NULL)
- return (NULL);
+ if (rv != NULL) {
+ KASSERT(object != kernel_object || rv->domain == domain,
+ ("vm_reserv_alloc_page: domain mismatch"));
+ domain = rv->domain;
+ vmd = VM_DOMAIN(domain);
+ index = VM_RESERV_INDEX(object, pindex);
+ m = &rv->pages[index];
+ vm_reserv_lock(rv);
+ /* Handle reclaim race. */
+ if (rv->object != object ||
+ /* Handle vm_page_rename(m, new_object, ...). */
+ popmap_is_set(rv->popmap, index)) {
+ m = NULL;
+ goto out;
+ }
+ if (vm_domain_allocate(vmd, req, 1) == 0)
+ m = NULL;
+ else
+ vm_reserv_populate(rv, index);
+out:
+ vm_reserv_unlock(rv);
+ return (m);
+ }
/*
* Could a reservation fit between the first index to the left that