Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/uvm uvm_loanuobjpages():



details:   https://anonhg.NetBSD.org/src/rev/8d709764c4f2
branches:  trunk
changeset: 972215:8d709764c4f2
user:      ad <ad%NetBSD.org@localhost>
date:      Tue May 19 21:52:04 2020 +0000

description:
uvm_loanuobjpages():

- vmobjlock is shared between tmpfs vnodes and UAOs now
- split into two routines, to simplify
- fix error recovery

diffstat:

 sys/uvm/uvm_loan.c |  150 ++++++++++++++++++++++------------------------------
 1 files changed, 65 insertions(+), 85 deletions(-)

diffs (184 lines):

diff -r 9b7bc672a9f0 -r 8d709764c4f2 sys/uvm/uvm_loan.c
--- a/sys/uvm/uvm_loan.c        Tue May 19 21:45:57 2020 +0000
+++ b/sys/uvm/uvm_loan.c        Tue May 19 21:52:04 2020 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: uvm_loan.c,v 1.101 2020/05/17 19:38:17 ad Exp $        */
+/*     $NetBSD: uvm_loan.c,v 1.102 2020/05/19 21:52:04 ad Exp $        */
 
 /*
  * Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uvm_loan.c,v 1.101 2020/05/17 19:38:17 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uvm_loan.c,v 1.102 2020/05/19 21:52:04 ad Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -505,102 +505,82 @@
 #define        UVM_LOAN_GET_CHUNK      16
 
 /*
+ * uvm_loanuobjchunk: helper for uvm_loanuobjpages()
+ */
+static int
+uvm_loanuobjchunk(struct uvm_object *uobj, voff_t pgoff, int orignpages,
+    struct vm_page **pgpp)
+{
+       int error, npages;
+
+       rw_enter(uobj->vmobjlock, RW_WRITER);
+ reget:
+       npages = orignpages;
+       error = (*uobj->pgops->pgo_get)(uobj, pgoff, pgpp, &npages, 0,
+           VM_PROT_READ, 0, PGO_SYNCIO);
+       switch (error) {
+       case 0:
+               KASSERT(npages == orignpages);
+
+               /* check for released pages */
+               rw_enter(uobj->vmobjlock, RW_WRITER);
+               for (int i = 0; i < npages; i++) {
+                       KASSERT(pgpp[i]->uobject->vmobjlock == uobj->vmobjlock);
+                       if ((pgpp[i]->flags & PG_RELEASED) != 0) {
+                               /*
+                                * release pages and try again.
+                                */
+                               uvm_page_unbusy(pgpp, npages);
+                               goto reget;
+                       }
+               }
+
+               /* loan out pages.  they will be unbusied whatever happens. */
+               error = uvm_loanpage(pgpp, npages, true);
+               rw_exit(uobj->vmobjlock);
+               return error;
+
+       case EAGAIN:
+               kpause("loanuopg", false, hz/2, NULL);
+               rw_enter(uobj->vmobjlock, RW_WRITER);
+               goto reget;
+
+       default:
+               if (npages > 0) {
+                       rw_enter(uobj->vmobjlock, RW_WRITER);
+                       uvm_page_unbusy(pgpp, npages);
+                       rw_exit(uobj->vmobjlock);
+               }
+               return error;
+       }
+}
+
+/*
  * uvm_loanuobjpages: loan pages from a uobj out (O->K)
  *
  * => uobj shouldn't be locked.  (we'll lock it)
  * => fail with EBUSY if we meet a wired page.
  */
 int
-uvm_loanuobjpages(struct uvm_object *uobj, voff_t pgoff, int orignpages,
-    struct vm_page **origpgpp)
+uvm_loanuobjpages(struct uvm_object *uobj, voff_t pgoff, int npages,
+    struct vm_page **pgpp)
 {
-       int ndone; /* # of pages loaned out */
-       struct vm_page **pgpp;
-       int error;
-       int i;
-       krwlock_t *slock;
+       int ndone, error, chunk;
 
-       pgpp = origpgpp;
-       for (ndone = 0; ndone < orignpages; ) {
-               int npages;
-               /* npendloan: # of pages busied but not loand out yet. */
-               int npendloan = 0xdead; /* XXX gcc */
-reget:
-               npages = MIN(UVM_LOAN_GET_CHUNK, orignpages - ndone);
-               rw_enter(uobj->vmobjlock, RW_WRITER);
-               error = (*uobj->pgops->pgo_get)(uobj,
-                   pgoff + (ndone << PAGE_SHIFT), pgpp, &npages, 0,
-                   VM_PROT_READ, 0, PGO_SYNCIO);
-               if (error == EAGAIN) {
-                       kpause("loanuopg", false, hz/2, NULL);
-                       continue;
-               }
-               if (error)
-                       goto fail;
-
-               KASSERT(npages > 0);
-
-               /* loan and unbusy pages */
-               slock = NULL;
-               for (i = 0; i < npages; i++) {
-                       krwlock_t *nextslock; /* slock for next page */
-                       struct vm_page *pg = *pgpp;
-
-                       /* XXX assuming that the page is owned by uobj */
-                       KASSERT(pg->uobject != NULL);
-                       nextslock = pg->uobject->vmobjlock;
+       KASSERT(npages > 0);
 
-                       if (slock != nextslock) {
-                               if (slock) {
-                                       KASSERT(npendloan > 0);
-                                       error = uvm_loanpage(pgpp - npendloan,
-                                           npendloan, true);
-                                       rw_exit(slock);
-                                       if (error)
-                                               goto fail;
-                                       ndone += npendloan;
-                                       KASSERT(origpgpp + ndone == pgpp);
-                               }
-                               slock = nextslock;
-                               npendloan = 0;
-                               rw_enter(slock, RW_WRITER);
+       for (ndone = 0; ndone < npages; ndone += chunk) {
+               chunk = MIN(UVM_LOAN_GET_CHUNK, npages - ndone);
+               error = uvm_loanuobjchunk(uobj, pgoff + (ndone << PAGE_SHIFT),
+                   chunk, pgpp + ndone);
+               if (error != 0) {
+                       if (ndone != 0) {
+                               uvm_unloan(pgpp, ndone, UVM_LOAN_TOPAGE);
                        }
-
-                       if ((pg->flags & PG_RELEASED) != 0) {
-                               /*
-                                * release pages and try again.
-                                */
-                               rw_exit(slock);
-                               for (; i < npages; i++) {
-                                       pg = pgpp[i];
-                                       slock = pg->uobject->vmobjlock;
-
-                                       rw_enter(slock, RW_WRITER);
-                                       uvm_page_unbusy(&pg, 1);
-                                       rw_exit(slock);
-                               }
-                               goto reget;
-                       }
-
-                       npendloan++;
-                       pgpp++;
-                       KASSERT(origpgpp + ndone + npendloan == pgpp);
+                       break;
                }
-               KASSERT(slock != NULL);
-               KASSERT(npendloan > 0);
-               error = uvm_loanpage(pgpp - npendloan, npendloan, true);
-               rw_exit(slock);
-               if (error)
-                       goto fail;
-               ndone += npendloan;
-               KASSERT(origpgpp + ndone == pgpp);
        }
 
-       return 0;
-
-fail:
-       uvm_unloan(origpgpp, ndone, UVM_LOAN_TOPAGE);
-
        return error;
 }
 



Home | Main Index | Thread Index | Old Index