Page MenuHomeFreeBSD

D49460.1790682635.diff
No OneTemporary

Size
6 KB
Referenced Files
None
Subscribers
None

D49460.1790682635.diff

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
@@ -549,6 +549,73 @@
return (((pindex - rv->pindex) & ~(VM_LEVEL_0_NPAGES - 1)) == 0);
}
+/*
+ * How many pages should be in a new allocation that starts at the first page of
+ * the reservation superpage that contains 'first', fits between the allocations
+ * that include 'mpred' and 'msucc', fits within 'object', includes at least
+ * 'minpages' pages, and tries to include every allocated page in a superpage?
+ *
+ * We must synchronize with the reserv object lock to protect the pindex/object
+ * of the resulting reservations against rename while we are inspecting.
+ */
+static u_long
+vm_reserv_num_alloc_pages(vm_object_t object, vm_pindex_t first,
+ u_long minpages, vm_page_t mpred, vm_page_t msucc)
+{
+ vm_pindex_t leftcap, rightcap;
+ vm_reserv_t rv;
+ u_int allocpages;
+
+ allocpages = roundup2(minpages, VM_LEVEL_0_NPAGES);
+
+ vm_reserv_object_lock(object);
+ if (mpred != NULL) {
+ if ((rv = vm_reserv_from_page(mpred))->object != object)
+ leftcap = mpred->pindex + 1;
+ else
+ leftcap = rv->pindex + VM_LEVEL_0_NPAGES;
+ if (leftcap > first)
+ allocpages = 0;
+ }
+ if (minpages < allocpages) {
+ if (msucc == NULL) {
+ /*
+ * Would the last new reservation extend past the end of
+ * the object?
+ *
+ * If the object is unlikely to grow don't allocate a
+ * reservation for the tail.
+ */
+ if ((object->flags & OBJ_ANON) == 0)
+ rightcap = object->size;
+ else
+ rightcap = OBJ_MAX_SIZE;
+ } else {
+ /*
+ * Would the last new reservation extend past the start
+ * of another page or reservation?
+ *
+ * If the object would, don't allocate a reservation for
+ * the tail.
+ */
+ if ((rv = vm_reserv_from_page(msucc))->object != object)
+ rightcap = msucc->pindex;
+ else
+ rightcap = rv->pindex;
+ }
+ if (first + allocpages > rightcap) {
+ /*
+ * A reservation for the last of the requested pages
+ * will not fit. Reduce the size of the upcoming
+ * allocation accordingly.
+ */
+ allocpages = minpages;
+ }
+ }
+ vm_reserv_object_unlock(object);
+ return (allocpages);
+}
+
/*
* Increases the given reservation's population count. Moves the reservation
* to the tail of the partially populated reservation queue.
@@ -623,9 +690,9 @@
struct vm_domain *vmd;
vm_paddr_t pa, size;
vm_page_t m, m_ret, msucc;
- vm_pindex_t first, leftcap, rightcap;
+ vm_pindex_t first;
vm_reserv_t rv;
- u_long allocpages, maxpages, minpages;
+ u_long allocpages;
int i, index, n;
VM_OBJECT_ASSERT_WLOCKED(object);
@@ -690,63 +757,14 @@
}
/*
- * Could at least one reservation fit between the first index to the
- * left that can be used ("leftcap") and the first index to the right
- * that cannot be used ("rightcap")?
- *
- * We must synchronize with the reserv object lock to protect the
- * pindex/object of the resulting reservations against rename while
- * we are inspecting.
+ * Check whether an allocation including at least one reservation can
+ * fit between mpred and msucc.
*/
first = pindex - VM_RESERV_INDEX(object, pindex);
- minpages = VM_RESERV_INDEX(object, pindex) + npages;
- maxpages = roundup2(minpages, VM_LEVEL_0_NPAGES);
- allocpages = maxpages;
- vm_reserv_object_lock(object);
- if (mpred != NULL) {
- if ((rv = vm_reserv_from_page(mpred))->object != object)
- leftcap = mpred->pindex + 1;
- else
- leftcap = rv->pindex + VM_LEVEL_0_NPAGES;
- if (leftcap > first) {
- vm_reserv_object_unlock(object);
- return (NULL);
- }
- }
- if (msucc != NULL) {
- if ((rv = vm_reserv_from_page(msucc))->object != object)
- rightcap = msucc->pindex;
- else
- rightcap = rv->pindex;
- if (first + maxpages > rightcap) {
- if (maxpages == VM_LEVEL_0_NPAGES) {
- vm_reserv_object_unlock(object);
- return (NULL);
- }
-
- /*
- * At least one reservation will fit between "leftcap"
- * and "rightcap". However, a reservation for the
- * last of the requested pages will not fit. Reduce
- * the size of the upcoming allocation accordingly.
- */
- allocpages = minpages;
- }
- }
- vm_reserv_object_unlock(object);
-
- /*
- * Would the last new reservation extend past the end of the object?
- *
- * If the object is unlikely to grow don't allocate a reservation for
- * the tail.
- */
- if ((object->flags & OBJ_ANON) == 0 &&
- first + maxpages > object->size) {
- if (maxpages == VM_LEVEL_0_NPAGES)
- return (NULL);
- allocpages = minpages;
- }
+ allocpages = vm_reserv_num_alloc_pages(object, first,
+ VM_RESERV_INDEX(object, pindex) + npages, mpred, msucc);
+ if (allocpages < VM_LEVEL_0_NPAGES)
+ return (NULL);
/*
* Allocate the physical pages. The alignment and boundary specified
@@ -817,7 +835,7 @@
{
struct vm_domain *vmd;
vm_page_t m, msucc;
- vm_pindex_t first, leftcap, rightcap;
+ vm_pindex_t first;
vm_reserv_t rv;
int index;
@@ -859,45 +877,12 @@
}
/*
- * Could a reservation fit between the first index to the left that
- * can be used and the first index to the right that cannot be used?
- *
- * We must synchronize with the reserv object lock to protect the
- * pindex/object of the resulting reservations against rename while
- * we are inspecting.
+ * Check whether an allocation including reservations can fit
+ * between mpred and msucc.
*/
first = pindex - VM_RESERV_INDEX(object, pindex);
- vm_reserv_object_lock(object);
- if (mpred != NULL) {
- if ((rv = vm_reserv_from_page(mpred))->object != object)
- leftcap = mpred->pindex + 1;
- else
- leftcap = rv->pindex + VM_LEVEL_0_NPAGES;
- if (leftcap > first) {
- vm_reserv_object_unlock(object);
- return (NULL);
- }
- }
- if (msucc != NULL) {
- if ((rv = vm_reserv_from_page(msucc))->object != object)
- rightcap = msucc->pindex;
- else
- rightcap = rv->pindex;
- if (first + VM_LEVEL_0_NPAGES > rightcap) {
- vm_reserv_object_unlock(object);
- return (NULL);
- }
- }
- vm_reserv_object_unlock(object);
-
- /*
- * Would the last new reservation extend past the end of the object?
- *
- * If the object is unlikely to grow don't allocate a reservation for
- * the tail.
- */
- if ((object->flags & OBJ_ANON) == 0 &&
- first + VM_LEVEL_0_NPAGES > object->size)
+ if (vm_reserv_num_alloc_pages(object, first, 1, mpred, msucc) <
+ VM_LEVEL_0_NPAGES)
return (NULL);
/*

File Metadata

Mime Type
text/plain
Expires
Tue, Sep 29, 11:50 AM (5 h, 45 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
30009351
Default Alt Text
D49460.1790682635.diff (6 KB)

Event Timeline