Module Name: src
Committed By: ad
Date: Fri Mar 20 19:08:54 UTC 2020
Modified Files:
src/sys/uvm: uvm_amap.c uvm_amap.h uvm_anon.c uvm_anon.h uvm_fault.c
uvm_loan.c uvm_map.c
Log Message:
Go back to freeing struct vm_anon one by one. There may have been an
advantage circa ~2008 but there isn't now.
To generate a diff of this commit:
cvs rdiff -u -r1.118 -r1.119 src/sys/uvm/uvm_amap.c
cvs rdiff -u -r1.40 -r1.41 src/sys/uvm/uvm_amap.h
cvs rdiff -u -r1.75 -r1.76 src/sys/uvm/uvm_anon.c
cvs rdiff -u -r1.31 -r1.32 src/sys/uvm/uvm_anon.h
cvs rdiff -u -r1.220 -r1.221 src/sys/uvm/uvm_fault.c
cvs rdiff -u -r1.98 -r1.99 src/sys/uvm/uvm_loan.c
cvs rdiff -u -r1.374 -r1.375 src/sys/uvm/uvm_map.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/uvm/uvm_amap.c
diff -u src/sys/uvm/uvm_amap.c:1.118 src/sys/uvm/uvm_amap.c:1.119
--- src/sys/uvm/uvm_amap.c:1.118 Sat Mar 14 20:23:51 2020
+++ src/sys/uvm/uvm_amap.c Fri Mar 20 19:08:54 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: uvm_amap.c,v 1.118 2020/03/14 20:23:51 ad Exp $ */
+/* $NetBSD: uvm_amap.c,v 1.119 2020/03/20 19:08:54 ad 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.118 2020/03/14 20:23:51 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uvm_amap.c,v 1.119 2020/03/20 19:08:54 ad Exp $");
#include "opt_uvmhist.h"
@@ -358,7 +358,7 @@ amap_extend(struct vm_map_entry *entry,
int *newppref, *oldppref;
#endif
int i, *newsl, *newbck, *oldsl, *oldbck;
- struct vm_anon **newover, **oldover, *tofree;
+ struct vm_anon **newover, **oldover;
const km_flag_t kmflags =
(flags & AMAP_EXTEND_NOWAIT) ? KM_NOSLEEP : KM_SLEEP;
@@ -386,7 +386,6 @@ amap_extend(struct vm_map_entry *entry,
slotadj = slotadd - slotoff;
slotarea = amap->am_maxslot - slotmapped;
}
- tofree = NULL;
/*
* case 1: we already have enough slots in the map and thus
@@ -399,10 +398,10 @@ amap_extend(struct vm_map_entry *entry,
#ifdef UVM_AMAP_PPREF
if (amap->am_ppref && amap->am_ppref != PPREF_NONE) {
amap_pp_adjref(amap, slotoff + slotmapped,
- slotadd, 1, &tofree);
+ slotadd, 1);
}
#endif
- uvm_anon_freelst(amap, tofree);
+ amap_unlock(amap);
UVMHIST_LOG(maphist,
"<- done (case 1f), amap = %#jx, sltneed=%jd",
(uintptr_t)amap, slotneed, 0, 0);
@@ -414,11 +413,10 @@ amap_extend(struct vm_map_entry *entry,
entry->aref.ar_pageoff = slotoff;
#ifdef UVM_AMAP_PPREF
if (amap->am_ppref && amap->am_ppref != PPREF_NONE) {
- amap_pp_adjref(amap, slotoff, slotadd, 1,
- &tofree);
+ amap_pp_adjref(amap, slotoff, slotadd, 1);
}
#endif
- uvm_anon_freelst(amap, tofree);
+ amap_unlock(amap);
UVMHIST_LOG(maphist,
"<- done (case 1b), amap = %#jx, sltneed=%jd",
(uintptr_t)amap, slotneed, 0, 0);
@@ -439,14 +437,13 @@ amap_extend(struct vm_map_entry *entry,
amap_pp_adjref(amap,
slotoff + slotmapped,
(amap->am_nslot -
- (slotoff + slotmapped)), 1,
- &tofree);
+ (slotoff + slotmapped)), 1);
pp_setreflen(amap->am_ppref, amap->am_nslot, 1,
slotneed - amap->am_nslot);
}
#endif
amap->am_nslot = slotneed;
- uvm_anon_freelst(amap, tofree);
+ amap_unlock(amap);
/*
* no need to zero am_anon since that was done at
@@ -620,8 +617,7 @@ amap_extend(struct vm_map_entry *entry,
if ((flags & AMAP_EXTEND_FORWARDS) &&
(slotoff + slotmapped) < amap->am_nslot)
amap_pp_adjref(amap, slotoff + slotmapped,
- (amap->am_nslot - (slotoff + slotmapped)), 1,
- &tofree);
+ (amap->am_nslot - (slotoff + slotmapped)), 1);
if (flags & AMAP_EXTEND_FORWARDS)
pp_setreflen(newppref, amap->am_nslot, 1,
slotneed - amap->am_nslot);
@@ -646,8 +642,7 @@ amap_extend(struct vm_map_entry *entry,
}
oldnslots = amap->am_maxslot;
amap->am_maxslot = slotalloc;
-
- uvm_anon_freelst(amap, tofree);
+ amap_unlock(amap);
kmem_free(oldsl, oldnslots * sizeof(*oldsl));
kmem_free(oldbck, oldnslots * sizeof(*oldbck));
@@ -727,7 +722,6 @@ amap_share_protect(struct vm_map_entry *
void
amap_wipeout(struct vm_amap *amap)
{
- struct vm_anon *tofree = NULL;
u_int lcv;
UVMHIST_FUNC("amap_wipeout"); UVMHIST_CALLED(maphist);
@@ -757,14 +751,13 @@ amap_wipeout(struct vm_amap *amap)
(uintptr_t)anon, anon->an_ref, 0, 0);
/*
- * Drop the reference. Defer freeing.
+ * Drop the reference.
*/
- if (--anon->an_ref == 0) {
- anon->an_link = tofree;
- tofree = anon;
+ if (__predict_true(--anon->an_ref == 0)) {
+ uvm_anfree(anon);
}
- if ((lcv & 31) == 31) {
+ if (__predict_false((lcv & 31) == 31)) {
preempt_point();
}
}
@@ -774,7 +767,7 @@ amap_wipeout(struct vm_amap *amap)
*/
amap->am_nused = 0;
- uvm_anon_freelst(amap, tofree);
+ amap_unlock(amap);
amap_free(amap);
UVMHIST_LOG(maphist,"<- done!", 0,0,0,0);
}
@@ -799,7 +792,6 @@ amap_copy(struct vm_map *map, struct vm_
{
const int waitf = (flags & AMAP_COPY_NOWAIT) ? UVM_FLAG_NOWAIT : 0;
struct vm_amap *amap, *srcamap;
- struct vm_anon *tofree;
u_int slots, lcv;
krwlock_t *oldlock;
vsize_t len;
@@ -958,15 +950,14 @@ amap_copy(struct vm_map *map, struct vm_
if (srcamap->am_ref == 1 && (srcamap->am_flags & AMAP_SHARED) != 0) {
srcamap->am_flags &= ~AMAP_SHARED;
}
- tofree = NULL;
#ifdef UVM_AMAP_PPREF
if (srcamap->am_ppref && srcamap->am_ppref != PPREF_NONE) {
amap_pp_adjref(srcamap, entry->aref.ar_pageoff,
- len >> PAGE_SHIFT, -1, &tofree);
+ len >> PAGE_SHIFT, -1);
}
#endif
- uvm_anon_freelst(srcamap, tofree);
+ amap_unlock(srcamap);
/*
* Install new amap.
@@ -1078,7 +1069,7 @@ ReStart:
nanon->an_lock = NULL;
nanon->an_ref--;
KASSERT(nanon->an_ref == 0);
- uvm_anon_free(nanon);
+ uvm_anfree(nanon);
}
uvm_wait("cownowpage");
goto ReStart;
@@ -1173,8 +1164,7 @@ amap_pp_establish(struct vm_amap *amap,
* => map and amap must be locked.
*/
void
-amap_pp_adjref(struct vm_amap *amap, int curslot, vsize_t slotlen, int adjval,
- struct vm_anon **tofree)
+amap_pp_adjref(struct vm_amap *amap, int curslot, vsize_t slotlen, int adjval)
{
int stopslot, *ppref, lcv, prevlcv;
int ref, len, prevref, prevlen;
@@ -1232,7 +1222,7 @@ amap_pp_adjref(struct vm_amap *amap, int
pp_setreflen(ppref, lcv, ref, len);
}
if (ref == 0) {
- amap_wiperange(amap, lcv, len, tofree);
+ amap_wiperange(amap, lcv, len);
}
}
}
@@ -1244,8 +1234,7 @@ amap_pp_adjref(struct vm_amap *amap, int
* => Both map and amap must be locked by caller.
*/
void
-amap_wiperange(struct vm_amap *amap, int slotoff, int slots,
- struct vm_anon **tofree)
+amap_wiperange(struct vm_amap *amap, int slotoff, int slots)
{
u_int lcv, stop, slotend;
bool byanon;
@@ -1307,12 +1296,7 @@ amap_wiperange(struct vm_amap *amap, int
KASSERT(anon->an_lock == amap->am_lock);
if (--anon->an_ref == 0) {
- /*
- * Eliminated the last reference to an anon - defer
- * freeing as uvm_anon_freelst() will unlock the amap.
- */
- anon->an_link = *tofree;
- *tofree = anon;
+ uvm_anfree(anon);
}
}
}
@@ -1570,7 +1554,6 @@ static void
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(rw_write_held(amap->am_lock));
@@ -1590,13 +1573,13 @@ amap_adjref_anons(struct vm_amap *amap,
#ifdef UVM_AMAP_PPREF
if (amap->am_ppref && amap->am_ppref != PPREF_NONE) {
if (all) {
- amap_pp_adjref(amap, 0, amap->am_nslot, refv, &tofree);
+ amap_pp_adjref(amap, 0, amap->am_nslot, refv);
} else {
- amap_pp_adjref(amap, offset, len, refv, &tofree);
+ amap_pp_adjref(amap, offset, len, refv);
}
}
#endif
- uvm_anon_freelst(amap, tofree);
+ amap_unlock(amap);
}
/*
Index: src/sys/uvm/uvm_amap.h
diff -u src/sys/uvm/uvm_amap.h:1.40 src/sys/uvm/uvm_amap.h:1.41
--- src/sys/uvm/uvm_amap.h:1.40 Sun Feb 23 15:46:43 2020
+++ src/sys/uvm/uvm_amap.h Fri Mar 20 19:08:54 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: uvm_amap.h,v 1.40 2020/02/23 15:46:43 ad Exp $ */
+/* $NetBSD: uvm_amap.h,v 1.41 2020/03/20 19:08:54 ad Exp $ */
/*
* Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -266,12 +266,11 @@ struct vm_amap {
#define PPREF_NONE ((int *) -1) /* not using ppref */
void amap_pp_adjref /* adjust references */
- (struct vm_amap *, int, vsize_t, int,
- struct vm_anon **);
+ (struct vm_amap *, int, vsize_t, int);
void amap_pp_establish /* establish ppref */
(struct vm_amap *, vaddr_t);
void amap_wiperange /* wipe part of an amap */
- (struct vm_amap *, int, int, struct vm_anon **);
+ (struct vm_amap *, int, int);
#endif /* UVM_AMAP_PPREF */
#endif /* _KERNEL */
Index: src/sys/uvm/uvm_anon.c
diff -u src/sys/uvm/uvm_anon.c:1.75 src/sys/uvm/uvm_anon.c:1.76
--- src/sys/uvm/uvm_anon.c:1.75 Sat Mar 14 20:23:51 2020
+++ src/sys/uvm/uvm_anon.c Fri Mar 20 19:08:54 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: uvm_anon.c,v 1.75 2020/03/14 20:23:51 ad Exp $ */
+/* $NetBSD: uvm_anon.c,v 1.76 2020/03/20 19:08:54 ad 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.75 2020/03/14 20:23:51 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uvm_anon.c,v 1.76 2020/03/20 19:08:54 ad Exp $");
#include "opt_uvmhist.h"
@@ -95,26 +95,28 @@ uvm_analloc(void)
}
/*
- * uvm_anon_dispose: free any resident page or swap resources of anon.
+ * uvm_anfree: free a single anon structure
*
* => anon must be removed from the amap (if anon was in an amap).
- * => amap must be locked; we may drop and re-acquire the lock here.
+ * => amap must be locked, if anon was owned by amap.
+ * => we may drop and re-acquire the lock here (to break loans).
*/
-static bool
-uvm_anon_dispose(struct vm_anon *anon)
+void
+uvm_anfree(struct vm_anon *anon)
{
- struct vm_page *pg = anon->an_page;
+ struct vm_page *pg = anon->an_page, *pg2 __diagused;
UVMHIST_FUNC("uvm_anon_dispose"); UVMHIST_CALLED(maphist);
UVMHIST_LOG(maphist,"(anon=%#jx)", (uintptr_t)anon, 0,0,0);
- KASSERT(rw_write_held(anon->an_lock));
+ KASSERT(anon->an_lock == NULL || rw_write_held(anon->an_lock));
+ KASSERT(anon->an_ref == 0);
/*
- * Dispose the page, if it is resident.
+ * Dispose of the page, if it is resident.
*/
- if (pg) {
+ if (__predict_true(pg != NULL)) {
KASSERT(anon->an_lock != NULL);
/*
@@ -123,8 +125,9 @@ uvm_anon_dispose(struct vm_anon *anon)
* identify and lock the real owner of the page.
*/
- if (pg->loan_count) {
- pg = uvm_anon_lockloanpg(anon);
+ if (__predict_false(pg->loan_count != 0)) {
+ pg2 = uvm_anon_lockloanpg(anon);
+ KASSERT(pg2 == pg);
}
/*
@@ -133,7 +136,7 @@ uvm_anon_dispose(struct vm_anon *anon)
* and release the object lock.
*/
- if (pg->uobject) {
+ if (__predict_false(pg->uobject != NULL)) {
mutex_enter(&pg->interlock);
KASSERT(pg->loan_count > 0);
pg->loan_count--;
@@ -155,25 +158,26 @@ uvm_anon_dispose(struct vm_anon *anon)
* that uvm_anon_release(9) would release it later.
*/
- if (pg->flags & PG_BUSY) {
+ if (__predict_false((pg->flags & PG_BUSY) != 0)) {
pg->flags |= PG_RELEASED;
rw_obj_hold(anon->an_lock);
- return false;
+ return;
}
uvm_pagefree(pg);
UVMHIST_LOG(maphist, "anon %#jx, page %#jx: "
"freed now!", (uintptr_t)anon, (uintptr_t)pg,
0, 0);
}
- }
-
+ } else {
#if defined(VMSWAP)
- if (pg == NULL && anon->an_swslot > 0) {
- /* This page is no longer only in swap. */
- KASSERT(uvmexp.swpgonly > 0);
- atomic_dec_uint(&uvmexp.swpgonly);
- }
+ if (anon->an_swslot > 0) {
+ /* This page is no longer only in swap. */
+ KASSERT(uvmexp.swpgonly > 0);
+ atomic_dec_uint(&uvmexp.swpgonly);
+ }
#endif
+ }
+ anon->an_lock = NULL;
/*
* Free any swap resources, leave a page replacement hint.
@@ -182,54 +186,10 @@ uvm_anon_dispose(struct vm_anon *anon)
uvm_anon_dropswap(anon);
uvmpdpol_anfree(anon);
UVMHIST_LOG(maphist,"<- done!",0,0,0,0);
- return true;
-}
-
-/*
- * 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);
}
/*
- * uvm_anon_freelst: free a linked list of anon structures.
- *
- * => amap must be locked, we will unlock it.
- */
-void
-uvm_anon_freelst(struct vm_amap *amap, struct vm_anon *anonlst)
-{
- struct vm_anon *next;
-
- UVMHIST_FUNC(__func__); UVMHIST_CALLED(maphist);
-
- KASSERT(rw_write_held(amap->am_lock));
-
- for (; anonlst != NULL; anonlst = next) {
- next = anonlst->an_link;
- /* Note: clears an_ref as well. */
- anonlst->an_link = NULL;
- if (uvm_anon_dispose(anonlst)) {
- anonlst->an_lock = NULL;
- uvm_anon_free(anonlst);
- }
- }
- amap_unlock(amap);
-}
-
-/*
* uvm_anon_lockloanpg: given a locked anon, lock its resident page owner.
*
* => anon is locked by caller
@@ -398,7 +358,7 @@ void
uvm_anon_release(struct vm_anon *anon)
{
struct vm_page *pg = anon->an_page;
- bool success __diagused;
+ krwlock_t *lock;
KASSERT(rw_write_held(anon->an_lock));
KASSERT(pg != NULL);
@@ -411,12 +371,9 @@ uvm_anon_release(struct vm_anon *anon)
uvm_pagefree(pg);
KASSERT(anon->an_page == NULL);
- /* dispose should succeed as no one can reach this anon anymore. */
- success = uvm_anon_dispose(anon);
- KASSERT(success);
- rw_exit(anon->an_lock);
+ lock = anon->an_lock;
+ uvm_anfree(anon);
+ rw_exit(lock);
/* Note: extra reference is held for PG_RELEASED case. */
- rw_obj_free(anon->an_lock);
- anon->an_lock = NULL;
- uvm_anon_free(anon);
+ rw_obj_free(lock);
}
Index: src/sys/uvm/uvm_anon.h
diff -u src/sys/uvm/uvm_anon.h:1.31 src/sys/uvm/uvm_anon.h:1.32
--- src/sys/uvm/uvm_anon.h:1.31 Sun Feb 23 15:46:43 2020
+++ src/sys/uvm/uvm_anon.h Fri Mar 20 19:08:54 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: uvm_anon.h,v 1.31 2020/02/23 15:46:43 ad Exp $ */
+/* $NetBSD: uvm_anon.h,v 1.32 2020/03/20 19:08:54 ad Exp $ */
/*
* Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -46,12 +46,7 @@
struct vm_anon {
krwlock_t *an_lock; /* Lock for an_ref */
- union {
- uintptr_t au_ref; /* Reference count [an_lock] */
- struct vm_anon *au_link; /* Link for deferred free */
- } an_u;
-#define an_ref an_u.au_ref
-#define an_link an_u.au_link
+ uintptr_t an_ref; /* Reference count [an_lock] */
struct vm_page *an_page; /* If in RAM [an_lock] */
#if defined(VMSWAP) || 1 /* XXX libkvm */
/*
@@ -100,8 +95,7 @@ struct vm_aref {
*/
struct vm_anon *uvm_analloc(void);
-void uvm_anon_free(struct vm_anon *);
-void uvm_anon_freelst(struct vm_amap *, struct vm_anon *);
+void uvm_anfree(struct vm_anon *);
void uvm_anon_init(void);
struct vm_page *uvm_anon_lockloanpg(struct vm_anon *);
#if defined(VMSWAP)
Index: src/sys/uvm/uvm_fault.c
diff -u src/sys/uvm/uvm_fault.c:1.220 src/sys/uvm/uvm_fault.c:1.221
--- src/sys/uvm/uvm_fault.c:1.220 Fri Mar 20 18:50:09 2020
+++ src/sys/uvm/uvm_fault.c Fri Mar 20 19:08:54 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: uvm_fault.c,v 1.220 2020/03/20 18:50:09 ad Exp $ */
+/* $NetBSD: uvm_fault.c,v 1.221 2020/03/20 19:08:54 ad Exp $ */
/*
* Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -32,7 +32,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uvm_fault.c,v 1.220 2020/03/20 18:50:09 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uvm_fault.c,v 1.221 2020/03/20 19:08:54 ad Exp $");
#include "opt_uvmhist.h"
@@ -910,7 +910,7 @@ uvm_fault_internal(struct vm_map *orig_m
flt.anon_spare->an_ref--;
KASSERT(flt.anon_spare->an_ref == 0);
KASSERT(flt.anon_spare->an_lock == NULL);
- uvm_anon_free(flt.anon_spare);
+ uvm_anfree(flt.anon_spare);
}
return error;
}
Index: src/sys/uvm/uvm_loan.c
diff -u src/sys/uvm/uvm_loan.c:1.98 src/sys/uvm/uvm_loan.c:1.99
--- src/sys/uvm/uvm_loan.c:1.98 Tue Mar 17 18:31:39 2020
+++ src/sys/uvm/uvm_loan.c Fri Mar 20 19:08:54 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: uvm_loan.c,v 1.98 2020/03/17 18:31:39 ad Exp $ */
+/* $NetBSD: uvm_loan.c,v 1.99 2020/03/20 19:08:54 ad Exp $ */
/*
* Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -32,7 +32,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uvm_loan.c,v 1.98 2020/03/17 18:31:39 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uvm_loan.c,v 1.99 2020/03/20 19:08:54 ad Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -808,7 +808,7 @@ fail:
uvmfault_unlockall(ufi, amap, uobj, NULL);
if (anon) {
anon->an_ref--;
- uvm_anon_free(anon);
+ uvm_anfree(anon);
}
#endif /* notdef */
return (-1);
@@ -943,11 +943,10 @@ uvm_unloananon(struct vm_anon **aloans,
while (nanons-- > 0) {
anon = *aloans++;
if (--anon->an_ref == 0) {
- anon->an_link = to_free;
- to_free = anon;
+ uvm_anfree(anon);
}
}
- uvm_anon_freelst(amap, to_free);
+ amap_unlock(amap);
#endif /* notdef */
}
Index: src/sys/uvm/uvm_map.c
diff -u src/sys/uvm/uvm_map.c:1.374 src/sys/uvm/uvm_map.c:1.375
--- src/sys/uvm/uvm_map.c:1.374 Sat Mar 14 17:29:53 2020
+++ src/sys/uvm/uvm_map.c Fri Mar 20 19:08:54 2020
@@ -1,4 +1,4 @@
-/* $NetBSD: uvm_map.c,v 1.374 2020/03/14 17:29:53 ad Exp $ */
+/* $NetBSD: uvm_map.c,v 1.375 2020/03/20 19:08:54 ad Exp $ */
/*
* Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -66,7 +66,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uvm_map.c,v 1.374 2020/03/14 17:29:53 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uvm_map.c,v 1.375 2020/03/20 19:08:54 ad Exp $");
#include "opt_ddb.h"
#include "opt_pax.h"
@@ -3796,7 +3796,7 @@ uvm_map_clean(struct vm_map *map, vaddr_
struct vm_map_entry *current, *entry;
struct uvm_object *uobj;
struct vm_amap *amap;
- struct vm_anon *anon, *anon_tofree;
+ struct vm_anon *anon;
struct vm_page *pg;
vaddr_t offset;
vsize_t size;
@@ -3857,7 +3857,6 @@ uvm_map_clean(struct vm_map *map, vaddr_
offset = start - current->start;
size = MIN(end, current->end) - start;
- anon_tofree = NULL;
amap_lock(amap, RW_WRITER);
for ( ; size != 0; size -= PAGE_SIZE, offset += PAGE_SIZE) {
@@ -3917,13 +3916,12 @@ uvm_map_clean(struct vm_map *map, vaddr_
amap_unadd(¤t->aref, offset);
refs = --anon->an_ref;
if (refs == 0) {
- anon->an_link = anon_tofree;
- anon_tofree = anon;
+ uvm_anfree(anon);
}
continue;
}
}
- uvm_anon_freelst(amap, anon_tofree);
+ amap_unlock(amap);
flush_object:
/*