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(&current->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:
 		/*

Reply via email to