Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F115841440
D49688.id153440.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
18 KB
Referenced Files
None
Subscribers
None
D49688.id153440.diff
View Options
Index: sys/vm/phys_pager.c
===================================================================
--- sys/vm/phys_pager.c
+++ 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);
Index: sys/vm/swap_pager.c
===================================================================
--- sys/vm/swap_pager.c
+++ 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;
Index: sys/vm/vm_fault.c
===================================================================
--- sys/vm/vm_fault.c
+++ 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));
}
@@ -2087,6 +2087,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;
@@ -2163,6 +2164,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;
@@ -2207,14 +2209,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;
}
Index: sys/vm/vm_glue.c
===================================================================
--- sys/vm/vm_glue.c
+++ 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
Index: sys/vm/vm_kern.c
===================================================================
--- sys/vm/vm_kern.c
+++ 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);
/*
Index: sys/vm/vm_object.c
===================================================================
--- sys/vm/vm_object.c
+++ 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;
Index: sys/vm/vm_page.h
===================================================================
--- sys/vm/vm_page.h
+++ 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);
Index: sys/vm/vm_page.c
===================================================================
--- sys/vm/vm_page.c
+++ 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,
@@ -1539,24 +1537,6 @@
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));
-}
-
/*
* vm_page_iter_insert:
*
@@ -2125,8 +2105,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 +2119,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,7 +2128,7 @@
vm_domainset_iter_page_init(&di, object, pindex, &domain, &req);
do {
- m = vm_page_alloc_domain_after(object, pindex, domain, req,
+ m = vm_page_alloc_domain_after(object, pages, pindex, domain, req,
mpred);
if (m != NULL)
break;
@@ -2209,8 +2191,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;
@@ -2315,7 +2297,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, false)) {
if (req & VM_ALLOC_WIRED) {
vm_wire_sub(1);
m->ref_count = 0;
@@ -2471,7 +2453,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 (;;) {
@@ -4846,32 +4828,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 &&
@@ -4882,13 +4864,30 @@
if ((allocflags &
(VM_ALLOC_NOWAIT | VM_ALLOC_WAITFAIL)) != 0)
return (NULL);
- pctrie_iter_reset(&pages);
+ 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
@@ -4969,9 +4968,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;
@@ -4985,9 +4986,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
@@ -5001,6 +5003,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))
@@ -5013,12 +5016,17 @@
} 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);
+ }
+ pctrie_iter_reset(&pages);
+ goto retrylookup;
}
- goto retrylookup;
}
vm_page_assert_xbusied(m);
@@ -5026,18 +5034,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);
@@ -5102,8 +5109,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);
@@ -5215,6 +5222,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;
@@ -5228,30 +5236,30 @@
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 |
VM_ALLOC_WAITFAIL)) != 0)
break;
+ pctrie_iter_reset(&pages);
goto retrylookup;
}
}
@@ -5263,7 +5271,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:18 AM (24 m, 14 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
17856067
Default Alt Text
D49688.id153440.diff (18 KB)
Attached To
Mode
D49688: vm_page: uses iterators in page allocaction
Attached
Detach File
Event Timeline
Log In to Comment