Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/uvm - Rework uvm_anfree() into uvm_anon_freelst(), which...
details: https://anonhg.NetBSD.org/src/rev/874bf0d38dd5
branches: trunk
changeset: 768025:874bf0d38dd5
user: rmind <rmind%NetBSD.org@localhost>
date: Sat Aug 06 17:25:03 2011 +0000
description:
- Rework uvm_anfree() into uvm_anon_freelst(), which always drops the lock.
- Free anons in uvm_anon_freelst() without lock held.
- Mechanic sync to unused loaning code.
diffstat:
sys/uvm/uvm_amap.c | 47 ++++++++++++++++----------------
sys/uvm/uvm_anon.c | 75 +++++++++++++++++++++++++++++++++++-----------------
sys/uvm/uvm_anon.h | 5 ++-
sys/uvm/uvm_fault.c | 6 ++--
sys/uvm/uvm_loan.c | 37 ++++++++++++--------------
sys/uvm/uvm_map.c | 12 ++++----
6 files changed, 102 insertions(+), 80 deletions(-)
diffs (truncated from 528 to 300 lines):
diff -r 29624e0ca717 -r 874bf0d38dd5 sys/uvm/uvm_amap.c
--- a/sys/uvm/uvm_amap.c Sat Aug 06 17:17:39 2011 +0000
+++ b/sys/uvm/uvm_amap.c Sat Aug 06 17:25:03 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: uvm_amap.c,v 1.101 2011/07/05 13:47:24 yamt Exp $ */
+/* $NetBSD: uvm_amap.c,v 1.102 2011/08/06 17:25:03 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.101 2011/07/05 13:47:24 yamt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uvm_amap.c,v 1.102 2011/08/06 17:25:03 rmind Exp $");
#include "opt_uvmhist.h"
@@ -365,9 +365,8 @@
amap_pp_adjref(amap, slotoff + slotmapped,
slotadd, 1, &tofree);
}
- uvm_anfree(tofree);
#endif
- amap_unlock(amap);
+ uvm_anon_freelst(amap, tofree);
UVMHIST_LOG(maphist,
"<- done (case 1f), amap = 0x%x, sltneed=%d",
amap, slotneed, 0, 0);
@@ -382,9 +381,8 @@
amap_pp_adjref(amap, slotoff, slotadd, 1,
&tofree);
}
- uvm_anfree(tofree);
#endif
- amap_unlock(amap);
+ uvm_anon_freelst(amap, tofree);
UVMHIST_LOG(maphist,
"<- done (case 1b), amap = 0x%x, sltneed=%d",
amap, slotneed, 0, 0);
@@ -412,8 +410,7 @@
}
#endif
amap->am_nslot = slotneed;
- uvm_anfree(tofree);
- amap_unlock(amap);
+ uvm_anon_freelst(amap, tofree);
/*
* no need to zero am_anon since that was done at
@@ -614,8 +611,8 @@
oldnslots = amap->am_maxslot;
amap->am_maxslot = slotalloc;
- uvm_anfree(tofree);
- amap_unlock(amap);
+ uvm_anon_freelst(amap, tofree);
+
kmem_free(oldsl, oldnslots * sizeof(*oldsl));
kmem_free(oldbck, oldnslots * sizeof(*oldbck));
kmem_free(oldover, oldnslots * sizeof(*oldover));
@@ -694,6 +691,7 @@
void
amap_wipeout(struct vm_amap *amap)
{
+ struct vm_anon *tofree = NULL;
u_int lcv;
UVMHIST_FUNC("amap_wipeout"); UVMHIST_CALLED(maphist);
@@ -724,11 +722,12 @@
anon->an_ref, 0, 0);
/*
- * Drop the reference, and free the anon, if it is last.
+ * Drop the reference. Defer freeing.
*/
if (--anon->an_ref == 0) {
- uvm_anfree(anon);
+ anon->an_link = tofree;
+ tofree = anon;
}
if (curlwp->l_cpu->ci_schedstate.spc_flags & SPCF_SHOULDYIELD) {
preempt();
@@ -740,7 +739,7 @@
*/
amap->am_nused = 0;
- amap_unlock(amap);
+ uvm_anon_freelst(amap, tofree);
amap_free(amap);
UVMHIST_LOG(maphist,"<- done!", 0,0,0,0);
}
@@ -915,7 +914,6 @@
len >> PAGE_SHIFT, -1, &tofree);
}
#endif
- uvm_anfree(tofree);
/*
* If we referenced any anons, then share the source amap's lock.
@@ -927,9 +925,11 @@
amap->am_lock = srcamap->am_lock;
mutex_obj_hold(amap->am_lock);
}
- amap_unlock(srcamap);
- if (amap->am_lock == NULL)
+ uvm_anon_freelst(srcamap, tofree);
+
+ if (amap->am_lock == NULL) {
amap->am_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NONE);
+ }
amap_list_insert(amap);
/*
@@ -1047,9 +1047,10 @@
if (nanon) {
nanon->an_ref--;
KASSERT(nanon->an_ref == 0);
- uvm_anfree(nanon);
+ uvm_anon_freelst(amap, nanon);
+ } else {
+ amap_unlock(amap);
}
- amap_unlock(amap);
uvm_wait("cownowpage");
goto ReStart;
}
@@ -1279,7 +1280,7 @@
if (--anon->an_ref == 0) {
/*
* Eliminated the last reference to an anon - defer
- * freeing as uvm_anfree() can unlock the amap.
+ * freeing as uvm_anon_freelst() will unlock the amap.
*/
anon->an_link = *tofree;
*tofree = anon;
@@ -1543,6 +1544,8 @@
amap_adjref_anons(struct vm_amap *amap, vaddr_t offset, vsize_t len,
int refv, bool all)
{
+ struct vm_anon *tofree = NULL;
+
#ifdef UVM_AMAP_PPREF
KASSERT(mutex_owned(amap->am_lock));
@@ -1550,16 +1553,14 @@
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
+ uvm_anon_freelst(amap, tofree);
}
/*
@@ -1580,7 +1581,6 @@
}
amap->am_ref++;
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);
}
@@ -1620,7 +1620,6 @@
amap->am_flags &= ~AMAP_SHARED;
}
amap_adjref_anons(amap, offset, len, -1, all);
- amap_unlock(amap);
UVMHIST_LOG(maphist,"<- done!", 0, 0, 0, 0);
}
diff -r 29624e0ca717 -r 874bf0d38dd5 sys/uvm/uvm_anon.c
--- a/sys/uvm/uvm_anon.c Sat Aug 06 17:17:39 2011 +0000
+++ b/sys/uvm/uvm_anon.c Sat Aug 06 17:25:03 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: uvm_anon.c,v 1.58 2011/07/05 13:47:24 yamt Exp $ */
+/* $NetBSD: uvm_anon.c,v 1.59 2011/08/06 17:25:03 rmind Exp $ */
/*
* Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uvm_anon.c,v 1.58 2011/07/05 13:47:24 yamt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uvm_anon.c,v 1.59 2011/08/06 17:25:03 rmind Exp $");
#include "opt_uvmhist.h"
@@ -62,6 +62,7 @@
struct vm_anon *anon = object;
anon->an_ref = 0;
+ anon->an_lock = NULL;
anon->an_page = NULL;
#if defined(VMSWAP)
anon->an_swslot = 0;
@@ -82,33 +83,32 @@
anon = pool_cache_get(&uvm_anon_cache, PR_NOWAIT);
if (anon) {
KASSERT(anon->an_ref == 0);
+ KASSERT(anon->an_lock == NULL);
KASSERT(anon->an_page == NULL);
#if defined(VMSWAP)
KASSERT(anon->an_swslot == 0);
#endif
anon->an_ref = 1;
- anon->an_lock = NULL;
}
return anon;
}
/*
- * uvm_anfree1: free a single anon.
+ * uvm_anon_dispose: free any resident page or swap resources of anon.
*
* => anon must be removed from the amap (if anon was in an amap).
- * => amap must be locked or anon must not be associated.
- * => amap lock may be dropped and re-acquired here.
+ * => amap must be locked; we may drop and re-acquire the lock here.
*/
static void
-uvm_anfree1(struct vm_anon *anon)
+uvm_anon_dispose(struct vm_anon *anon)
{
struct vm_page *pg = anon->an_page;
- UVMHIST_FUNC("uvm_anfree"); UVMHIST_CALLED(maphist);
+ UVMHIST_FUNC("uvm_anon_dispose"); UVMHIST_CALLED(maphist);
UVMHIST_LOG(maphist,"(anon=0x%x)", anon, 0,0,0);
- KASSERT(anon->an_lock == NULL || mutex_owned(anon->an_lock));
+ KASSERT(mutex_owned(anon->an_lock));
/*
* If there is a resident page and it is loaned, then anon may not
@@ -180,35 +180,57 @@
#endif
/*
- * Free any swap resources, leave a page replacement hint, drop
- * the reference on lock and finally destroy the anon itself.
+ * Free any swap resources, leave a page replacement hint.
*/
uvm_anon_dropswap(anon);
uvmpdpol_anfree(anon);
+ UVMHIST_LOG(maphist,"<- done!",0,0,0,0);
+}
+/*
+ * uvm_anon_free: free a single anon.
+ *
+ * => anon must be already disposed.
+ */
+void
+uvm_anon_free(struct vm_anon *anon)
+{
+
+ KASSERT(anon->an_ref == 0);
+ KASSERT(anon->an_lock == NULL);
KASSERT(anon->an_page == NULL);
#if defined(VMSWAP)
KASSERT(anon->an_swslot == 0);
#endif
-
pool_cache_put(&uvm_anon_cache, anon);
- UVMHIST_LOG(maphist,"<- done!",0,0,0,0);
}
/*
- * uvm_anfree: free a linked list of anon structures.
+ * uvm_anon_freelst: free a linked list of anon structures.
+ *
+ * => anon must be locked, we will unlock it.
*/
void
-uvm_anfree(struct vm_anon *anon)
+uvm_anon_freelst(struct vm_amap *amap, struct vm_anon *anonlst)
{
- struct vm_anon *next;
+ struct vm_anon *anon = anonlst;
+
+ KASSERT(mutex_owned(amap->am_lock));
- for (; anon != NULL; anon = next) {
- /* Note: clearing an_link also clears a reference count. */
- next = anon->an_link;
- anon->an_link = NULL;
- uvm_anfree1(anon);
Home |
Main Index |
Thread Index |
Old Index