summaryrefslogtreecommitdiff
path: root/sys/uvm/uvm_aobj.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/uvm/uvm_aobj.c')
-rw-r--r--sys/uvm/uvm_aobj.c57
1 files changed, 53 insertions, 4 deletions
diff --git a/sys/uvm/uvm_aobj.c b/sys/uvm/uvm_aobj.c
index b651338c28a..b2a68d6d249 100644
--- a/sys/uvm/uvm_aobj.c
+++ b/sys/uvm/uvm_aobj.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uvm_aobj.c,v 1.42 2009/06/06 17:46:44 art Exp $ */
+/* $OpenBSD: uvm_aobj.c,v 1.43 2009/06/16 00:11:29 oga Exp $ */
/* $NetBSD: uvm_aobj.c,v 1.39 2001/02/18 21:19:08 chs Exp $ */
/*
@@ -174,6 +174,7 @@ 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);
@@ -190,6 +191,10 @@ 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 */
};
/*
@@ -521,7 +526,7 @@ uao_create(vsize_t size, int flags)
*/
simple_lock_init(&aobj->u_obj.vmobjlock);
aobj->u_obj.pgops = &aobj_pager;
- RB_INIT(&aobj->u_obj.memt);
+ TAILQ_INIT(&aobj->u_obj.memq);
aobj->u_obj.uo_npages = 0;
/*
@@ -665,7 +670,7 @@ uao_detach_locked(struct uvm_object *uobj)
* Release swap resources then free the page.
*/
uvm_lock_pageq();
- while((pg = RB_ROOT(&uobj->memt)) != NULL) {
+ while((pg = TAILQ_FIRST(&uobj->memq)) != NULL) {
if (pg->pg_flags & PG_BUSY) {
atomic_setbits_int(&pg->pg_flags, PG_WANTED);
uvm_unlock_pageq();
@@ -790,8 +795,10 @@ uao_flush(struct uvm_object *uobj, voff_t start, voff_t stop, int flags)
continue;
uvm_lock_pageq();
+ /* zap all mappings for the page. */
+ pmap_page_protect(pp, VM_PROT_NONE);
- /* Deactivate the page. */
+ /* ...and deactivate the page. */
uvm_pagedeactivate(pp);
uvm_unlock_pageq();
@@ -1135,6 +1142,45 @@ 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.
@@ -1350,6 +1396,9 @@ uao_pagein_page(struct uvm_aobj *aobj, int 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();