diff options
author | Owain Ainsworth <oga@cvs.openbsd.org> | 2009-06-01 19:54:03 +0000 |
---|---|---|
committer | Owain Ainsworth <oga@cvs.openbsd.org> | 2009-06-01 19:54:03 +0000 |
commit | f8d7e4725bdfb323dc5095eb2d8e80a36d63a496 (patch) | |
tree | bb29916c2b175311cd9f31dc72f34dbff9affc44 | |
parent | 4e5208a438b355025e66c603943140401434cd55 (diff) |
Since we've now cleared up a lot of the PG_RELEASED setting, remove the
pgo_releasepg() hook and just free the page the "normal" way in the one
place we'll ever see PG_RELEASED and should care (uvm_page_unbusy,
called in aiodoned).
ok art@, beck@, thib@
-rw-r--r-- | sys/uvm/uvm_aobj.c | 46 | ||||
-rw-r--r-- | sys/uvm/uvm_fault.c | 57 | ||||
-rw-r--r-- | sys/uvm/uvm_loan.c | 26 | ||||
-rw-r--r-- | sys/uvm/uvm_mmap.c | 5 | ||||
-rw-r--r-- | sys/uvm/uvm_page.c | 11 | ||||
-rw-r--r-- | sys/uvm/uvm_pager.h | 4 | ||||
-rw-r--r-- | sys/uvm/uvm_pdaemon.c | 41 | ||||
-rw-r--r-- | sys/uvm/uvm_vnode.c | 45 |
8 files changed, 49 insertions, 186 deletions
diff --git a/sys/uvm/uvm_aobj.c b/sys/uvm/uvm_aobj.c index 0f7770a4707..ad2509f3bc2 100644 --- a/sys/uvm/uvm_aobj.c +++ b/sys/uvm/uvm_aobj.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uvm_aobj.c,v 1.39 2009/05/08 13:50:15 ariane Exp $ */ +/* $OpenBSD: uvm_aobj.c,v 1.40 2009/06/01 19:54:02 oga Exp $ */ /* $NetBSD: uvm_aobj.c,v 1.39 2001/02/18 21:19:08 chs Exp $ */ /* @@ -174,7 +174,6 @@ boolean_t uao_flush(struct uvm_object *, voff_t, voff_t, int); void uao_free(struct uvm_aobj *); int uao_get(struct uvm_object *, voff_t, vm_page_t *, int *, int, vm_prot_t, int, int); -boolean_t uao_releasepg(struct vm_page *, struct vm_page **); boolean_t uao_pagein(struct uvm_aobj *, int, int); boolean_t uao_pagein_page(struct uvm_aobj *, int); @@ -191,10 +190,6 @@ struct uvm_pagerops aobj_pager = { NULL, /* fault */ uao_flush, /* flush */ uao_get, /* get */ - NULL, /* put (done by pagedaemon) */ - NULL, /* cluster */ - NULL, /* mk_pcluster */ - uao_releasepg /* releasepg */ }; /* @@ -1142,45 +1137,6 @@ uao_get(struct uvm_object *uobj, voff_t offset, struct vm_page **pps, } /* - * 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 - * => called with page's object locked, pageq's unlocked - * => returns TRUE if page's object is still alive, FALSE if we - * killed the page's object. if we return TRUE, then we - * return with the object locked. - * => if (nextpgp != NULL) => we return the next page on the queue, and return - * with the page queues locked [for pagedaemon] - * => if (nextpgp == NULL) => we return with page queues unlocked [normal case] - * => we kill the aobj if it is not referenced and we are suppose to - * kill it ("KILLME"). - */ -boolean_t -uao_releasepg(struct vm_page *pg, struct vm_page **nextpgp /* OUT */) -{ - struct uvm_aobj *aobj = (struct uvm_aobj *) pg->uobject; - - KASSERT(pg->pg_flags & PG_RELEASED); - - /* - * dispose of the page [caller handles PG_WANTED] and swap slot. - */ - pmap_page_protect(pg, VM_PROT_NONE); - uao_dropswap(&aobj->u_obj, pg->offset >> PAGE_SHIFT); - uvm_lock_pageq(); - if (nextpgp) - *nextpgp = TAILQ_NEXT(pg, pageq); /* next page for daemon */ - uvm_pagefree(pg); - if (!nextpgp) - uvm_unlock_pageq(); /* keep locked for daemon */ - - return TRUE; -} - - -/* * uao_dropswap: release any swap resources from this aobj page. * * => aobj must be locked or have a reference count of 0. diff --git a/sys/uvm/uvm_fault.c b/sys/uvm/uvm_fault.c index a596ef1d342..e9b26c9f9bc 100644 --- a/sys/uvm/uvm_fault.c +++ b/sys/uvm/uvm_fault.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uvm_fault.c,v 1.53 2009/05/08 13:50:15 ariane Exp $ */ +/* $OpenBSD: uvm_fault.c,v 1.54 2009/06/01 19:54:02 oga Exp $ */ /* $NetBSD: uvm_fault.c,v 1.51 2000/08/06 00:22:53 thorpej Exp $ */ /* @@ -921,10 +921,10 @@ ReFault: /* * if center page is resident and not - * PG_BUSY|PG_RELEASED then pgo_get - * made it PG_BUSY for us and gave - * us a handle to it. remember this - * page as "uobjpage." (for later use). + * PG_BUSY, then pgo_get made it PG_BUSY + * for us and gave us a handle to it. + * remember this page as "uobjpage." + * (for later use). */ if (lcv == centeridx) { @@ -966,8 +966,8 @@ ReFault: (wired ? PMAP_WIRED : 0)); /* - * NOTE: page can't be PG_WANTED or PG_RELEASED - * because we've held the lock the whole time + * NOTE: page can't be PG_WANTED because + * we've held the lock the whole time * we've had the handle. */ @@ -1371,15 +1371,12 @@ Case2: /* locked(!locked): uobj, uobjpage */ /* - * verify that the page has not be released and re-verify - * that amap slot is still free. if there is a problem, - * we unlock and clean up. + * Re-verify that amap slot is still free. if there is + * a problem, we unlock and clean up. */ - if ((uobjpage->pg_flags & PG_RELEASED) != 0 || - (locked && amap && - amap_lookup(&ufi.entry->aref, - ufi.orig_rvaddr - ufi.entry->start))) { + if (locked && amap && amap_lookup(&ufi.entry->aref, + ufi.orig_rvaddr - ufi.entry->start)) { if (locked) uvmfault_unlockall(&ufi, amap, NULL, NULL); locked = FALSE; @@ -1398,17 +1395,6 @@ Case2: /* still holding object lock */ wakeup(uobjpage); - if (uobjpage->pg_flags & PG_RELEASED) { - uvmexp.fltpgrele++; - KASSERT(uobj->pgops->pgo_releasepg != NULL); - - /* frees page */ - if (uobj->pgops->pgo_releasepg(uobjpage,NULL)) - /* unlock if still alive */ - simple_unlock(&uobj->vmobjlock); - goto ReFault; - } - uvm_lock_pageq(); /* make sure it is in queues */ uvm_pageactivate(uobjpage); @@ -1423,9 +1409,8 @@ Case2: } /* - * we have the data in uobjpage which is PG_BUSY and - * !PG_RELEASED. we are holding object lock (so the page - * can't be released on us). + * we have the data in uobjpage which is PG_BUSY and we are + * holding object lock. */ /* locked: maps(read), amap(if !null), uobj, uobjpage */ @@ -1439,8 +1424,6 @@ Case2: /* * notes: * - at this point uobjpage can not be NULL - * - at this point uobjpage can not be PG_RELEASED (since we checked - * for it above) * - at this point uobjpage could be PG_WANTED (handle later) */ @@ -1627,9 +1610,7 @@ Case2: } /* - * dispose of uobjpage. it can't be PG_RELEASED - * since we still hold the object lock. - * drop handle to uobj as well. + * dispose of uobjpage. drop handle to uobj as well. */ if (uobjpage->pg_flags & PG_WANTED) @@ -1692,11 +1673,6 @@ Case2: if (pg->pg_flags & PG_WANTED) wakeup(pg); /* lock still held */ - /* - * note that pg can't be PG_RELEASED since we did not drop - * the object lock since the last time we checked. - */ - atomic_clearbits_int(&pg->pg_flags, PG_BUSY|PG_FAKE|PG_WANTED); UVM_PAGE_OWN(pg, NULL); uvmfault_unlockall(&ufi, amap, uobj, NULL); @@ -1736,11 +1712,6 @@ Case2: if (pg->pg_flags & PG_WANTED) wakeup(pg); /* lock still held */ - /* - * note that pg can't be PG_RELEASED since we did not drop the object - * lock since the last time we checked. - */ - atomic_clearbits_int(&pg->pg_flags, PG_BUSY|PG_FAKE|PG_WANTED); UVM_PAGE_OWN(pg, NULL); uvmfault_unlockall(&ufi, amap, uobj, NULL); diff --git a/sys/uvm/uvm_loan.c b/sys/uvm/uvm_loan.c index 989d0bb2867..b4f62568fd7 100644 --- a/sys/uvm/uvm_loan.c +++ b/sys/uvm/uvm_loan.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uvm_loan.c,v 1.30 2009/05/08 13:50:15 ariane Exp $ */ +/* $OpenBSD: uvm_loan.c,v 1.31 2009/06/01 19:54:02 oga Exp $ */ /* $NetBSD: uvm_loan.c,v 1.22 2000/06/27 17:29:25 mrg Exp $ */ /* @@ -462,14 +462,12 @@ uvm_loanuobj(struct uvm_faultinfo *ufi, void ***output, int flags, vaddr_t va) simple_lock(&uobj->vmobjlock); /* - * verify that the page has not be released and re-verify - * that amap slot is still free. if there is a problem we - * drop our lock (thus force a lookup refresh/retry). + * Re-verify that amap slot is still free. if there is a + * problem we drop our lock (thus force a lookup refresh/retry). */ - if ((pg->pg_flags & PG_RELEASED) != 0 || - (locked && amap && amap_lookup(&ufi->entry->aref, - ufi->orig_rvaddr - ufi->entry->start))) { + if (locked && amap && amap_lookup(&ufi->entry->aref, + ufi->orig_rvaddr - ufi->entry->start)) { if (locked) uvmfault_unlockall(ufi, amap, NULL, NULL); @@ -486,17 +484,6 @@ uvm_loanuobj(struct uvm_faultinfo *ufi, void ***output, int flags, vaddr_t va) /* still holding object lock */ wakeup(pg); - if (pg->pg_flags & PG_RELEASED) { -#ifdef DIAGNOSTIC - if (uobj->pgops->pgo_releasepg == NULL) - panic("uvm_loanuobj: object has no releasepg function"); -#endif - /* frees page */ - if (uobj->pgops->pgo_releasepg(pg, NULL)) - simple_unlock(&uobj->vmobjlock); - return (0); - } - uvm_lock_pageq(); uvm_pageactivate(pg); /* make sure it is in queues */ uvm_unlock_pageq(); @@ -509,8 +496,7 @@ uvm_loanuobj(struct uvm_faultinfo *ufi, void ***output, int flags, vaddr_t va) /* * at this point we have the page we want ("pg") marked PG_BUSY for us - * and we have all data structures locked. do the loanout. page can - * not be PG_RELEASED (we caught this above). + * and we have all data structures locked. do the loanout. */ if ((flags & UVM_LOAN_TOANON) == 0) { /* loan to wired-kernel page? */ diff --git a/sys/uvm/uvm_mmap.c b/sys/uvm/uvm_mmap.c index 685eb5d341e..76d65abd04d 100644 --- a/sys/uvm/uvm_mmap.c +++ b/sys/uvm/uvm_mmap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uvm_mmap.c,v 1.72 2009/03/20 15:19:04 oga Exp $ */ +/* $OpenBSD: uvm_mmap.c,v 1.73 2009/06/01 19:54:02 oga Exp $ */ /* $NetBSD: uvm_mmap.c,v 1.49 2001/02/18 21:19:08 chs Exp $ */ /* @@ -298,8 +298,7 @@ sys_mincore(struct proc *p, void *v, register_t *retval) */ if (UVM_ET_ISOBJ(entry)) { KASSERT(!UVM_OBJ_IS_KERN_OBJECT(entry->object.uvm_obj)); - if (entry->object.uvm_obj->pgops->pgo_releasepg - == NULL) { + if (entry->object.uvm_obj->pgops->pgo_fault != NULL) { pgi = 1; for (/* nothing */; start < lim; start += PAGE_SIZE, vec++) diff --git a/sys/uvm/uvm_page.c b/sys/uvm/uvm_page.c index 7c6e257ccb5..1d88b3b5209 100644 --- a/sys/uvm/uvm_page.c +++ b/sys/uvm/uvm_page.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uvm_page.c,v 1.81 2009/06/01 17:42:33 ariane Exp $ */ +/* $OpenBSD: uvm_page.c,v 1.82 2009/06/01 19:54:02 oga Exp $ */ /* $NetBSD: uvm_page.c,v 1.44 2000/11/27 08:40:04 chs Exp $ */ /* @@ -1168,7 +1168,14 @@ uvm_page_unbusy(struct vm_page **pgs, int npgs) UVMHIST_LOG(pdhist, "releasing pg %p", pg,0,0,0); uobj = pg->uobject; if (uobj != NULL) { - uobj->pgops->pgo_releasepg(pg, NULL); + uvm_lock_pageq(); + pmap_page_protect(pg, VM_PROT_NONE); + /* XXX won't happen right now */ + if (pg->pg_flags & PQ_ANON) + uao_dropswap(uobj, + pg->offset >> PAGE_SHIFT); + uvm_pagefree(pg); + uvm_unlock_pageq(); } else { atomic_clearbits_int(&pg->pg_flags, PG_BUSY); UVM_PAGE_OWN(pg, NULL); diff --git a/sys/uvm/uvm_pager.h b/sys/uvm/uvm_pager.h index 229303e5247..5b820ea65b3 100644 --- a/sys/uvm/uvm_pager.h +++ b/sys/uvm/uvm_pager.h @@ -1,4 +1,4 @@ -/* $OpenBSD: uvm_pager.h,v 1.23 2009/03/27 16:29:33 oga Exp $ */ +/* $OpenBSD: uvm_pager.h,v 1.24 2009/06/01 19:54:02 oga Exp $ */ /* $NetBSD: uvm_pager.h,v 1.20 2000/11/27 08:40:05 chs Exp $ */ /* @@ -109,8 +109,6 @@ struct uvm_pagerops { struct vm_page ** (*pgo_mk_pcluster)(struct uvm_object *, struct vm_page **, int *, struct vm_page *, int, voff_t, voff_t); - /* release page */ - boolean_t (*pgo_releasepg)(struct vm_page *, struct vm_page **); }; /* pager flags [mostly for flush] */ diff --git a/sys/uvm/uvm_pdaemon.c b/sys/uvm/uvm_pdaemon.c index e92069c3459..3079110cb1c 100644 --- a/sys/uvm/uvm_pdaemon.c +++ b/sys/uvm/uvm_pdaemon.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uvm_pdaemon.c,v 1.44 2009/05/08 13:50:15 ariane Exp $ */ +/* $OpenBSD: uvm_pdaemon.c,v 1.45 2009/06/01 19:54:02 oga Exp $ */ /* $NetBSD: uvm_pdaemon.c,v 1.23 2000/08/20 10:24:14 bjh21 Exp $ */ /* @@ -820,35 +820,20 @@ uvmpd_scan_inactive(struct pglist *pglst) atomic_clearbits_int(&p->pg_flags, PG_BUSY|PG_WANTED); UVM_PAGE_OWN(p, NULL); - /* released during I/O? */ + /* released during I/O? Can only happen for anons */ if (p->pg_flags & PG_RELEASED) { - if (anon) { - /* remove page so we can get nextpg */ - anon->an_page = NULL; - - simple_unlock(&anon->an_lock); - uvm_anfree(anon); /* kills anon */ - pmap_page_protect(p, VM_PROT_NONE); - anon = NULL; - uvm_lock_pageq(); - nextpg = TAILQ_NEXT(p, pageq); - /* free released page */ - uvm_pagefree(p); - - } else { - - /* - * pgo_releasepg nukes the page and - * gets "nextpg" for us. it returns - * with the page queues locked (when - * given nextpg ptr). - */ + KASSERT(anon != NULL); + /* remove page so we can get nextpg */ + anon->an_page = NULL; - if (!uobj->pgops->pgo_releasepg(p, - &nextpg)) - /* uobj died after release */ - uobj = NULL; - } + simple_unlock(&anon->an_lock); + uvm_anfree(anon); /* kills anon */ + pmap_page_protect(p, VM_PROT_NONE); + anon = NULL; + uvm_lock_pageq(); + nextpg = TAILQ_NEXT(p, pageq); + /* free released page */ + uvm_pagefree(p); } else { /* page was not released during I/O */ uvm_lock_pageq(); nextpg = TAILQ_NEXT(p, pageq); diff --git a/sys/uvm/uvm_vnode.c b/sys/uvm/uvm_vnode.c index 2e4870b745d..f52f6921336 100644 --- a/sys/uvm/uvm_vnode.c +++ b/sys/uvm/uvm_vnode.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uvm_vnode.c,v 1.59 2009/06/01 17:42:33 ariane Exp $ */ +/* $OpenBSD: uvm_vnode.c,v 1.60 2009/06/01 19:54:02 oga Exp $ */ /* $NetBSD: uvm_vnode.c,v 1.36 2000/11/24 20:34:01 chs Exp $ */ /* @@ -93,7 +93,6 @@ void uvn_init(void); int uvn_io(struct uvm_vnode *, vm_page_t *, int, int, int); int uvn_put(struct uvm_object *, vm_page_t *, int, boolean_t); void uvn_reference(struct uvm_object *); -boolean_t uvn_releasepg(struct vm_page *, struct vm_page **); /* * master pager structure @@ -109,7 +108,6 @@ struct uvm_pagerops uvm_vnodeops = { uvn_put, uvn_cluster, uvm_mk_pcluster, /* use generic version of this: see uvm_pager.c */ - uvn_releasepg, }; /* @@ -526,8 +524,8 @@ uvm_vnp_terminate(struct vnode *vp) /* * it is possible that the uvn was detached and is in the relkill - * state [i.e. waiting for async i/o to finish so that releasepg can - * kill object]. we take over the vnode now and cancel the relkill. + * state [i.e. waiting for async i/o to finish]. + * we take over the vnode now and cancel the relkill. * we want to know when the i/o is done so we can recycle right * away. note that a uvn can only be in the RELKILL state if it * has a zero reference count. @@ -621,41 +619,6 @@ uvm_vnp_terminate(struct vnode *vp) } /* - * uvn_releasepg: handled a released page in a uvn - * - * => "pg" is a PG_BUSY [caller owns it], PG_RELEASED page that we need - * to dispose of. - * => caller must handled PG_WANTED case - * => called with page's object locked, pageq's unlocked - * => returns TRUE if page's object is still alive, FALSE if we - * killed the page's object. if we return TRUE, then we - * return with the object locked. - * => if (nextpgp != NULL) => we return pageq.tqe_next here, and return - * with the page queues locked [for pagedaemon] - * => if (nextpgp == NULL) => we return with page queues unlocked [normal case] - * => we kill the uvn if it is not referenced and we are suppose to - * kill it ("relkill"). - */ - -boolean_t -uvn_releasepg(struct vm_page *pg, struct vm_page **nextpgp /* OUT */) -{ - KASSERT(pg->pg_flags & PG_RELEASED); - - /* - * dispose of the page [caller handles PG_WANTED] - */ - pmap_page_protect(pg, VM_PROT_NONE); - uvm_lock_pageq(); - if (nextpgp) - *nextpgp = TAILQ_NEXT(pg, pageq); /* next page for daemon */ - uvm_pagefree(pg); - if (!nextpgp) - uvm_unlock_pageq(); - return (TRUE); -} - -/* * NOTE: currently we have to use VOP_READ/VOP_WRITE because they go * through the buffer cache and allow I/O in any size. These VOPs use * synchronous i/o. [vs. VOP_STRATEGY which can be async, but doesn't @@ -689,8 +652,6 @@ uvn_releasepg(struct vm_page *pg, struct vm_page **nextpgp /* OUT */) * - if (object->iosync && u_naio == 0) { wakeup &uvn->u_naio } * - get "page" structures (atop?). * - handle "wanted" pages - * - handle "released" pages [using pgo_releasepg] - * >>> pgo_releasepg may kill the object * dont forget to look at "object" wanted flag in all cases. */ |