Source-Changes-HG archive

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

[src/trunk]: src/sys/uvm revert uvm_fault.c 1.104 for now. see PR/28372, PR/...



details:   https://anonhg.NetBSD.org/src/rev/0c567dc2cc18
branches:  trunk
changeset: 587602:0c567dc2cc18
user:      yamt <yamt%NetBSD.org@localhost>
date:      Mon Jan 30 11:50:17 2006 +0000

description:
revert uvm_fault.c 1.104 for now.  see PR/28372, PR/32665.

diffstat:

 sys/uvm/uvm_fault.c |  289 ++++++++++++++++++---------------------------------
 1 files changed, 102 insertions(+), 187 deletions(-)

diffs (truncated from 434 to 300 lines):

diff -r 89b07f52f407 -r 0c567dc2cc18 sys/uvm/uvm_fault.c
--- a/sys/uvm/uvm_fault.c       Mon Jan 30 04:25:44 2006 +0000
+++ b/sys/uvm/uvm_fault.c       Mon Jan 30 11:50:17 2006 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: uvm_fault.c,v 1.104 2006/01/21 13:13:07 yamt Exp $     */
+/*     $NetBSD: uvm_fault.c,v 1.105 2006/01/30 11:50:17 yamt Exp $     */
 
 /*
  *
@@ -39,7 +39,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uvm_fault.c,v 1.104 2006/01/21 13:13:07 yamt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uvm_fault.c,v 1.105 2006/01/30 11:50:17 yamt Exp $");
 
 #include "opt_uvmhist.h"
 
@@ -536,143 +536,6 @@
 }
 
 /*
- * uvmfault_promote: promote data to a new anon.  used for 1B and 2B.
- *
- *     1. allocate an anon and a page.
- *     2. fill its contents.
- *     3. put it into amap.
- *
- * => if we fail (result != 0) we unlock everything.
- * => on success, return a new locked anon via 'nanon'.
- *    (*nanon)->an_page will be a resident, locked, dirty page.
- */
-
-static int
-uvmfault_promote(struct uvm_faultinfo *ufi,
-    struct vm_anon *oanon,
-    struct vm_page *uobjpage,
-    struct vm_anon **nanon, /* OUT: allocated anon */
-    struct vm_anon **spare)
-{
-       struct vm_amap *amap = ufi->entry->aref.ar_amap;
-       struct uvm_object *uobj;
-       struct vm_anon *anon;
-       struct vm_page *pg;
-       struct vm_page *opg;
-       int error;
-       UVMHIST_FUNC(__func__); UVMHIST_CALLED(maphist);
-
-       if (oanon) {
-               /* anon COW */
-               opg = oanon->an_page;
-               KASSERT(opg != NULL);
-               KASSERT(opg->uobject == NULL || opg->loan_count > 0);
-       } else if (uobjpage != PGO_DONTCARE) {
-               /* object-backed COW */
-               opg = uobjpage;
-               KASSERT(opg->uobject == ufi->entry->object.uvm_obj);
-       } else {
-               /* ZFOD */
-               opg = NULL;
-       }
-       if (opg != NULL) {
-               uobj = opg->uobject;
-       } else {
-               uobj = NULL;
-       }
-
-       KASSERT(amap != NULL);
-       KASSERT(uobjpage != NULL);
-       KASSERT(uobjpage == PGO_DONTCARE || (uobjpage->flags & PG_BUSY) != 0);
-       LOCK_ASSERT(simple_lock_held(&amap->am_l));
-       LOCK_ASSERT(oanon == NULL || simple_lock_held(&oanon->an_lock));
-       LOCK_ASSERT(uobj == NULL || simple_lock_held(&uobj->vmobjlock));
-       LOCK_ASSERT(*spare == NULL || !simple_lock_held(&(*spare)->an_lock));
-
-       if (*spare != NULL) {
-               anon = *spare;
-               *spare = NULL;
-               simple_lock(&anon->an_lock);
-       } else if (ufi->map != kernel_map) {
-               anon = uvm_analloc();
-       } else {
-               UVMHIST_LOG(maphist, "kernel_map, unlock and retry", 0,0,0,0);
-
-               /*
-                * we can't allocate anons with kernel_map locked.
-                */
-
-               uvm_page_unbusy(&uobjpage, 1);
-               uvmfault_unlockall(ufi, amap, uobj, oanon);
-
-               *spare = uvm_analloc();
-               if (*spare == NULL) {
-                       goto nomem;
-               }
-               simple_unlock(&(*spare)->an_lock);
-               error = ERESTART;
-               goto done;
-       }
-       if (anon) {
-
-               /*
-                * The new anon is locked.
-                *
-                * if opg == NULL, we want a zero'd, dirty page,
-                * so have uvm_pagealloc() do that for us.
-                */
-
-               pg = uvm_pagealloc(NULL, 0, anon,
-                   (opg == NULL) ? UVM_PGA_ZERO : 0);
-       } else {
-               pg = NULL;
-       }
-
-       /*
-        * out of memory resources?
-        */
-
-       if (pg == NULL) {
-               /* save anon for the next try. */
-               if (anon != NULL) {
-                       simple_unlock(&anon->an_lock);
-                       *spare = anon;
-               }
-
-               /* unlock and fail ... */
-               uvm_page_unbusy(&uobjpage, 1);
-               uvmfault_unlockall(ufi, amap, uobj, oanon);
-nomem:
-               if (!uvm_reclaimable()) {
-                       UVMHIST_LOG(maphist, "out of VM", 0,0,0,0);
-                       uvmexp.fltnoanon++;
-                       error = ENOMEM;
-                       goto done;
-               }
-
-               UVMHIST_LOG(maphist, "out of RAM, waiting for more", 0,0,0,0);
-               uvmexp.fltnoram++;
-               uvm_wait("flt_noram5");
-               error = ERESTART;
-               goto done;
-       }
-
-       /* copy page [pg now dirty] */
-       if (opg) {
-               uvm_pagecopy(opg, pg);
-       }
-
-       amap_add(&ufi->entry->aref, ufi->orig_rvaddr - ufi->entry->start, anon,
-           oanon != NULL);
-
-       *nanon = anon;
-       error = 0;
-done:
-       return error;
-}
-
-
-/*
  *   F A U L T   -   m a i n   e n t r y   p o i n t
  */
 
