Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F115840863
D49688.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
20 KB
Referenced Files
None
Subscribers
None
D49688.diff
View Options
diff --git a/sys/vm/phys_pager.c b/sys/vm/phys_pager.c
--- a/sys/vm/phys_pager.c
+++ b/sys/vm/phys_pager.c
@@ -33,6 +33,7 @@
#include <sys/proc.h>
#include <sys/mutex.h>
#include <sys/mman.h>
+#include <sys/pctrie.h>
#include <sys/rwlock.h>
#include <sys/sysctl.h>
#include <sys/user.h>
@@ -230,10 +231,12 @@
int fault_type __unused, vm_prot_t max_prot __unused, vm_pindex_t *first,
vm_pindex_t *last)
{
+ struct pctrie_iter pages;
vm_page_t m;
vm_pindex_t base, end, i;
int ahead;
+ VM_OBJECT_ASSERT_WLOCKED(object);
base = rounddown(pidx, phys_pager_cluster);
end = base + phys_pager_cluster - 1;
if (end >= object->size)
@@ -244,10 +247,11 @@
end = *last;
*first = base;
*last = end;
+ vm_page_iter_init(&pages, object);
for (i = base; i <= end; i++) {
ahead = MIN(end - i, PHYSALLOC);
- m = vm_page_grab(object, i,
+ m = vm_page_grab_iter(object, &pages, i,
VM_ALLOC_NORMAL | VM_ALLOC_COUNT(ahead));
if (!vm_page_all_valid(m))
vm_page_zero_invalid(m, TRUE);
diff --git a/sys/vm/swap_pager.c b/sys/vm/swap_pager.c
--- a/sys/vm/swap_pager.c
+++ b/sys/vm/swap_pager.c
@@ -1935,9 +1935,10 @@
if (!vm_page_busy_acquire(m, VM_ALLOC_WAITFAIL))
break;
} else {
- m = vm_radix_iter_lookup_le(&pages,
+ m = vm_radix_iter_lookup_lt(&pages,
blks.index + i);
- m = vm_page_alloc_after(object, blks.index + i,
+ m = vm_page_alloc_after(
+ object, &pages, blks.index + i,
VM_ALLOC_NORMAL | VM_ALLOC_WAITFAIL, m);
if (m == NULL)
break;
diff --git a/sys/vm/vm_fault.c b/sys/vm/vm_fault.c
--- a/sys/vm/vm_fault.c
+++ b/sys/vm/vm_fault.c
@@ -1292,7 +1292,7 @@
vm_fault_unlock_and_deallocate(fs);
return (FAULT_FAILURE);
}
- fs->m = vm_page_alloc_after(fs->object, fs->pindex,
+ fs->m = vm_page_alloc_after(fs->object, pages, fs->pindex,
P_KILLED(curproc) ? VM_ALLOC_SYSTEM : 0,
vm_radix_iter_lookup_lt(pages, fs->pindex));
}
@@ -2100,6 +2100,7 @@
vm_map_entry_t dst_entry, vm_map_entry_t src_entry,
vm_ooffset_t *fork_charge)
{
+ struct pctrie_iter pages;
vm_object_t backing_object, dst_object, object, src_object;
vm_pindex_t dst_pindex, pindex, src_pindex;
vm_prot_t access, prot;
@@ -2176,6 +2177,7 @@
* with the source object, all of its pages must be dirtied,
* regardless of whether they can be written.
*/
+ vm_page_iter_init(&pages, dst_object);
mpred = (src_object == dst_object) ?
vm_page_mpred(src_object, src_pindex) : NULL;
for (vaddr = dst_entry->start, dst_pindex = 0;
@@ -2220,14 +2222,15 @@
*/
pindex = (src_object == dst_object ? src_pindex : 0) +
dst_pindex;
- dst_m = vm_page_alloc_after(dst_object, pindex,
+ dst_m = vm_page_alloc_after(dst_object, &pages, pindex,
VM_ALLOC_NORMAL, mpred);
if (dst_m == NULL) {
VM_OBJECT_WUNLOCK(dst_object);
VM_OBJECT_RUNLOCK(object);
vm_wait(dst_object);
VM_OBJECT_WLOCK(dst_object);
- mpred = vm_page_mpred(dst_object, pindex);
+ pctrie_iter_reset(&pages);
+ mpred = vm_radix_iter_lookup_lt(&pages, pindex);
goto again;
}
@@ -2249,8 +2252,11 @@
VM_OBJECT_RUNLOCK(object);
} else {
dst_m = src_m;
- if (vm_page_busy_acquire(dst_m, VM_ALLOC_WAITFAIL) == 0)
+ if (vm_page_busy_acquire(
+ dst_m, VM_ALLOC_WAITFAIL) == 0) {
+ pctrie_iter_reset(&pages);
goto again;
+ }
if (dst_m->pindex >= dst_object->size) {
/*
* We are upgrading. Index can occur
diff --git a/sys/vm/vm_glue.c b/sys/vm/vm_glue.c
--- a/sys/vm/vm_glue.c
+++ b/sys/vm/vm_glue.c
@@ -98,6 +98,7 @@
#include <vm/vm_pagequeue.h>
#include <vm/vm_object.h>
#include <vm/vm_kern.h>
+#include <vm/vm_radix.h>
#include <vm/vm_extern.h>
#include <vm/vm_pager.h>
#include <vm/vm_phys.h>
@@ -611,40 +612,36 @@
vm_thread_stack_back(vm_offset_t ks, vm_page_t ma[], int npages, int req_class,
int domain)
{
+ struct pctrie_iter pages;
vm_object_t obj = vm_thread_kstack_size_to_obj(npages);
vm_pindex_t pindex;
- vm_page_t m;
+ vm_page_t m, mpred;
int n;
pindex = vm_kstack_pindex(ks, npages);
+ vm_page_iter_init(&pages, obj);
VM_OBJECT_WLOCK(obj);
- for (n = 0; n < npages;) {
- m = vm_page_grab(obj, pindex + n,
+ for (n = 0; n < npages; ma[n++] = m) {
+ m = vm_page_grab_iter(obj, &pages, pindex + n,
VM_ALLOC_NOCREAT | VM_ALLOC_WIRED);
- if (m == NULL) {
- m = n > 0 ? ma[n - 1] : vm_page_mpred(obj, pindex);
- m = vm_page_alloc_domain_after(obj, pindex + n, domain,
- req_class | VM_ALLOC_WIRED, m);
+ if (m != NULL)
+ continue;
+ mpred = (n > 0) ? ma[n - 1] :
+ vm_radix_iter_lookup_lt(&pages, pindex);
+ m = vm_page_alloc_domain_after(obj, &pages, pindex + n,
+ domain, req_class | VM_ALLOC_WIRED, mpred);
+ if (m != NULL)
+ continue;
+ for (int i = 0; i < n; i++) {
+ m = ma[i];
+ (void)vm_page_unwire_noq(m);
+ vm_page_free(m);
}
- if (m == NULL)
- break;
- ma[n++] = m;
+ break;
}
- if (n < npages)
- goto cleanup;
VM_OBJECT_WUNLOCK(obj);
-
- return (0);
-cleanup:
- for (int i = 0; i < n; i++) {
- m = ma[i];
- (void)vm_page_unwire_noq(m);
- vm_page_free(m);
- }
- VM_OBJECT_WUNLOCK(obj);
-
- return (ENOMEM);
+ return (n < npages ? ENOMEM : 0);
}
static vm_object_t
diff --git a/sys/vm/vm_kern.c b/sys/vm/vm_kern.c
--- a/sys/vm/vm_kern.c
+++ b/sys/vm/vm_kern.c
@@ -530,6 +530,7 @@
kmem_back_domain(int domain, vm_object_t object, vm_offset_t addr,
vm_size_t size, int flags)
{
+ struct pctrie_iter pages;
vm_offset_t offset, i;
vm_page_t m, mpred;
vm_prot_t prot;
@@ -546,11 +547,12 @@
prot = (flags & M_EXEC) != 0 ? VM_PROT_ALL : VM_PROT_RW;
i = 0;
+ vm_page_iter_init(&pages, object);
VM_OBJECT_WLOCK(object);
retry:
- mpred = vm_radix_lookup_le(&object->rtree, atop(offset + i));
+ mpred = vm_radix_iter_lookup_lt(&pages, atop(offset + i));
for (; i < size; i += PAGE_SIZE, mpred = m) {
- m = vm_page_alloc_domain_after(object, atop(offset + i),
+ m = vm_page_alloc_domain_after(object, &pages, atop(offset + i),
domain, pflags, mpred);
/*
diff --git a/sys/vm/vm_object.c b/sys/vm/vm_object.c
--- a/sys/vm/vm_object.c
+++ b/sys/vm/vm_object.c
@@ -2275,19 +2275,21 @@
vm_object_prepare_buf_pages(vm_object_t object, vm_page_t *ma_dst, int count,
int *rbehind, int *rahead, vm_page_t *ma_src)
{
+ struct pctrie_iter pages;
vm_pindex_t pindex;
vm_page_t m, mpred, msucc;
+ vm_page_iter_init(&pages, object);
VM_OBJECT_ASSERT_LOCKED(object);
if (*rbehind != 0) {
m = ma_src[0];
pindex = m->pindex;
- mpred = TAILQ_PREV(m, pglist, listq);
+ mpred = vm_radix_iter_lookup_lt(&pages, pindex);
*rbehind = MIN(*rbehind,
pindex - (mpred != NULL ? mpred->pindex + 1 : 0));
/* Stepping backward from pindex, mpred doesn't change. */
for (int i = 0; i < *rbehind; i++) {
- m = vm_page_alloc_after(object, pindex - i - 1,
+ m = vm_page_alloc_after(object, &pages, pindex - i - 1,
VM_ALLOC_NORMAL, mpred);
if (m == NULL) {
/* Shift the array. */
@@ -2305,12 +2307,12 @@
if (*rahead != 0) {
m = ma_src[count - 1];
pindex = m->pindex + 1;
- msucc = TAILQ_NEXT(m, listq);
+ msucc = vm_radix_iter_lookup_ge(&pages, pindex);
*rahead = MIN(*rahead,
(msucc != NULL ? msucc->pindex : object->size) - pindex);
mpred = m;
for (int i = 0; i < *rahead; i++) {
- m = vm_page_alloc_after(object, pindex + i,
+ m = vm_page_alloc_after(object, &pages, pindex + i,
VM_ALLOC_NORMAL, mpred);
if (m == NULL) {
*rahead = i;
diff --git a/sys/vm/vm_page.h b/sys/vm/vm_page.h
--- a/sys/vm/vm_page.h
+++ b/sys/vm/vm_page.h
@@ -608,9 +608,10 @@
void vm_page_advise(vm_page_t m, int advice);
vm_page_t vm_page_mpred(vm_object_t, vm_pindex_t);
vm_page_t vm_page_alloc(vm_object_t, vm_pindex_t, int);
-vm_page_t vm_page_alloc_after(vm_object_t, vm_pindex_t, int, vm_page_t);
-vm_page_t vm_page_alloc_domain_after(vm_object_t, vm_pindex_t, int, int,
- vm_page_t);
+vm_page_t vm_page_alloc_after(vm_object_t, struct pctrie_iter *, vm_pindex_t,
+ int, vm_page_t);
+vm_page_t vm_page_alloc_domain_after(vm_object_t, struct pctrie_iter *,
+ vm_pindex_t, int, int, vm_page_t);
vm_page_t vm_page_alloc_contig(vm_object_t object, vm_pindex_t pindex, int req,
u_long npages, vm_paddr_t low, vm_paddr_t high, u_long alignment,
vm_paddr_t boundary, vm_memattr_t memattr);
@@ -631,6 +632,8 @@
int vm_page_grab_zero_partial(vm_object_t object, vm_pindex_t pindex, int base,
int end);
vm_page_t vm_page_grab(vm_object_t, vm_pindex_t, int);
+vm_page_t vm_page_grab_iter(vm_object_t object, struct pctrie_iter *pages, vm_pindex_t pindex,
+ int allocflags);
vm_page_t vm_page_grab_unlocked(vm_object_t, vm_pindex_t, int);
int vm_page_grab_pages(vm_object_t object, vm_pindex_t pindex, int allocflags,
vm_page_t *ma, int count);
diff --git a/sys/vm/vm_page.c b/sys/vm/vm_page.c
--- a/sys/vm/vm_page.c
+++ b/sys/vm/vm_page.c
@@ -171,8 +171,6 @@
static bool vm_page_free_prep(vm_page_t m);
static void vm_page_free_toq(vm_page_t m);
static void vm_page_init(void *dummy);
-static int vm_page_insert_after(vm_page_t m, vm_object_t object,
- vm_pindex_t pindex, vm_page_t mpred);
static void vm_page_insert_radixdone(vm_page_t m, vm_object_t object,
vm_page_t mpred);
static void vm_page_mvqueue(vm_page_t m, const uint8_t queue,
@@ -1473,18 +1471,17 @@
/*
* Insert the given page into the given object at the given pindex. mpred is
- * used for memq linkage. From vm_page_insert, lookup is true, mpred is
- * initially NULL, and this procedure looks it up. From vm_page_insert_after
- * and vm_page_iter_insert, lookup is false and mpred is known to the caller
- * to be valid, and may be NULL if this will be the page with the lowest
- * pindex.
+ * used for memq linkage. From vm_page_insert, iter is false, mpred is
+ * initially NULL, and this procedure looks it up. From vm_page_iter_insert,
+ * iter is true and mpred is known to the caller to be valid, and may be NULL if
+ * this will be the page with the lowest pindex.
*
* The procedure is marked __always_inline to suggest to the compiler to
* eliminate the lookup parameter and the associated alternate branch.
*/
static __always_inline int
vm_page_insert_lookup(vm_page_t m, vm_object_t object, vm_pindex_t pindex,
- struct pctrie_iter *pages, bool iter, vm_page_t mpred, bool lookup)
+ struct pctrie_iter *pages, bool iter, vm_page_t mpred)
{
int error;
@@ -1503,13 +1500,10 @@
* Add this page to the object's radix tree, and look up mpred if
* needed.
*/
- if (iter) {
- KASSERT(!lookup, ("%s: cannot lookup mpred", __func__));
+ if (iter)
error = vm_radix_iter_insert(pages, m);
- } else if (lookup)
- error = vm_radix_insert_lookup_lt(&object->rtree, m, &mpred);
else
- error = vm_radix_insert(&object->rtree, m);
+ error = vm_radix_insert_lookup_lt(&object->rtree, m, &mpred);
if (__predict_false(error != 0)) {
m->object = NULL;
m->pindex = 0;
@@ -1535,26 +1529,7 @@
int
vm_page_insert(vm_page_t m, vm_object_t object, vm_pindex_t pindex)
{
- return (vm_page_insert_lookup(m, object, pindex, NULL, false, NULL,
- true));
-}
-
-/*
- * vm_page_insert_after:
- *
- * Inserts the page "m" into the specified object at offset "pindex".
- *
- * The page "mpred" must immediately precede the offset "pindex" within
- * the specified object.
- *
- * The object must be locked.
- */
-static int
-vm_page_insert_after(vm_page_t m, vm_object_t object, vm_pindex_t pindex,
- vm_page_t mpred)
-{
- return (vm_page_insert_lookup(m, object, pindex, NULL, false, mpred,
- false));
+ return (vm_page_insert_lookup(m, object, pindex, NULL, false, NULL));
}
/*
@@ -1573,8 +1548,7 @@
vm_page_iter_insert(struct pctrie_iter *pages, vm_page_t m, vm_object_t object,
vm_pindex_t pindex, vm_page_t mpred)
{
- return (vm_page_insert_lookup(m, object, pindex, pages, true, mpred,
- false));
+ return (vm_page_insert_lookup(m, object, pindex, pages, true, mpred));
}
/*
@@ -2125,8 +2099,10 @@
vm_page_t
vm_page_alloc(vm_object_t object, vm_pindex_t pindex, int req)
{
+ struct pctrie_iter pages;
- return (vm_page_alloc_after(object, pindex, req,
+ vm_page_iter_init(&pages, object);
+ return (vm_page_alloc_after(object, &pages, pindex, req,
vm_page_mpred(object, pindex)));
}
@@ -2137,8 +2113,8 @@
* page index, or NULL if no such page exists.
*/
vm_page_t
-vm_page_alloc_after(vm_object_t object, vm_pindex_t pindex,
- int req, vm_page_t mpred)
+vm_page_alloc_after(vm_object_t object, struct pctrie_iter *pages,
+ vm_pindex_t pindex, int req, vm_page_t mpred)
{
struct vm_domainset_iter di;
vm_page_t m;
@@ -2146,8 +2122,8 @@
vm_domainset_iter_page_init(&di, object, pindex, &domain, &req);
do {
- m = vm_page_alloc_domain_after(object, pindex, domain, req,
- mpred);
+ m = vm_page_alloc_domain_after(object, pages, pindex, domain,
+ req, mpred);
if (m != NULL)
break;
} while (vm_domainset_iter_page(&di, object, &domain) == 0);
@@ -2209,8 +2185,8 @@
}
vm_page_t
-vm_page_alloc_domain_after(vm_object_t object, vm_pindex_t pindex, int domain,
- int req, vm_page_t mpred)
+vm_page_alloc_domain_after(vm_object_t object, struct pctrie_iter *pages,
+ vm_pindex_t pindex, int domain, int req, vm_page_t mpred)
{
struct vm_domain *vmd;
vm_page_t m;
@@ -2279,6 +2255,7 @@
/*
* Not allocatable, give up.
*/
+ pctrie_iter_reset(pages);
if (vm_domain_alloc_fail(vmd, object, req))
goto again;
return (NULL);
@@ -2315,7 +2292,7 @@
}
m->a.act_count = 0;
- if (vm_page_insert_after(m, object, pindex, mpred)) {
+ if (vm_page_insert_lookup(m, object, pindex, pages, true, mpred)) {
if (req & VM_ALLOC_WIRED) {
vm_wire_sub(1);
m->ref_count = 0;
@@ -2328,6 +2305,7 @@
if (req & VM_ALLOC_WAITFAIL) {
VM_OBJECT_WUNLOCK(object);
vm_radix_wait();
+ pctrie_iter_reset(pages);
VM_OBJECT_WLOCK(object);
}
return (NULL);
@@ -2471,7 +2449,7 @@
KASSERT(npages > 0, ("vm_page_alloc_contig: npages is zero"));
vm_page_iter_init(&pages, object);
- mpred = vm_radix_iter_lookup_le(&pages, pindex);
+ mpred = vm_radix_iter_lookup_lt(&pages, pindex);
KASSERT(mpred == NULL || mpred->pindex != pindex,
("vm_page_alloc_contig: pindex already allocated"));
for (;;) {
@@ -4875,32 +4853,32 @@
}
/*
- * Grab a page. Keep on waiting, as long as the page exists in the object. If
- * the page doesn't exist, first allocate it and then conditionally zero it.
+ * Grab a page. Use an iterator parameter. Keep on waiting, as long as the page
+ * exists in the object. If the page doesn't exist, first allocate it and then
+ * conditionally zero it.
*
* The object must be locked on entry. This routine may sleep. The lock will,
* however, be released and reacquired if the routine sleeps.
*/
vm_page_t
-vm_page_grab(vm_object_t object, vm_pindex_t pindex, int allocflags)
+vm_page_grab_iter(vm_object_t object, struct pctrie_iter *pages,
+ vm_pindex_t pindex, int allocflags)
{
- struct pctrie_iter pages;
vm_page_t m, mpred;
bool found;
VM_OBJECT_ASSERT_WLOCKED(object);
vm_page_grab_check(allocflags);
- vm_page_iter_init(&pages, object);
while ((m = vm_page_grab_lookup(
- &pages, object, pindex, allocflags, &found)) == NULL) {
+ pages, object, pindex, allocflags, &found)) == NULL) {
if ((allocflags & VM_ALLOC_NOCREAT) != 0)
return (NULL);
if (found &&
(allocflags & (VM_ALLOC_NOWAIT | VM_ALLOC_WAITFAIL)) != 0)
return (NULL);
- mpred = vm_radix_iter_lookup_le(&pages, pindex);
- m = vm_page_alloc_after(object, pindex,
+ mpred = vm_radix_iter_lookup_lt(pages, pindex);
+ m = vm_page_alloc_after(object, pages, pindex,
vm_page_grab_pflags(allocflags), mpred);
if (m != NULL) {
if ((allocflags & VM_ALLOC_ZERO) != 0 &&
@@ -4911,13 +4889,29 @@
if ((allocflags &
(VM_ALLOC_NOWAIT | VM_ALLOC_WAITFAIL)) != 0)
return (NULL);
- pctrie_iter_reset(&pages);
}
vm_page_grab_release(m, allocflags);
return (m);
}
+/*
+ * Grab a page. Keep on waiting, as long as the page exists in the object. If
+ * the page doesn't exist, first allocate it and then conditionally zero it.
+ *
+ * The object must be locked on entry. This routine may sleep. The lock will,
+ * however, be released and reacquired if the routine sleeps.
+ */
+vm_page_t
+vm_page_grab(vm_object_t object, vm_pindex_t pindex, int allocflags)
+{
+ struct pctrie_iter pages;
+
+ VM_OBJECT_ASSERT_WLOCKED(object);
+ vm_page_iter_init(&pages, object);
+ return (vm_page_grab_iter(object, &pages, pindex, allocflags));
+}
+
/*
* Attempt to validate a page, locklessly acquiring it if necessary, given a
* (object, pindex) tuple and either an invalided page or NULL. The resulting
@@ -4998,9 +4992,11 @@
* will neither be wired nor busy regardless of allocflags.
*/
int
-vm_page_grab_valid(vm_page_t *mp, vm_object_t object, vm_pindex_t pindex, int allocflags)
+vm_page_grab_valid(vm_page_t *mp, vm_object_t object, vm_pindex_t pindex,
+ int allocflags)
{
- vm_page_t m;
+ struct pctrie_iter pages;
+ vm_page_t m, mpred;
vm_page_t ma[VM_INITIAL_PAGEIN];
int after, i, pflags, rv;
@@ -5014,9 +5010,10 @@
pflags = allocflags & ~(VM_ALLOC_NOBUSY | VM_ALLOC_SBUSY |
VM_ALLOC_WIRED | VM_ALLOC_IGN_SBUSY);
pflags |= VM_ALLOC_WAITFAIL;
+ vm_page_iter_init(&pages, object);
retrylookup:
- if ((m = vm_page_lookup(object, pindex)) != NULL) {
+ if ((m = vm_radix_iter_lookup(&pages, pindex)) != NULL) {
/*
* If the page is fully valid it can only become invalid
* with the object lock held. If it is not valid it can
@@ -5030,6 +5027,7 @@
vm_page_all_valid(m) ? allocflags : 0)) {
(void)vm_page_grab_sleep(object, m, pindex, "pgrbwt",
allocflags, true);
+ pctrie_iter_reset(&pages);
goto retrylookup;
}
if (vm_page_all_valid(m))
@@ -5042,12 +5040,16 @@
} else if ((allocflags & VM_ALLOC_NOCREAT) != 0) {
*mp = NULL;
return (VM_PAGER_FAIL);
- } else if ((m = vm_page_alloc(object, pindex, pflags)) == NULL) {
- if (!vm_pager_can_alloc_page(object, pindex)) {
- *mp = NULL;
- return (VM_PAGER_AGAIN);
+ } else {
+ mpred = vm_radix_iter_lookup_lt(&pages, pindex);
+ m = vm_page_alloc_after(object, &pages, pindex, pflags, mpred);
+ if (m == NULL) {
+ if (!vm_pager_can_alloc_page(object, pindex)) {
+ *mp = NULL;
+ return (VM_PAGER_AGAIN);
+ }
+ goto retrylookup;
}
- goto retrylookup;
}
vm_page_assert_xbusied(m);
@@ -5055,18 +5057,17 @@
after = MIN(after, VM_INITIAL_PAGEIN);
after = MIN(after, allocflags >> VM_ALLOC_COUNT_SHIFT);
after = MAX(after, 1);
- ma[0] = m;
+ ma[0] = mpred = m;
for (i = 1; i < after; i++) {
- if ((ma[i] = vm_page_next(ma[i - 1])) != NULL) {
- if (vm_page_any_valid(ma[i]) ||
- !vm_page_tryxbusy(ma[i]))
- break;
- } else {
- ma[i] = vm_page_alloc_after(object,
- m->pindex + i, VM_ALLOC_NORMAL, ma[i - 1]);
- if (ma[i] == NULL)
+ m = vm_radix_iter_lookup(&pages, pindex + i);
+ if (m == NULL) {
+ m = vm_page_alloc_after(object, &pages,
+ pindex + i, VM_ALLOC_NORMAL, mpred);
+ if (m == NULL)
break;
- }
+ } else if (vm_page_any_valid(m) || !vm_page_tryxbusy(m))
+ break;
+ mpred = ma[i] = m;
}
after = i;
vm_object_pip_add(object, after);
@@ -5131,8 +5132,8 @@
&pages, object, pindex, allocflags, &found)) == NULL) {
if (!vm_pager_has_page(object, pindex, NULL, NULL))
return (0);
- mpred = vm_radix_iter_lookup_le(&pages, pindex);
- m = vm_page_alloc_after(object, pindex,
+ mpred = vm_radix_iter_lookup_lt(&pages, pindex);
+ m = vm_page_alloc_after(object, &pages, pindex,
vm_page_grab_pflags(allocflags), mpred);
if (m != NULL) {
vm_object_pip_add(object, 1);
@@ -5154,7 +5155,6 @@
vm_page_launder(m);
break;
}
- pctrie_iter_reset(&pages);
}
pmap_zero_page_area(m, base, end - base);
@@ -5244,6 +5244,7 @@
vm_page_grab_pages(vm_object_t object, vm_pindex_t pindex, int allocflags,
vm_page_t *ma, int count)
{
+ struct pctrie_iter pages;
vm_page_t m, mpred;
int pflags;
int i;
@@ -5257,25 +5258,24 @@
pflags = vm_page_grab_pflags(allocflags);
i = 0;
+ vm_page_iter_init(&pages, object);
retrylookup:
- m = vm_page_mpred(object, pindex + i);
- if (m == NULL || m->pindex != pindex + i) {
- mpred = m;
- m = NULL;
- } else
- mpred = TAILQ_PREV(m, pglist, listq);
+ mpred = vm_radix_iter_lookup_lt(&pages, pindex + i);
for (; i < count; i++) {
+ m = vm_radix_iter_lookup(&pages, pindex + i);
if (m != NULL) {
if (!vm_page_tryacquire(m, allocflags)) {
if (vm_page_grab_sleep(object, m, pindex + i,
- "grbmaw", allocflags, true))
+ "grbmaw", allocflags, true)) {
+ pctrie_iter_reset(&pages);
goto retrylookup;
+ }
break;
}
} else {
if ((allocflags & VM_ALLOC_NOCREAT) != 0)
break;
- m = vm_page_alloc_after(object, pindex + i,
+ m = vm_page_alloc_after(object, &pages, pindex + i,
pflags | VM_ALLOC_COUNT(count - i), mpred);
if (m == NULL) {
if ((allocflags & (VM_ALLOC_NOWAIT |
@@ -5292,7 +5292,6 @@
}
vm_page_grab_release(m, allocflags);
ma[i] = mpred = m;
- m = vm_page_next(m);
}
return (i);
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Apr 30, 10:07 AM (2 h, 5 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
17855885
Default Alt Text
D49688.diff (20 KB)
Attached To
Mode
D49688: vm_page: uses iterators in page allocaction
Attached
Detach File
Event Timeline
Log In to Comment