From 2359fa84f66ce44b07196f963ed263c00c533976 Mon Sep 17 00:00:00 2001 From: uebayasi Date: Sun, 31 Jan 2010 09:20:31 +0000 Subject: [PATCH] uvm_fault_internal: Move local variables around to isolate contexts. Note that remaining variables are global in that function, and some hold state across re-fault. Slilently clean-up the "eoff" mess. (Superfluous braces will go once things settle down.) --- sys/uvm/uvm_fault.c | 74 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 59 insertions(+), 15 deletions(-) diff --git a/sys/uvm/uvm_fault.c b/sys/uvm/uvm_fault.c index ed9ee5140bc8..888895015eb9 100644 --- a/sys/uvm/uvm_fault.c +++ b/sys/uvm/uvm_fault.c @@ -1,4 +1,4 @@ -/* $NetBSD: uvm_fault.c,v 1.136 2010/01/31 07:47:29 uebayasi Exp $ */ +/* $NetBSD: uvm_fault.c,v 1.137 2010/01/31 09:20:31 uebayasi Exp $ */ /* * @@ -39,7 +39,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: uvm_fault.c,v 1.136 2010/01/31 07:47:29 uebayasi Exp $"); +__KERNEL_RCSID(0, "$NetBSD: uvm_fault.c,v 1.137 2010/01/31 09:20:31 uebayasi Exp $"); #include "opt_uvmhist.h" @@ -697,23 +697,21 @@ uvm_fault_internal(struct vm_map *orig_map, vaddr_t vaddr, vm_prot_t access_type, int fault_flag) { struct uvm_faultinfo ufi; - vm_prot_t enter_prot, check_prot; - bool wired, narrow, promote, locked, shadowed, wire_fault, cow_now; - int npages, nback, nforw, centeridx, error, lcv, gotpages; - vaddr_t startva, currva; - voff_t uoff; + vm_prot_t enter_prot; + bool wired, narrow, shadowed, wire_fault, cow_now; + int npages, centeridx, error; + vaddr_t startva; struct vm_amap *amap; struct uvm_object *uobj; - struct vm_anon *anons_store[UVM_MAXRANGE], **anons, *anon, *oanon; + struct vm_anon *anons_store[UVM_MAXRANGE], **anons; struct vm_anon *anon_spare; - struct vm_page *pages[UVM_MAXRANGE], *pg, *uobjpage; + struct vm_page *pages[UVM_MAXRANGE], *uobjpage; UVMHIST_FUNC("uvm_fault"); UVMHIST_CALLED(maphist); UVMHIST_LOG(maphist, "(map=0x%x, vaddr=0x%x, at=%d, ff=%d)", orig_map, vaddr, access_type, fault_flag); - anon = anon_spare = NULL; - pg = NULL; + anon_spare = NULL; uvmexp.faults++; /* XXX: locking? */ @@ -736,6 +734,11 @@ uvm_fault_internal(struct vm_map *orig_map, vaddr_t vaddr, */ ReFault: +/* uvm_fault_prepare */ + { + vm_prot_t check_prot; + int nback, nforw; + /* * lookup and lock the maps */ @@ -873,7 +876,7 @@ ReFault: } /* offset from entry's start to pgs' start */ - voff_t eoff = startva - ufi.entry->start; + const voff_t eoff = startva - ufi.entry->start; /* locked: maps(read) */ UVMHIST_LOG(maphist, " narrow=%d, back=%d, forw=%d, startva=0x%x", @@ -911,6 +914,8 @@ ReFault: /* flush object? */ if (uobj) { + voff_t uoff; + uoff = ufi.entry->offset + eoff; mutex_enter(&uobj->vmobjlock); (void) (uobj->pgops->pgo_put)(uobj, uoff, uoff + @@ -922,9 +927,19 @@ ReFault: anons += nback; startva += (nback << PAGE_SHIFT); npages -= nback; - nback = centeridx = 0; - eoff = startva - ufi.entry->start; + centeridx = 0; } + } + + /* + * => startva is fixed + * => npages is fixed + */ + +/* uvm_fault_upper_lookup */ + { + int lcv; + vaddr_t currva; /* locked: maps(read), amap(if there) */ KASSERT(amap == NULL || mutex_owned(&amap->am_l)); @@ -938,6 +953,7 @@ ReFault: currva = startva; shadowed = false; for (lcv = 0 ; lcv < npages ; lcv++, currva += PAGE_SIZE) { + struct vm_anon *anon; /* * dont play with VAs that are already mapped @@ -1009,10 +1025,12 @@ ReFault: * XXX Actually, that is bad; pmap_enter() should just fail in that * XXX case. --thorpej */ + } if (shadowed == true) goto Case1; +/* uvm_fault_lower */ /* * if the desired page is not shadowed by the amap and we have a * backing object, then we check to see if the backing object would @@ -1022,6 +1040,7 @@ ReFault: */ if (uobj && uobj->pgops->pgo_fault != NULL) { +/* uvm_fault_lower_special */ mutex_enter(&uobj->vmobjlock); /* locked: maps(read), amap (if there), uobj */ error = uobj->pgops->pgo_fault(&ufi, startva, pages, npages, @@ -1037,6 +1056,11 @@ ReFault: goto done; } +/* uvm_fault_lower_generic_lookup */ + { + int lcv, gotpages; + vaddr_t currva; + /* * now, if the desired page is not shadowed by the amap and we have * a backing object that does not have a special fault routine, then @@ -1059,7 +1083,7 @@ ReFault: uvmexp.fltlget++; gotpages = npages; - (void) uobj->pgops->pgo_get(uobj, ufi.entry->offset + eoff, + (void) uobj->pgops->pgo_get(uobj, ufi.entry->offset + startva - ufi.entry->start, pages, &gotpages, centeridx, access_type & MASK(ufi.entry), ufi.entry->advice, PGO_LOCKED); @@ -1153,6 +1177,7 @@ ReFault: lower_fault_lookup_done: {} + } /* locked: maps(read), amap(if there), uobj(if !null), uobjpage(if !null) */ KASSERT(!shadowed); @@ -1181,7 +1206,11 @@ lower_fault_lookup_done: goto Case2; +/* uvm_fault_upper */ Case1: + { + struct vm_anon *anon, *oanon; + /* locked: maps(read), amap */ KASSERT(mutex_owned(&amap->am_l)); @@ -1269,6 +1298,7 @@ Case1: /* >1 case is already ok */ if (anon->an_ref == 1) { + struct vm_page *pg; /* get new un-owned replacement page */ pg = uvm_pagealloc(NULL, 0, NULL, 0); @@ -1339,6 +1369,7 @@ Case1: * if we are out of anon VM we kill the process (XXX: could wait?). */ + struct vm_page *pg; if (cow_now && anon->an_ref > 1) { UVMHIST_LOG(maphist, " case 1B: COW fault",0,0,0,0); @@ -1452,8 +1483,14 @@ Case1: pmap_update(ufi.orig_map->pmap); error = 0; goto done; + } +/* uvm_fault_lower_generic */ Case2: + { + struct vm_anon *anon; + bool promote; + /* * handle case 2: faulting on backing object or zero fill */ @@ -1496,6 +1533,10 @@ Case2: /* update rusage counters */ curlwp->l_ru.ru_minflt++; } else { + bool locked; + int gotpages; + voff_t uoff; + /* update rusage counters */ curlwp->l_ru.ru_majflt++; @@ -1613,6 +1654,7 @@ Case2: KASSERT(uobj == NULL || uobj == uobjpage->uobject); KASSERT(uobj == NULL || !UVM_OBJ_IS_CLEAN(uobjpage->uobject) || (uobjpage->flags & PG_CLEAN) != 0); + struct vm_page *pg; if (promote == false) { /* @@ -1840,6 +1882,8 @@ Case2: pmap_update(ufi.orig_map->pmap); UVMHIST_LOG(maphist, "<- done (SUCCESS!)",0,0,0,0); error = 0; + } + done: if (anon_spare != NULL) { anon_spare->an_ref--;