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.c65
1 files changed, 41 insertions, 24 deletions
diff --git a/sys/uvm/uvm_aobj.c b/sys/uvm/uvm_aobj.c
index a0a50c7f72c..250662bece8 100644
--- a/sys/uvm/uvm_aobj.c
+++ b/sys/uvm/uvm_aobj.c
@@ -1,11 +1,6 @@
-/* $OpenBSD: uvm_aobj.c,v 1.3 1999/04/28 09:28:18 art Exp $ */
-/* $NetBSD: uvm_aobj.c,v 1.15 1998/10/18 23:49:59 chs Exp $ */
+/* $NetBSD: uvm_aobj.c,v 1.18 1999/03/26 17:34:15 chs Exp $ */
/*
- * XXXCDC: "ROUGH DRAFT" QUALITY UVM PRE-RELEASE FILE!
- * >>>USE AT YOUR OWN RISK, WORK IS NOT FINISHED<<<
- */
-/*
* Copyright (c) 1998 Chuck Silvers, Charles D. Cranor and
* Washington University.
* All rights reserved.
@@ -198,7 +193,6 @@ static boolean_t uao_releasepg __P((struct vm_page *,
struct uvm_pagerops aobj_pager = {
uao_init, /* init */
- NULL, /* attach */
uao_reference, /* reference */
uao_detach, /* detach */
NULL, /* fault */
@@ -425,8 +419,17 @@ uao_free(aobj)
{
int slot = elt->slots[j];
- if (slot)
+ if (slot) {
uvm_swap_free(slot, 1);
+
+ /*
+ * this page is no longer
+ * only in swap.
+ */
+ simple_lock(&uvm.swap_data_lock);
+ uvmexp.swpgonly--;
+ simple_unlock(&uvm.swap_data_lock);
+ }
}
next = elt->list.le_next;
@@ -445,8 +448,14 @@ uao_free(aobj)
{
int slot = aobj->u_swslots[i];
- if (slot)
+ if (slot) {
uvm_swap_free(slot, 1);
+
+ /* this page is no longer only in swap. */
+ simple_lock(&uvm.swap_data_lock);
+ uvmexp.swpgonly--;
+ simple_unlock(&uvm.swap_data_lock);
+ }
}
FREE(aobj->u_swslots, M_UVMAOBJ);
}
@@ -663,7 +672,6 @@ uao_detach(uobj)
busybody = FALSE;
for (pg = uobj->memq.tqh_first ; pg != NULL ; pg = pg->listq.tqe_next) {
- int swslot;
if (pg->flags & PG_BUSY) {
pg->flags |= PG_RELEASED;
@@ -671,16 +679,9 @@ uao_detach(uobj)
continue;
}
-
/* zap the mappings, free the swap slot, free the page */
pmap_page_protect(PMAP_PGARG(pg), VM_PROT_NONE);
-
- swslot = uao_set_swslot(&aobj->u_obj,
- pg->offset >> PAGE_SHIFT, 0);
- if (swslot) {
- uvm_swap_free(swslot, 1);
- }
-
+ uao_dropswap(&aobj->u_obj, pg->offset >> PAGE_SHIFT);
uvm_lock_pageq();
uvm_pagefree(pg);
uvm_unlock_pageq();
@@ -796,7 +797,7 @@ uao_get(uobj, offset, pps, npagesp, centeridx, access_type, advice, flags)
if (ptmp == NULL && uao_find_swslot(aobj,
current_offset >> PAGE_SHIFT) == 0) {
ptmp = uvm_pagealloc(uobj, current_offset,
- NULL);
+ NULL, 0);
if (ptmp) {
/* new page */
ptmp->flags &= ~(PG_BUSY|PG_FAKE);
@@ -886,7 +887,7 @@ uao_get(uobj, offset, pps, npagesp, centeridx, access_type, advice, flags)
if (ptmp == NULL) {
ptmp = uvm_pagealloc(uobj, current_offset,
- NULL); /* alloc */
+ NULL, 0);
/* out of RAM? */
if (ptmp == NULL) {
@@ -1039,7 +1040,6 @@ static boolean_t uao_releasepg(pg, nextpgp)
struct vm_page **nextpgp; /* OUT */
{
struct uvm_aobj *aobj = (struct uvm_aobj *) pg->uobject;
- int slot;
#ifdef DIAGNOSTIC
if ((pg->flags & PG_RELEASED) == 0)
@@ -1050,9 +1050,7 @@ static boolean_t uao_releasepg(pg, nextpgp)
* dispose of the page [caller handles PG_WANTED] and swap slot.
*/
pmap_page_protect(PMAP_PGARG(pg), VM_PROT_NONE);
- slot = uao_set_swslot(&aobj->u_obj, pg->offset >> PAGE_SHIFT, 0);
- if (slot)
- uvm_swap_free(slot, 1);
+ uao_dropswap(&aobj->u_obj, pg->offset >> PAGE_SHIFT);
uvm_lock_pageq();
if (nextpgp)
*nextpgp = pg->pageq.tqe_next; /* next page for daemon */
@@ -1089,3 +1087,22 @@ static boolean_t uao_releasepg(pg, nextpgp)
return FALSE;
}
+
+/*
+ * uao_dropswap: release any swap resources from this aobj page.
+ *
+ * => aobj must be locked or have a reference count of 0.
+ */
+
+void
+uao_dropswap(uobj, pageidx)
+ struct uvm_object *uobj;
+ int pageidx;
+{
+ int slot;
+
+ slot = uao_set_swslot(uobj, pageidx, 0);
+ if (slot) {
+ uvm_swap_free(slot, 1);
+ }
+}