Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F149672094
D49460.1790682635.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
6 KB
Referenced Files
None
Subscribers
None
D49460.1790682635.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D49460: vm_reserv: extract common gap-checking code
Attached
Detach File
Event Timeline
Log In to Comment