Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/uvm Add amap_adjref_anons() helper and simplify amap_ref...
details: https://anonhg.NetBSD.org/src/rev/8c724c635ffa
branches: trunk
changeset: 766203:8c724c635ffa
user: rmind <rmind%NetBSD.org@localhost>
date: Sat Jun 18 20:29:56 2011 +0000
description:
Add amap_adjref_anons() helper and simplify amap_ref()/amap_unref().
diffstat:
sys/uvm/uvm_amap.c | 111 ++++++++++++++++++++++++----------------------------
1 files changed, 52 insertions(+), 59 deletions(-)
diffs (165 lines):
diff -r db8de2a3a18d -r 8c724c635ffa sys/uvm/uvm_amap.c
--- a/sys/uvm/uvm_amap.c Sat Jun 18 20:28:48 2011 +0000
+++ b/sys/uvm/uvm_amap.c Sat Jun 18 20:29:56 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: uvm_amap.c,v 1.92 2011/06/16 19:42:20 rmind Exp $ */
+/* $NetBSD: uvm_amap.c,v 1.93 2011/06/18 20:29:56 rmind Exp $ */
/*
* Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -35,7 +35,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uvm_amap.c,v 1.92 2011/06/16 19:42:20 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uvm_amap.c,v 1.93 2011/06/18 20:29:56 rmind Exp $");
#include "opt_uvmhist.h"
@@ -1525,96 +1525,89 @@
}
/*
- * amap_ref: gain a reference to an amap
+ * amap_adjref_anons: adjust the reference count(s) on anons of the amap.
+ */
+static void
+amap_adjref_anons(struct vm_amap *amap, vaddr_t offset, vsize_t len,
+ int refv, bool all)
+{
+#ifdef UVM_AMAP_PPREF
+ KASSERT(mutex_owned(amap->am_lock));
+
+ if (amap->am_ppref == NULL && !all && len != amap->am_nslot) {
+ amap_pp_establish(amap, offset);
+ }
+ if (amap->am_ppref && amap->am_ppref != PPREF_NONE) {
+ struct vm_anon *tofree = NULL;
+
+ if (all) {
+ amap_pp_adjref(amap, 0, amap->am_nslot, refv, &tofree);
+ } else {
+ amap_pp_adjref(amap, offset, len, refv, &tofree);
+ }
+ uvm_anfree(tofree);
+ }
+#endif
+}
+
+/*
+ * amap_ref: gain a reference to an amap.
*
- * => amap must not be locked (we will lock)
- * => "offset" and "len" are in units of pages
- * => called at fork time to gain the child's reference
+ * => amap must not be locked (we will lock).
+ * => "offset" and "len" are in units of pages.
+ * => Called at fork time to gain the child's reference.
*/
void
amap_ref(struct vm_amap *amap, vaddr_t offset, vsize_t len, int flags)
{
-
UVMHIST_FUNC("amap_ref"); UVMHIST_CALLED(maphist);
amap_lock(amap);
- if (flags & AMAP_SHARED)
+ if (flags & AMAP_SHARED) {
amap->am_flags |= AMAP_SHARED;
-#ifdef UVM_AMAP_PPREF
- if (amap->am_ppref == NULL && (flags & AMAP_REFALL) == 0 &&
- len != amap->am_nslot)
- amap_pp_establish(amap, offset);
-#endif
+ }
amap->am_ref++;
-#ifdef UVM_AMAP_PPREF
- if (amap->am_ppref && amap->am_ppref != PPREF_NONE) {
- struct vm_anon *tofree = NULL;
- if (flags & AMAP_REFALL)
- amap_pp_adjref(amap, 0, amap->am_nslot, 1, &tofree);
- else
- amap_pp_adjref(amap, offset, len, 1, &tofree);
- uvm_anfree(tofree); /* must be last action before unlock */
- }
-#endif
+ amap_adjref_anons(amap, offset, len, 1, (flags & AMAP_REFALL) != 0);
amap_unlock(amap);
+
UVMHIST_LOG(maphist,"<- done! amap=0x%x", amap, 0, 0, 0);
}
/*
- * amap_unref: remove a reference to an amap
+ * amap_unref: remove a reference to an amap.
*
- * => caller must remove all pmap-level references to this amap before
- * dropping the reference
- * => called from uvm_unmap_detach [only] ... note that entry is no
- * longer part of a map
- * => amap must be unlocked (we will lock it).
+ * => All pmap-level references to this amap must be already removed.
+ * => Called from uvm_unmap_detach(); entry is already removed from the map.
+ * => We will lock amap, so it must be unlocked.
*/
void
amap_unref(struct vm_amap *amap, vaddr_t offset, vsize_t len, bool all)
{
- struct vm_anon *tofree;
-
UVMHIST_FUNC("amap_unref"); UVMHIST_CALLED(maphist);
- /*
- * lock it
- */
amap_lock(amap);
+
UVMHIST_LOG(maphist," amap=0x%x refs=%d, nused=%d",
amap, amap->am_ref, amap->am_nused, 0);
-
- KASSERT(amap_refs(amap) > 0);
-
- /*
- * if we are the last reference, free the amap and return.
- */
+ KASSERT(amap->am_ref > 0);
- amap->am_ref--;
-
- if (amap_refs(amap) == 0) {
- amap_wipeout(amap); /* drops final ref and frees */
+ if (--amap->am_ref == 0) {
+ /*
+ * If the last reference - wipeout and destroy the amap.
+ */
+ amap_wipeout(amap);
UVMHIST_LOG(maphist,"<- done (was last ref)!", 0, 0, 0, 0);
- return; /* no need to unlock */
+ return;
}
/*
- * otherwise just drop the reference count(s)
+ * Otherwise, drop the reference count(s) on anons.
*/
- if (amap_refs(amap) == 1 && (amap->am_flags & AMAP_SHARED) != 0)
- amap->am_flags &= ~AMAP_SHARED; /* clear shared flag */
- tofree = NULL;
-#ifdef UVM_AMAP_PPREF
- if (amap->am_ppref == NULL && all == 0 && len != amap->am_nslot)
- amap_pp_establish(amap, offset);
- if (amap->am_ppref && amap->am_ppref != PPREF_NONE) {
- if (all)
- amap_pp_adjref(amap, 0, amap->am_nslot, -1, &tofree);
- else
- amap_pp_adjref(amap, offset, len, -1, &tofree);
+ if (amap->am_ref == 1 && (amap->am_flags & AMAP_SHARED) != 0) {
+ amap->am_flags &= ~AMAP_SHARED;
}
-#endif
- uvm_anfree(tofree);
+ amap_adjref_anons(amap, offset, len, -1, all);
amap_unlock(amap);
UVMHIST_LOG(maphist,"<- done!", 0, 0, 0, 0);
Home |
Main Index |
Thread Index |
Old Index