summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOwain Ainsworth <oga@cvs.openbsd.org>2009-06-01 19:54:03 +0000
committerOwain Ainsworth <oga@cvs.openbsd.org>2009-06-01 19:54:03 +0000
commitf8d7e4725bdfb323dc5095eb2d8e80a36d63a496 (patch)
treebb29916c2b175311cd9f31dc72f34dbff9affc44
parent4e5208a438b355025e66c603943140401434cd55 (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.c46
-rw-r--r--sys/uvm/uvm_fault.c57
-rw-r--r--sys/uvm/uvm_loan.c26
-rw-r--r--sys/uvm/uvm_mmap.c5
-rw-r--r--sys/uvm/uvm_page.c11
-rw-r--r--sys/uvm/uvm_pager.h4
-rw-r--r--sys/uvm/uvm_pdaemon.c41
-rw-r--r--sys/uvm/uvm_vnode.c45
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.
*/