Page MenuHomeFreeBSD

D49688.diff
No OneTemporary

D49688.diff

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

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)

Event Timeline