Module Name:    src
Committed By:   ad
Date:           Thu Jan  2 02:00:35 UTC 2020

Modified Files:
        src/sys/uvm: uvm_amap.c uvm_amap.h

Log Message:
Back out the amap allocation  changes from earlier today - have seen a panic
with them.  Retain the lock changes.


To generate a diff of this commit:
cvs rdiff -u -r1.113 -r1.114 src/sys/uvm/uvm_amap.c
cvs rdiff -u -r1.38 -r1.39 src/sys/uvm/uvm_amap.h

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.113 src/sys/uvm/uvm_amap.c:1.114
--- src/sys/uvm/uvm_amap.c:1.113	Wed Jan  1 22:01:13 2020
+++ src/sys/uvm/uvm_amap.c	Thu Jan  2 02:00:35 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: uvm_amap.c,v 1.113 2020/01/01 22:01:13 ad Exp $	*/
+/*	$NetBSD: uvm_amap.c,v 1.114 2020/01/02 02:00:35 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.113 2020/01/01 22:01:13 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uvm_amap.c,v 1.114 2020/01/02 02:00:35 ad Exp $");
 
 #include "opt_uvmhist.h"
 
@@ -67,14 +67,7 @@ static int
 amap_roundup_slots(int slots)
 {
 
-#ifdef _LP64
-	/* Align to cacheline boundary for best performance. */
-	return roundup2((slots * sizeof(struct vm_amap *)),
-	    COHERENCY_UNIT) / sizeof(struct vm_amap *);
-#else
-	/* On 32-bit, KVA shortage is a concern. */
 	return kmem_roundup_size(slots * sizeof(int)) / sizeof(int);
-#endif
 }
 
 #ifdef UVM_AMAP_PPREF
