Index: sys/vm/swap_pager.c =================================================================== --- sys/vm/swap_pager.c +++ sys/vm/swap_pager.c @@ -1415,9 +1415,10 @@ * Allocate readahead and readbehind pages. */ if (rbehind != NULL) { + pindex = ma[0]->pindex; for (i = 1; i <= *rbehind; i++) { - p = vm_page_alloc(object, ma[0]->pindex - i, - VM_ALLOC_NORMAL); + p = vm_page_alloc_after(object, pindex - i, + VM_ALLOC_NORMAL, mpred); if (p == NULL) break; p->oflags |= VPO_SWAPINPROG; @@ -1426,9 +1427,11 @@ *rbehind = i - 1; } if (rahead != NULL) { + p = ma[reqcount - 1]; + pindex = p->pindex; for (i = 0; i < *rahead; i++) { - p = vm_page_alloc(object, - ma[reqcount - 1]->pindex + i + 1, VM_ALLOC_NORMAL); + p = vm_page_alloc_after(object, pindex + i + 1, + VM_ALLOC_NORMAL, p); if (p == NULL) break; p->oflags |= VPO_SWAPINPROG; @@ -1982,9 +1985,14 @@ if (m != NULL) { if (!vm_page_busy_acquire(m, VM_ALLOC_WAITFAIL)) break; - } else if ((m = vm_page_alloc(object, blks.index + i, - VM_ALLOC_NORMAL | VM_ALLOC_WAITFAIL)) == NULL) - break; + } else { + m = vm_radix_iter_lookup_le(&pages, + blks.index + i); + m = vm_page_alloc_after(object, blks.index + i, + VM_ALLOC_NORMAL | VM_ALLOC_WAITFAIL, m); + if (m == NULL) + break; + } /* Get the page from swap, and restart the scan. */ vm_object_pip_add(object, 1); Index: sys/vm/vm_page.h =================================================================== --- sys/vm/vm_page.h +++ sys/vm/vm_page.h @@ -608,6 +608,7 @@ 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_contig(vm_object_t object, vm_pindex_t pindex, int req, Index: sys/vm/vm_page.c =================================================================== --- sys/vm/vm_page.c +++ sys/vm/vm_page.c @@ -162,8 +162,6 @@ static uma_zone_t fakepg_zone; -static vm_page_t vm_page_alloc_after(vm_object_t object, vm_pindex_t pindex, - int req, vm_page_t mpred); static void vm_page_alloc_check(vm_page_t m); static vm_page_t vm_page_alloc_nofree_domain(int domain, int req); static bool _vm_page_busy_sleep(vm_object_t obj, vm_page_t m, @@ -2173,7 +2171,7 @@ * the resident page in the object with largest index smaller than the given * page index, or NULL if no such page exists. */ -static vm_page_t +vm_page_t vm_page_alloc_after(vm_object_t object, vm_pindex_t pindex, int req, vm_page_t mpred) { @@ -5045,8 +5043,8 @@ !vm_page_tryxbusy(ma[i])) break; } else { - ma[i] = vm_page_alloc(object, m->pindex + i, - VM_ALLOC_NORMAL); + ma[i] = vm_page_alloc_after(object, + m->pindex + i, VM_ALLOC_NORMAL, ma[i - 1]); if (ma[i] == NULL) break; } @@ -5087,7 +5085,7 @@ } /* - * Fill a partial page with zeroes. The object write lock is held on entry and + * Fill a partial a page with zeroes. The object write lock is held on entry and * exit, but may be temporarily released. */ int Index: sys/vm/vnode_pager.c =================================================================== --- sys/vm/vnode_pager.c +++ sys/vm/vnode_pager.c @@ -1042,19 +1042,20 @@ i = bp->b_npages = 0; if (rbehind) { vm_pindex_t startpindex, tpindex; - vm_page_t p; + vm_page_t mpred, p; VM_OBJECT_WLOCK(object); startpindex = m[0]->pindex - rbehind; - if ((p = TAILQ_PREV(m[0], pglist, listq)) != NULL && - p->pindex >= startpindex) - startpindex = p->pindex + 1; + if ((mpred = TAILQ_PREV(m[0], pglist, listq)) != NULL && + mpred->pindex >= startpindex) + startpindex = mpred->pindex + 1; /* tpindex is unsigned; beware of numeric underflow. */ for (tpindex = m[0]->pindex - 1; tpindex >= startpindex && tpindex < m[0]->pindex; tpindex--, i++) { - p = vm_page_alloc(object, tpindex, VM_ALLOC_NORMAL); + p = vm_page_alloc_after(object, tpindex, + VM_ALLOC_NORMAL, mpred); if (p == NULL) { /* Shift the array. */ for (int j = 0; j < i; j++) @@ -1089,9 +1090,11 @@ if (endpindex > object->size) endpindex = object->size; - for (tpindex = m[count - 1]->pindex + 1; + p = m[count - 1]; + for (tpindex = p->pindex + 1; tpindex < endpindex; i++, tpindex++) { - p = vm_page_alloc(object, tpindex, VM_ALLOC_NORMAL); + p = vm_page_alloc_after(object, tpindex, + VM_ALLOC_NORMAL, p); if (p == NULL) break; bp->b_pages[i] = p;