diff options
author | Artur Grabowski <art@cvs.openbsd.org> | 2001-12-19 08:58:08 +0000 |
---|---|---|
committer | Artur Grabowski <art@cvs.openbsd.org> | 2001-12-19 08:58:08 +0000 |
commit | d8afae924f4db99650aa0df115c6ae66ed02b950 (patch) | |
tree | a2cbc045f0eb624a394f8e45fea1a58ecf1faaf0 /sys/uvm/uvm_aobj.c | |
parent | 4a6c79ff4f05aaae32458104529a9a9e0d3d208b (diff) |
UBC was a disaster. It worked very good when it worked, but on some
machines or some configurations or in some phase of the moon (we actually
don't know when or why) files disappeared. Since we've not been able to
track down the problem in two weeks intense debugging and we need -current
to be stable, back out everything to a state it had before UBC.
We apologise for the inconvenience.
Diffstat (limited to 'sys/uvm/uvm_aobj.c')
-rw-r--r-- | sys/uvm/uvm_aobj.c | 125 |
1 files changed, 65 insertions, 60 deletions
diff --git a/sys/uvm/uvm_aobj.c b/sys/uvm/uvm_aobj.c index 924769d66bf..9a7f135cb98 100644 --- a/sys/uvm/uvm_aobj.c +++ b/sys/uvm/uvm_aobj.c @@ -1,5 +1,5 @@ -/* $OpenBSD: uvm_aobj.c,v 1.23 2001/11/28 19:28:14 art Exp $ */ -/* $NetBSD: uvm_aobj.c,v 1.45 2001/06/23 20:52:03 chs Exp $ */ +/* $OpenBSD: uvm_aobj.c,v 1.24 2001/12/19 08:58:07 art Exp $ */ +/* $NetBSD: uvm_aobj.c,v 1.39 2001/02/18 21:19:08 chs Exp $ */ /* * Copyright (c) 1998 Chuck Silvers, Charles D. Cranor and @@ -174,7 +174,7 @@ static boolean_t uao_flush __P((struct uvm_object *, voff_t, voff_t, int)); static void uao_free __P((struct uvm_aobj *)); static int uao_get __P((struct uvm_object *, voff_t, - struct vm_page **, int *, int, + vm_page_t *, int *, int, vm_prot_t, int, int)); static boolean_t uao_releasepg __P((struct vm_page *, struct vm_page **)); @@ -183,7 +183,7 @@ static boolean_t uao_pagein_page __P((struct uvm_aobj *, int)); /* * aobj_pager - * + * * note that some functions (e.g. put) are handled elsewhere */ @@ -205,7 +205,7 @@ struct uvm_pagerops aobj_pager = { */ static LIST_HEAD(aobjlist, uvm_aobj) uao_list; -static struct simplelock uao_list_lock; +static simple_lock_data_t uao_list_lock; /* @@ -233,41 +233,38 @@ uao_find_swhash_elt(aobj, pageidx, create) struct uao_swhash_elt *elt; voff_t page_tag; - swhash = UAO_SWHASH_HASH(aobj, pageidx); - page_tag = UAO_SWHASH_ELT_TAG(pageidx); + swhash = UAO_SWHASH_HASH(aobj, pageidx); /* first hash to get bucket */ + page_tag = UAO_SWHASH_ELT_TAG(pageidx); /* tag to search for */ /* * now search the bucket for the requested tag */ - LIST_FOREACH(elt, swhash, list) { - if (elt->tag == page_tag) { - return elt; - } + if (elt->tag == page_tag) + return(elt); } - if (!create) { + + /* fail now if we are not allowed to create a new entry in the bucket */ + if (!create) return NULL; - } + /* * allocate a new entry for the bucket and init/insert it in */ - - elt = pool_get(&uao_swhash_elt_pool, PR_NOWAIT); - if (elt == NULL) { - return NULL; - } + elt = pool_get(&uao_swhash_elt_pool, PR_WAITOK); LIST_INSERT_HEAD(swhash, elt, list); elt->tag = page_tag; elt->count = 0; memset(elt->slots, 0, sizeof(elt->slots)); - return elt; + + return(elt); } /* * uao_find_swslot: find the swap slot number for an aobj/pageidx * - * => object must be locked by caller + * => object must be locked by caller */ __inline static int uao_find_swslot(aobj, pageidx) @@ -296,7 +293,7 @@ uao_find_swslot(aobj, pageidx) return(0); } - /* + /* * otherwise, look in the array */ return(aobj->u_swslots[pageidx]); @@ -307,8 +304,6 @@ uao_find_swslot(aobj, pageidx) * * => setting a slot to zero frees the slot * => object must be locked by caller - * => we return the old slot number, or -1 if we failed to allocate - * memory to record the new slot number */ int uao_set_swslot(uobj, pageidx, slot) @@ -316,7 +311,6 @@ uao_set_swslot(uobj, pageidx, slot) int pageidx, slot; { struct uvm_aobj *aobj = (struct uvm_aobj *)uobj; - struct uao_swhash_elt *elt; int oldslot; UVMHIST_FUNC("uao_set_swslot"); UVMHIST_CALLED(pdhist); UVMHIST_LOG(pdhist, "aobj %p pageidx %d slot %d", @@ -348,9 +342,11 @@ uao_set_swslot(uobj, pageidx, slot) * we are freeing. */ - elt = uao_find_swhash_elt(aobj, pageidx, slot ? TRUE : FALSE); + struct uao_swhash_elt *elt = + uao_find_swhash_elt(aobj, pageidx, slot ? TRUE : FALSE); if (elt == NULL) { - return slot ? -1 : 0; + KASSERT(slot == 0); + return (0); } oldslot = UAO_SWHASH_ELT_PAGESLOT(elt, pageidx); @@ -365,8 +361,8 @@ uao_set_swslot(uobj, pageidx, slot) if (slot) { if (oldslot == 0) elt->count++; - } else { - if (oldslot) + } else { /* freeing slot ... */ + if (oldslot) /* to be safe */ elt->count--; if (elt->count == 0) { @@ -374,7 +370,7 @@ uao_set_swslot(uobj, pageidx, slot) pool_put(&uao_swhash_elt_pool, elt); } } - } else { + } else { /* we are using an array */ oldslot = aobj->u_swslots[pageidx]; aobj->u_swslots[pageidx] = slot; @@ -630,7 +626,7 @@ uao_reference_locked(uobj) return; uobj->uo_refs++; /* bump! */ - UVMHIST_LOG(maphist, "<- done (uobj=0x%x, ref = %d)", + UVMHIST_LOG(maphist, "<- done (uobj=0x%x, ref = %d)", uobj, uobj->uo_refs,0,0); } @@ -663,7 +659,7 @@ uao_detach_locked(uobj) struct uvm_object *uobj; { struct uvm_aobj *aobj = (struct uvm_aobj *)uobj; - struct vm_page *pg, *nextpg; + struct vm_page *pg; boolean_t busybody; UVMHIST_FUNC("uao_detach"); UVMHIST_CALLED(maphist); @@ -695,8 +691,9 @@ uao_detach_locked(uobj) * mark for release any that are. */ busybody = FALSE; - for (pg = TAILQ_FIRST(&uobj->memq); pg != NULL; pg = nextpg) { - nextpg = TAILQ_NEXT(pg, listq); + for (pg = TAILQ_FIRST(&uobj->memq); + pg != NULL; + pg = TAILQ_NEXT(pg, listq)) { if (pg->flags & PG_BUSY) { pg->flags |= PG_RELEASED; busybody = TRUE; @@ -864,7 +861,7 @@ uao_flush(uobj, start, stop, flags) if (pp == NULL) continue; } - + switch (flags & (PGO_CLEANIT|PGO_FREE|PGO_DEACTIVATE)) { /* * XXX In these first 3 cases, we always just @@ -881,8 +878,15 @@ uao_flush(uobj, start, stop, flags) pp->wire_count != 0) continue; +#ifdef UBC /* ...and deactivate the page. */ pmap_clear_reference(pp); +#else + /* zap all mappings for the page. */ + pmap_page_protect(pp, VM_PROT_NONE); + + /* ...and deactivate the page. */ +#endif uvm_pagedeactivate(pp); continue; @@ -938,7 +942,7 @@ uao_flush(uobj, start, stop, flags) * * cases 1 and 2 can be handled with PGO_LOCKED, case 3 cannot. * so, if the "center" page hits case 3 (or any page, with PGO_ALLPAGES), - * then we will need to return EBUSY. + * then we will need to return VM_PAGER_UNLOCK. * * => prefer map unlocked (not required) * => object must be locked! we will _unlock_ it before starting any I/O. @@ -958,7 +962,7 @@ uao_get(uobj, offset, pps, npagesp, centeridx, access_type, advice, flags) { struct uvm_aobj *aobj = (struct uvm_aobj *)uobj; voff_t current_offset; - struct vm_page *ptmp; + vm_page_t ptmp; int lcv, gotpages, maxpages, swslot, rv, pageidx; boolean_t done; UVMHIST_FUNC("uao_get"); UVMHIST_CALLED(pdhist); @@ -1017,7 +1021,7 @@ uao_get(uobj, offset, pps, npagesp, centeridx, access_type, advice, flags) if (lcv == centeridx || (flags & PGO_ALLPAGES) != 0) /* need to do a wait or I/O! */ - done = FALSE; + done = FALSE; continue; } @@ -1026,7 +1030,7 @@ uao_get(uobj, offset, pps, npagesp, centeridx, access_type, advice, flags) * result array */ /* caller must un-busy this page */ - ptmp->flags |= PG_BUSY; + ptmp->flags |= PG_BUSY; UVM_PAGE_OWN(ptmp, "uao_get1"); pps[lcv] = ptmp; gotpages++; @@ -1043,10 +1047,10 @@ uao_get(uobj, offset, pps, npagesp, centeridx, access_type, advice, flags) *npagesp = gotpages; if (done) /* bingo! */ - return(0); + return(VM_PAGER_OK); else /* EEK! Need to unlock and I/O */ - return(EBUSY); + return(VM_PAGER_UNLOCK); } /* @@ -1103,7 +1107,7 @@ uao_get(uobj, offset, pps, npagesp, centeridx, access_type, advice, flags) uvm_wait("uao_getpage"); simple_lock(&uobj->vmobjlock); /* goto top of pps while loop */ - continue; + continue; } /* @@ -1112,7 +1116,7 @@ uao_get(uobj, offset, pps, npagesp, centeridx, access_type, advice, flags) */ ptmp->pqflags |= PQ_AOBJ; - /* + /* * got new page ready for I/O. break pps while * loop. pps[lcv] is still NULL. */ @@ -1130,8 +1134,8 @@ uao_get(uobj, offset, pps, npagesp, centeridx, access_type, advice, flags) simple_lock(&uobj->vmobjlock); continue; /* goto top of pps while loop */ } - - /* + + /* * 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 @@ -1151,7 +1155,7 @@ uao_get(uobj, offset, pps, npagesp, centeridx, access_type, advice, flags) continue; /* next lcv */ /* - * we have a "fake/busy/clean" page that we just allocated. + * we have a "fake/busy/clean" page that we just allocated. * do the needed "i/o", either reading from swap or zeroing. */ swslot = uao_find_swslot(aobj, pageidx); @@ -1180,7 +1184,7 @@ uao_get(uobj, offset, pps, npagesp, centeridx, access_type, advice, flags) /* * I/O done. check for errors. */ - if (rv != 0) + if (rv != VM_PAGER_OK) { UVMHIST_LOG(pdhist, "<- done (error=%d)", rv,0,0,0); @@ -1195,9 +1199,7 @@ uao_get(uobj, offset, pps, npagesp, centeridx, access_type, advice, flags) */ swslot = uao_set_swslot(&aobj->u_obj, pageidx, SWSLOT_BAD); - if (swslot != -1) { - uvm_swap_markbad(swslot, 1); - } + uvm_swap_markbad(swslot, 1); ptmp->flags &= ~(PG_WANTED|PG_BUSY); UVM_PAGE_OWN(ptmp, NULL); @@ -1210,10 +1212,10 @@ uao_get(uobj, offset, pps, npagesp, centeridx, access_type, advice, flags) } } - /* + /* * we got the page! clear the fake flag (indicates valid * data now in page) and plug into our result array. note - * that page is still busy. + * that page is still busy. * * it is the callers job to: * => check if the page is released @@ -1233,12 +1235,12 @@ uao_get(uobj, offset, pps, npagesp, centeridx, access_type, advice, flags) simple_unlock(&uobj->vmobjlock); UVMHIST_LOG(pdhist, "<- done (OK)",0,0,0,0); - return(0); + return(VM_PAGER_OK); } /* * uao_releasepg: handle released page in an aobj - * + * * => "pg" is a PG_BUSY [caller owns it], PG_RELEASED page that we need * to dispose of. * => caller must handle PG_WANTED case @@ -1299,7 +1301,7 @@ uao_releasepg(pg, nextpgp) /* * uao_dropswap: release any swap resources from this aobj page. - * + * * => aobj must be locked or have a reference count of 0. */ @@ -1319,7 +1321,7 @@ uao_dropswap(uobj, pageidx) /* * page in every page in every aobj that is paged-out to a range of swslots. - * + * * => nothing should be locked. * => returns TRUE if pagein was aborted due to lack of memory. */ @@ -1420,7 +1422,7 @@ restart: /* * if the slot isn't in range, skip it. */ - if (slot < startslot || + if (slot < startslot || slot >= endslot) { continue; } @@ -1493,14 +1495,14 @@ uao_pagein_page(aobj, pageidx) simple_lock(&aobj->u_obj.vmobjlock); switch (rv) { - case 0: + case VM_PAGER_OK: break; - case EIO: - case ERESTART: + case VM_PAGER_ERROR: + case VM_PAGER_REFAULT: /* * nothing more to do on errors. - * ERESTART can only mean that the anon was freed, + * VM_PAGER_REFAULT can only mean that the anon was freed, * so again there's nothing to do. */ return FALSE; @@ -1521,6 +1523,9 @@ uao_pagein_page(aobj, pageidx) * deactivate the page (to put it on a page queue). */ pmap_clear_reference(pg); +#ifndef UBC + pmap_page_protect(pg, VM_PROT_NONE); +#endif uvm_lock_pageq(); uvm_pagedeactivate(pg); uvm_unlock_pageq(); |