@@ -161,7 +154,6 @@ amap_alloc1(int slots, int padslots, int
 	struct vm_amap *amap;
 	kmutex_t *newlock, *oldlock;
 	int totalslots;
-	size_t sz;
 
 	amap = pool_cache_get(&uvm_amap_cache, nowait ? PR_NOWAIT : PR_WAITOK);
 	if (amap == NULL) {
@@ -182,56 +174,38 @@ amap_alloc1(int slots, int padslots, int
 		}
 	}
 
-	totalslots = slots + padslots;
+	totalslots = amap_roundup_slots(slots + padslots);
 	amap->am_ref = 1;
 	amap->am_flags = 0;
 #ifdef UVM_AMAP_PPREF
 	amap->am_ppref = NULL;
 #endif
+	amap->am_maxslot = totalslots;
 	amap->am_nslot = slots;
 
 	/*
-	 * For small amaps use the storage in the amap structure.  Otherwise
-	 * go to the heap.  Note: since allocations are likely big, we
-	 * expect to reduce the memory fragmentation by allocating them in
-	 * separate blocks.
-	 */
-	if (totalslots <= UVM_AMAP_TINY) {
-		amap->am_maxslot = UVM_AMAP_TINY;
-		amap->am_anon = AMAP_TINY_ANON(amap);
-		amap->am_slots = AMAP_TINY_SLOTS(amap);
-		amap->am_bckptr = amap->am_slots + UVM_AMAP_TINY;
-	} else if (totalslots <= UVM_AMAP_SMALL) {
-		amap->am_maxslot = UVM_AMAP_SMALL;
-		amap->am_anon = AMAP_TINY_ANON(amap);
-
-		sz = UVM_AMAP_SMALL * sizeof(int) * 2;
-		sz = roundup2(sz, COHERENCY_UNIT);
-		amap->am_slots = kmem_alloc(sz, kmflags);
-		if (amap->am_slots == NULL)
-			goto fail1;
-
-		amap->am_bckptr = amap->am_slots + amap->am_maxslot;
-	} else {
-		amap->am_maxslot = amap_roundup_slots(totalslots);
-		sz = amap->am_maxslot * sizeof(int) * 2;
-		KASSERT((sz & (COHERENCY_UNIT - 1)) == 0);
-		amap->am_slots = kmem_alloc(sz, kmflags);
-		if (amap->am_slots == NULL)
-			goto fail1;
-
-		amap->am_bckptr = amap->am_slots + amap->am_maxslot;
-
-		amap->am_anon = kmem_alloc(amap->am_maxslot *
-		    sizeof(struct vm_anon *), kmflags);
-		if (amap->am_anon == NULL)
-			goto fail2;
-	}
+	 * Note: since allocations are likely big, we expect to reduce the
+	 * memory fragmentation by allocating them in separate blocks.
+	 */
+	amap->am_slots = kmem_alloc(totalslots * sizeof(int), kmflags);
+	if (amap->am_slots == NULL)
+		goto fail1;
+
+	amap->am_bckptr = kmem_alloc(totalslots * sizeof(int), kmflags);
+	if (amap->am_bckptr == NULL)
+		goto fail2;
+
+	amap->am_anon = kmem_alloc(totalslots * sizeof(struct vm_anon *),
+	    kmflags);
+	if (amap->am_anon == NULL)
+		goto fail3;
 
 	return amap;
 
+fail3:
+	kmem_free(amap->am_bckptr, totalslots * sizeof(int));
 fail2:
-	kmem_free(amap->am_slots, amap->am_maxslot * sizeof(int));
+	kmem_free(amap->am_slots, totalslots * sizeof(int));
 fail1:
 	pool_cache_put(&uvm_amap_cache, amap);
 
@@ -329,19 +303,10 @@ void
 uvm_amap_init(void)
 {
 
-#if defined(_LP64)
-	/*
-	 * Correct alignment helps performance.  For 32-bit platforms, KVA
-	 * availibility is a concern so leave them be.
-	 */
-	KASSERT((sizeof(struct vm_amap) & (COHERENCY_UNIT - 1)) == 0);
-#endif
-
 	mutex_init(&amap_list_lock, MUTEX_DEFAULT, IPL_NONE);
 
-	pool_cache_bootstrap(&uvm_amap_cache, sizeof(struct vm_amap),
-	    COHERENCY_UNIT, 0, 0, "amappl", NULL, IPL_NONE, amap_ctor,
-	    amap_dtor, NULL);
+	pool_cache_bootstrap(&uvm_amap_cache, sizeof(struct vm_amap), 0, 0, 0,
+	    "amappl", NULL, IPL_NONE, amap_ctor, amap_dtor, NULL);
 }
 
 /*
@@ -360,18 +325,12 @@ amap_free(struct vm_amap *amap)
 	KASSERT(amap->am_ref == 0 && amap->am_nused == 0);
 	KASSERT((amap->am_flags & AMAP_SWAPOFF) == 0);
 	slots = amap->am_maxslot;
-	if (amap->am_slots != AMAP_TINY_SLOTS(amap)) {
-		kmem_free(amap->am_slots, roundup2(slots * sizeof(int) * 2,
-		    COHERENCY_UNIT));
-	}
-	if (amap->am_anon != AMAP_TINY_ANON(amap)) {
-		kmem_free(amap->am_anon, slots * sizeof(*amap->am_anon));
-	}
+	kmem_free(amap->am_slots, slots * sizeof(*amap->am_slots));
+	kmem_free(amap->am_bckptr, slots * sizeof(*amap->am_bckptr));
+	kmem_free(amap->am_anon, slots * sizeof(*amap->am_anon));
 #ifdef UVM_AMAP_PPREF
-	if (amap->am_ppref && amap->am_ppref != PPREF_NONE) {
-		kmem_free(amap->am_ppref, roundup2(slots * sizeof(int),
-		    COHERENCY_UNIT));
-	}
+	if (amap->am_ppref && amap->am_ppref != PPREF_NONE)
+		kmem_free(amap->am_ppref, slots * sizeof(*amap->am_ppref));
 #endif
 	pool_cache_put(&uvm_amap_cache, amap);
 	UVMHIST_LOG(maphist,"<- done, freed amap = 0x%#jx", (uintptr_t)amap,
@@ -577,22 +536,23 @@ amap_extend(struct vm_map_entry *entry, 
 	newppref = NULL;
 	if (amap->am_ppref && amap->am_ppref != PPREF_NONE) {
 		/* Will be handled later if fails. */
-		newppref = kmem_alloc(roundup2(slotalloc * sizeof(int),
-		    COHERENCY_UNIT), kmflags);
+		newppref = kmem_alloc(slotalloc * sizeof(*newppref), kmflags);
 	}
 #endif
