Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/uvm uao_get(): in the PGO_SYNCIO case use uvm_page_array...
details: https://anonhg.NetBSD.org/src/rev/91109ceeff34
branches: trunk
changeset: 933504:91109ceeff34
user: ad <ad%NetBSD.org@localhost>
date: Mon May 25 22:04:51 2020 +0000
description:
uao_get(): in the PGO_SYNCIO case use uvm_page_array and simplify control
flow a little bit.
diffstat:
sys/uvm/uvm_aobj.c | 104 +++++++++++++++++++++++-----------------------------
1 files changed, 46 insertions(+), 58 deletions(-)
diffs (182 lines):
diff -r 34b93a92054a -r 91109ceeff34 sys/uvm/uvm_aobj.c
--- a/sys/uvm/uvm_aobj.c Mon May 25 22:01:26 2020 +0000
+++ b/sys/uvm/uvm_aobj.c Mon May 25 22:04:51 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: uvm_aobj.c,v 1.146 2020/05/25 21:15:10 ad Exp $ */
+/* $NetBSD: uvm_aobj.c,v 1.147 2020/05/25 22:04:51 ad Exp $ */
/*
* Copyright (c) 1998 Chuck Silvers, Charles D. Cranor and
@@ -38,7 +38,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uvm_aobj.c,v 1.146 2020/05/25 21:15:10 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uvm_aobj.c,v 1.147 2020/05/25 22:04:51 ad Exp $");
#ifdef _KERNEL_OPT
#include "opt_uvmhist.h"
@@ -799,10 +799,11 @@
int *npagesp, int centeridx, vm_prot_t access_type, int advice, int flags)
{
voff_t current_offset;
- struct vm_page *ptmp = NULL; /* Quell compiler warning */
- int lcv, gotpages, maxpages, swslot = -1, pageidx = -1; /* XXX: gcc */
+ struct vm_page *ptmp;
+ int lcv, gotpages, maxpages, swslot, pageidx;
UVMHIST_FUNC("uao_get"); UVMHIST_CALLED(pdhist);
bool overwrite = ((flags & PGO_OVERWRITE) != 0);
+ struct uvm_page_array a;
UVMHIST_LOG(pdhist, "aobj=%#jx offset=%jd, flags=%jd",
(uintptr_t)uobj, offset, flags,0);
@@ -828,7 +829,6 @@
*/
if (flags & PGO_LOCKED) {
- struct uvm_page_array a;
/*
* step 1a: get pages that are already resident. only do
@@ -890,8 +890,8 @@
goto done;
}
- for (lcv = 0, current_offset = offset ; lcv < maxpages ;
- lcv++, current_offset += PAGE_SIZE) {
+ uvm_page_array_init(&a, uobj, 0);
+ for (lcv = 0, current_offset = offset ; lcv < maxpages ;) {
/*
* we have yet to locate the current page (pps[lcv]). we
@@ -900,48 +900,14 @@
* released. if that is the case, then we sleep on the page
* until it is no longer busy or released and repeat the lookup.
* if the page we found is neither busy nor released, then we
- * busy it (so we own it) and plug it into pps[lcv]. this
- * 'break's the following while loop and indicates we are
- * ready to move on to the next page in the "lcv" loop above.
- *
- * if we exit the while loop with pps[lcv] set to NULL,
- * then it means that we allocated a new busy/fake/clean page
- * ptmp in the object and we need to do I/O to fill in the data.
+ * busy it (so we own it) and plug it into pps[lcv]. we are
+ * ready to move on to the next page.
*/
- /* top of "pps" while loop */
- for (;;) {
- /* look for a resident page */
- ptmp = uvm_pagelookup(uobj, current_offset);
-
- /* not resident? allocate one now (if we can) */
- if (ptmp == NULL) {
- /* get a zeroed page if not in swap */
- pageidx = current_offset >> PAGE_SHIFT;
- swslot = uao_find_swslot(uobj, pageidx);
- ptmp = uao_pagealloc(uobj, current_offset,
- swslot != 0 || overwrite ? 0 :
- UVM_PGA_ZERO);
+ ptmp = uvm_page_array_fill_and_peek(&a, current_offset,
+ maxpages - lcv);
- /* out of RAM? */
- if (ptmp == NULL) {
- rw_exit(uobj->vmobjlock);
- UVMHIST_LOG(pdhist,
- "sleeping, ptmp == NULL\n",0,0,0,0);
- uvm_wait("uao_getpage");
- rw_enter(uobj->vmobjlock, RW_WRITER);
- continue;
- }
-
- /*
- * got new page ready for I/O. break pps for
- * loop.
- */
-
- pps[lcv] = NULL;
- break;
- }
-
+ if (ptmp != NULL && ptmp->offset == current_offset) {
/* page is there, see if we need to wait on it */
if ((ptmp->flags & PG_BUSY) != 0) {
UVMHIST_LOG(pdhist,
@@ -949,14 +915,15 @@
ptmp->flags,0,0,0);
uvm_pagewait(ptmp, uobj->vmobjlock, "uao_get");
rw_enter(uobj->vmobjlock, RW_WRITER);
+ uvm_page_array_clear(&a);
continue;
}
/*
- * if we get here then the page has become resident and
- * unbusy between steps 1 and 2. we busy it now (so we
- * own it) and set pps[lcv] (so that we exit the while
- * loop).
+ * if we get here then the page is resident and
+ * unbusy. we busy it now (so we own it). if
+ * overwriting, mark the page dirty up front as
+ * it will be zapped via an unmanaged mapping.
*/
KASSERT(uvm_pagegetdirty(ptmp) !=
@@ -967,17 +934,35 @@
/* we own it, caller must un-busy */
ptmp->flags |= PG_BUSY;
UVM_PAGE_OWN(ptmp, "uao_get2");
- pps[lcv] = ptmp;
- break;
+ pps[lcv++] = ptmp;
+ current_offset += PAGE_SIZE;
+ uvm_page_array_advance(&a);
+ continue;
+ } else {
+ KASSERT(ptmp == NULL || ptmp->offset > current_offset);
}
/*
- * if we own the valid page at the correct offset, pps[lcv] will
- * point to it. nothing more to do except go to the next page.
- */
+ * not resident. allocate a new busy/fake/clean page in the
+ * object. if it's in swap we need to do I/O to fill in the
+ * data, otherwise the page needs to be cleared: if it's not
+ * destined to be overwritten, then zero it here and now.
+ */
- if (pps[lcv])
- continue; /* next lcv */
+ pageidx = current_offset >> PAGE_SHIFT;
+ swslot = uao_find_swslot(uobj, pageidx);
+ ptmp = uao_pagealloc(uobj, current_offset,
+ swslot != 0 || overwrite ? 0 : UVM_PGA_ZERO);
+
+ /* out of RAM? */
+ if (ptmp == NULL) {
+ rw_exit(uobj->vmobjlock);
+ UVMHIST_LOG(pdhist, "sleeping, ptmp == NULL\n",0,0,0,0);
+ uvm_wait("uao_getpage");
+ rw_enter(uobj->vmobjlock, RW_WRITER);
+ uvm_page_array_clear(&a);
+ continue;
+ }
/*
* if swslot == 0, page hasn't existed before and is zeroed.
@@ -1061,9 +1046,12 @@
*/
KASSERT(uvm_pagegetdirty(ptmp) != UVM_PAGE_STATUS_CLEAN);
KASSERT((ptmp->flags & PG_FAKE) != 0);
+ KASSERT(ptmp->offset == current_offset);
ptmp->flags &= ~PG_FAKE;
- pps[lcv] = ptmp;
+ pps[lcv++] = ptmp;
+ current_offset += PAGE_SIZE;
}
+ uvm_page_array_fini(&a);
/*
* finally, unlock object and return.
Home |
Main Index |
Thread Index |
Old Index