@@ -704,14 +567,13 @@
        struct vm_amap *amap;
        struct uvm_object *uobj;
        struct vm_anon *anons_store[UVM_MAXRANGE], **anons, *anon, *oanon;
-       struct vm_anon *anon_spare;
        struct vm_page *pages[UVM_MAXRANGE], *pg, *uobjpage;
        UVMHIST_FUNC("uvm_fault"); UVMHIST_CALLED(maphist);
 
        UVMHIST_LOG(maphist, "(map=0x%x, vaddr=0x%x, ft=%d, at=%d)",
              orig_map, vaddr, fault_type, access_type);
 
-       anon = anon_spare = NULL;
+       anon = NULL;
        pg = NULL;
 
        uvmexp.faults++;        /* XXX: locking? */
@@ -742,8 +604,7 @@
 
        if (uvmfault_lookup(&ufi, FALSE) == FALSE) {
                UVMHIST_LOG(maphist, "<- no mapping @ 0x%x", vaddr, 0,0,0);
-               error = EFAULT;
-               goto done;
+               return (EFAULT);
        }
        /* locked: maps(read) */
 
@@ -768,8 +629,7 @@
                    "<- protection failure (prot=0x%x, access=0x%x)",
                    ufi.entry->protection, access_type, 0, 0);
                uvmfault_unlockmaps(&ufi, FALSE);
-               error = EACCES;
-               goto done;
+               return EACCES;
        }
 
        /*
@@ -832,8 +692,7 @@
        if (amap == NULL && uobj == NULL) {
                uvmfault_unlockmaps(&ufi, FALSE);
                UVMHIST_LOG(maphist,"<- no backing store, no overlay",0,0,0,0);
-               error = EFAULT;
-               goto done;
+               return (EFAULT);
        }
 
        /*
@@ -1027,7 +886,7 @@
                /*
                 * object fault routine responsible for pmap_update().
                 */
-               goto done;
+               return error;
        }
 
        /*
@@ -1205,7 +1064,7 @@
                goto ReFault;
 
        default:
-               goto done;
+               return error;
        }
 
        /*
@@ -1321,24 +1180,41 @@
                UVMHIST_LOG(maphist, "  case 1B: COW fault",0,0,0,0);
                uvmexp.flt_acow++;
                oanon = anon;           /* oanon = old, locked anon */
-
-               error = uvmfault_promote(&ufi, oanon, PGO_DONTCARE,
-                   &anon, &anon_spare);
-               switch (error) {
-               case 0:
-                       break;
-               case ERESTART:
-                       goto ReFault;
-               default:
-                       goto done;
+               anon = uvm_analloc();
+               if (anon) {
+                       /* new anon is locked! */
+                       pg = uvm_pagealloc(NULL, 0, anon, 0);
                }
 
-               pg = anon->an_page;
+               /* check for out of RAM */
+               if (anon == NULL || pg == NULL) {
+                       if (anon) {
+                               anon->an_ref--;
+                               simple_unlock(&anon->an_lock);
+                               uvm_anfree(anon);
+                       }
+                       uvmfault_unlockall(&ufi, amap, uobj, oanon);
+                       if (!uvm_reclaimable()) {
+                               UVMHIST_LOG(maphist,
+                                   "<- failed.  out of VM",0,0,0,0);
+                               uvmexp.fltnoanon++;
+                               return ENOMEM;
+                       }
+
+                       uvmexp.fltnoram++;
+                       uvm_wait("flt_noram3"); /* out of RAM, wait for more */
+                       goto ReFault;
+               }
+
+               /* got all resources, replace anon with nanon */
+               uvm_pagecopy(oanon->an_page, pg);
                uvm_lock_pageq();
                uvm_pageactivate(pg);
+               pg->flags &= ~(PG_BUSY|PG_FAKE);
                uvm_unlock_pageq();
-               pg->flags &= ~(PG_BUSY|PG_FAKE);
                UVM_PAGE_OWN(pg, NULL);
+               amap_add(&ufi.entry->aref, ufi.orig_rvaddr - ufi.entry->start,
+                   anon, TRUE);
 
                /* deref: can not drop to zero here by defn! */
                oanon->an_ref--;
@@ -1386,8 +1262,7 @@
                        UVMHIST_LOG(maphist,
                            "<- failed.  out of VM",0,0,0,0);
                        /* XXX instrumentation */
-                       error = ENOMEM;
-                       goto done;
+                       return ENOMEM;
                }
                /* XXX instrumentation */
                uvm_wait("flt_pmfail1");
@@ -1424,8 +1299,7 @@
                simple_unlock(&anon->an_lock);
        uvmfault_unlockall(&ufi, amap, uobj, oanon);
        pmap_update(ufi.orig_map->pmap);
-       error = 0;
-       goto done;
+       return 0;
 
 Case2:
        /*



Home | Main Index | Thread Index | Old Index