-	newsl = kmem_alloc(slotalloc * sizeof(*newsl) * 2, kmflags);
-	newbck = newsl + slotalloc;
+	newsl = kmem_alloc(slotalloc * sizeof(*newsl), kmflags);
+	newbck = kmem_alloc(slotalloc * sizeof(*newbck), kmflags);
 	newover = kmem_alloc(slotalloc * sizeof(*newover), kmflags);
 	if (newsl == NULL || newbck == NULL || newover == NULL) {
 #ifdef UVM_AMAP_PPREF
 		if (newppref != NULL) {
-			kmem_free(newppref, roundup2(slotalloc * sizeof(int),
-			    COHERENCY_UNIT));
+			kmem_free(newppref, slotalloc * sizeof(*newppref));
 		}
 #endif
 		if (newsl != NULL) {
-			kmem_free(newsl, slotalloc * sizeof(*newsl) * 2);
+			kmem_free(newsl, slotalloc * sizeof(*newsl));
+		}
+		if (newbck != NULL) {
+			kmem_free(newbck, slotalloc * sizeof(*newbck));
 		}
 		if (newover != NULL) {
 			kmem_free(newover, slotalloc * sizeof(*newover));
@@ -689,18 +649,12 @@ amap_extend(struct vm_map_entry *entry, 
 
 	uvm_anon_freelst(amap, tofree);
 
-	if (oldsl != AMAP_TINY_SLOTS(amap)) {
-		kmem_free(oldsl, roundup2(oldnslots * sizeof(int) * 2,
-		    COHERENCY_UNIT));
-	}
-	if (oldover != AMAP_TINY_ANON(amap)) {
-		kmem_free(oldover, oldnslots * sizeof(*oldover));
-	}
+	kmem_free(oldsl, oldnslots * sizeof(*oldsl));
+	kmem_free(oldbck, oldnslots * sizeof(*oldbck));
+	kmem_free(oldover, oldnslots * sizeof(*oldover));
 #ifdef UVM_AMAP_PPREF
-	if (oldppref && oldppref != PPREF_NONE) {
-		kmem_free(oldppref, roundup2(oldnslots * sizeof(int),
-		    COHERENCY_UNIT));
-	}
+	if (oldppref && oldppref != PPREF_NONE)
+		kmem_free(oldppref, oldnslots * sizeof(*oldppref));
 #endif
 	UVMHIST_LOG(maphist,"<- done (case 3), amap = 0x%#jx, slotneed=%jd",
 	    (uintptr_t)amap, slotneed, 0, 0);
@@ -1198,8 +1152,7 @@ amap_splitref(struct vm_aref *origref, s
 void
 amap_pp_establish(struct vm_amap *amap, vaddr_t offset)
 {
-	const size_t sz = roundup2(amap->am_maxslot * sizeof(*amap->am_ppref),
-	    COHERENCY_UNIT);
+	const size_t sz = amap->am_maxslot * sizeof(*amap->am_ppref);
 
 	KASSERT(mutex_owned(amap->am_lock));
 

Index: src/sys/uvm/uvm_amap.h
diff -u src/sys/uvm/uvm_amap.h:1.38 src/sys/uvm/uvm_amap.h:1.39
--- src/sys/uvm/uvm_amap.h:1.38	Wed Jan  1 22:01:13 2020
+++ src/sys/uvm/uvm_amap.h	Thu Jan  2 02:00:35 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: uvm_amap.h,v 1.38 2020/01/01 22:01:13 ad Exp $	*/
+/*	$NetBSD: uvm_amap.h,v 1.39 2020/01/02 02:00:35 ad Exp $	*/
 
 /*
  * Copyright (c) 1997 Charles D. Cranor and Washington University.
@@ -147,27 +147,6 @@ bool		amap_swap_off
 #define UVM_AMAP_PPREF		/* track partial references */
 
 /*
- * for amaps with fewer than UVM_AMAP_TINY slots, we allocate storage
- * directly in vm_amap.  this should reduce pressure on the allocator and on
- * the CPU cache.  on _LP64, the chosen value of 3 sizes the structure at
- * 128 bytes, a multiple of the typical cache line size, which helps us to
- * avoid false sharing on MULTIPROCESSOR.
- *
- * for amaps with fewer than UVM_AMAP_SMALL slots, anons are stored directly
- * in the vm_amap but slots and backpointers are externally allocated.
- */
-
-#define UVM_AMAP_TINY	3	/* # of slots in "tiny" amap */
-#ifdef _LP64
-#define UVM_AMAP_SMALL	3*2	/* # of slots if 1/2 external allocation */
-#else
-#define UVM_AMAP_SMALL	3*3	/* # of slots in 1/2 external allocation */
-#endif
-
-#define	AMAP_TINY_ANON(am)	((struct vm_anon **)&(am)->am_storage[0])
-#define	AMAP_TINY_SLOTS(am)	((int *)&((am)->am_storage[UVM_AMAP_TINY]))
-
-/*
  * here is the definition of the vm_amap structure for this implementation.
  */
 
@@ -185,7 +164,6 @@ struct vm_amap {
 	int *am_ppref;		/* per page reference count (if !NULL) */
 #endif
 	LIST_ENTRY(vm_amap) am_list;
-	uintptr_t am_storage[UVM_AMAP_SMALL];
 };
 
 /*

Reply via email to