Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 7 Feb 2018 09:44:59 -0800
From:      Gleb Smirnoff <glebius@FreeBSD.org>
To:        Peter Holm <peter@holm.cc>, jtl@FreeBSD.org
Cc:        svn-src-head@freebsd.org, svn-src-all@freebsd.org, src-committers@freebsd.org
Subject:   Re: svn commit: r328916 - in head/sys: kern vm
Message-ID:  <20180207174459.GL1063@FreeBSD.org>
In-Reply-To: <20180207164619.GK1063@FreeBSD.org>
References:  <20180206182839.GB1063@FreeBSD.org> <20180206193430.GA36054@x2.osted.lan> <20180206221555.GC1063@FreeBSD.org> <20180206225244.GA40529@x2.osted.lan> <20180206230635.GE1063@FreeBSD.org> <20180206232521.GA41396@x2.osted.lan> <20180207004213.GG1063@FreeBSD.org> <20180207004549.GH1063@FreeBSD.org> <20180207064617.GA49792@x2.osted.lan> <20180207164619.GK1063@FreeBSD.org>

next in thread | previous in thread | raw e-mail | index | archive | help

--ILuaRSyQpoVaJ1HG
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

On Wed, Feb 07, 2018 at 08:46:19AM -0800, Gleb Smirnoff wrote:
T> On Wed, Feb 07, 2018 at 07:46:17AM +0100, Peter Holm wrote:
T> P> On Tue, Feb 06, 2018 at 04:45:49PM -0800, Gleb Smirnoff wrote:
T> P> > On Tue, Feb 06, 2018 at 04:42:13PM -0800, Gleb Smirnoff wrote:
T> P> > T>   Hi Peter,
T> P> > T> 
T> P> > T>   can you please try this patch? In either case success
T> P> > T> or not, please provide me with dmesg. Thanks a lot!
T> P> > 
T> P> > Sorry, patch was missing one file. 99.9% this is a no-op,
T> P> > but better use full patch.
T> 
T> Let's do one more attempt. I found where I miss one keg.

The previous patch will probably work for Peter, but not for
Jonathan. Here is an updated one.

-- 
Gleb Smirnoff

--ILuaRSyQpoVaJ1HG
Content-Type: text/x-diff; charset=us-ascii
Content-Disposition: attachment; filename="boot_pages.diff"

Index: sys/kern/subr_vmem.c
===================================================================
--- sys/kern/subr_vmem.c	(revision 328955)
+++ sys/kern/subr_vmem.c	(working copy)
@@ -667,7 +667,8 @@ int
 vmem_startup_count(void)
 {
 
-	return (howmany(BT_MAXALLOC, UMA_SLAB_SIZE / sizeof(struct vmem_btag)));
+	return (howmany(BT_MAXALLOC,
+	    UMA_SLAB_SPACE / sizeof(struct vmem_btag)));
 }
 #endif
 
Index: sys/vm/uma_core.c
===================================================================
--- sys/vm/uma_core.c	(revision 328955)
+++ sys/vm/uma_core.c	(working copy)
@@ -96,6 +96,7 @@ __FBSDID("$FreeBSD$");
 #ifdef DEBUG_MEMGUARD
 #include <vm/memguard.h>
 #endif
+#define	DIAGNOSTIC
 
 /*
  * This is the zone and keg from which all zones are spawned.
@@ -1102,7 +1103,7 @@ startup_alloc(uma_zone_t zone, vm_size_t bytes, in
 	}
 	mtx_unlock(&uma_boot_pages_mtx);
 	if (booted < BOOT_PAGEALLOC)
-		panic("UMA: Increase vm.boot_pages");
+		panic("UMA zone \"%s\": Increase vm.boot_pages", zone->uz_name);
 	/*
 	 * Now that we've booted reset these users to their real allocator.
 	 */
@@ -1785,6 +1786,8 @@ zone_foreach(void (*zfunc)(uma_zone_t))
  * zone of zones and zone of kegs are accounted separately.
  */
 #define	UMA_BOOT_ZONES	11
+/* Zone of zones and zone of kegs have arbitrary alignemnt. */
+#define	UMA_BOOT_ALIGN	32
 static int zsize, ksize;
 int
 uma_startup_count(int zones)
@@ -1796,28 +1799,43 @@ uma_startup_count(int zones)
 	zsize = sizeof(struct uma_zone) +
 	    (sizeof(struct uma_cache) * (mp_maxid + 1)) +
 	    (sizeof(struct uma_zone_domain) * vm_ndomains);
+	printf("ksize %d zsize %d slab %lu\n", ksize, zsize, sizeof(struct uma_slab));
 
-	/* Memory for the zone of zones and zone of kegs. */
+	/*
+	 * Memory for the zone of kegs and its keg,
+	 * and for zone of zones.
+	 */
 	pages = howmany(roundup(zsize, CACHE_LINE_SIZE) * 2 +
 	    roundup(ksize, CACHE_LINE_SIZE), PAGE_SIZE);
+	printf("boot_pages master %d\n", pages);
 
 	zones += UMA_BOOT_ZONES;
 
-	/* Memory for startup zones, UMA and VM, ... */
+	/* Memory for the rest of startup zones, UMA and VM, ... */
 	if (zsize > UMA_SLAB_SIZE)
-		pages += zones * howmany(zsize, UMA_SLAB_SIZE);
+		pages += zones * howmany(roundup2(zsize, UMA_BOOT_ALIGN),
+		    UMA_SLAB_SIZE);
 	else
-		pages += howmany(zones, UMA_SLAB_SIZE / zsize);
+		pages += howmany(zones,
+		    UMA_SLAB_SPACE / roundup2(zsize, UMA_BOOT_ALIGN));
+	printf("boot_pages zones %d\n", pages);
 
-	/* ... and their kegs. */
-	pages += howmany(zones, UMA_SLAB_SIZE / ksize);
+	/* ... and their kegs. Note that zone of zones allocates a keg! */
+	pages += howmany(zones + 1,
+	    UMA_SLAB_SPACE / roundup2(ksize, UMA_BOOT_ALIGN));
+	printf("boot_pages kegs %d\n", pages);
 
 	/*
-	 * Take conservative approach that every zone
-	 * is going to allocate hash.
+	 * Most of startup zones are not going to be offpages, that's
+	 * why we use UMA_SLAB_SPACE instead of UMA_SLAB_SIZE in all
+	 * calculations.  Some large bucket zones will be offpage, and
+	 * thus will allocate hashes.  We take conservative approach
+	 * and assume that all zones may allocate hash.  This may give
+	 * us some positive imprecision, usually an extra single page.
 	 */
-	pages += howmany(zones, UMA_SLAB_SIZE /
+	pages += howmany(zones, UMA_SLAB_SPACE /
 	    (sizeof(struct slabhead *) * UMA_HASH_SIZE_INIT));
+	printf("boot_pages hash %d\n", pages);
 
 	return (pages);
 }
@@ -1856,7 +1874,7 @@ uma_startup(void *mem, int npages)
 	args.uminit = zero_init;
 	args.fini = NULL;
 	args.keg = masterkeg;
-	args.align = 32 - 1;
+	args.align = UMA_BOOT_ALIGN - 1;
 	args.flags = UMA_ZFLAG_INTERNAL;
 	zone_ctor(kegs, zsize, &args, M_WAITOK);
 
@@ -1871,7 +1889,7 @@ uma_startup(void *mem, int npages)
 	args.uminit = zero_init;
 	args.fini = NULL;
 	args.keg = NULL;
-	args.align = 32 - 1;
+	args.align = UMA_BOOT_ALIGN - 1;
 	args.flags = UMA_ZFLAG_INTERNAL;
 	zone_ctor(zones, zsize, &args, M_WAITOK);
 
Index: sys/vm/uma_int.h
===================================================================
--- sys/vm/uma_int.h	(revision 328955)
+++ sys/vm/uma_int.h	(working copy)
@@ -138,6 +138,11 @@
 #define UMA_MAX_WASTE	10
 
 /*
+ * Size of memory in a not offpage slab available for actual items.
+ */
+#define	UMA_SLAB_SPACE	(UMA_SLAB_SIZE - sizeof(struct uma_slab))
+
+/*
  * I doubt there will be many cases where this is exceeded. This is the initial
  * size of the hash table for uma_slabs that are managed off page. This hash
  * does expand by powers of two.  Currently it doesn't get smaller.
Index: sys/vm/vm_page.c
===================================================================
--- sys/vm/vm_page.c	(revision 328955)
+++ sys/vm/vm_page.c	(working copy)
@@ -518,8 +518,11 @@ vm_page_startup(vm_offset_t vaddr)
 
 	/* vmem_startup() calls uma_prealloc(). */
 	boot_pages += vmem_startup_count();
+	printf("boot_pages vmem %d\n", boot_pages);
 	/* vm_map_startup() calls uma_prealloc(). */
-	boot_pages += howmany(MAX_KMAP, UMA_SLAB_SIZE / sizeof(struct vm_map));
+	boot_pages += howmany(MAX_KMAP,
+	    UMA_SLAB_SPACE / sizeof(struct vm_map));
+	printf("boot_pages kmap %d\n", boot_pages);
 
 	/*
 	 * Before going fully functional kmem_init() does allocation

--ILuaRSyQpoVaJ1HG--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20180207174459.GL1063>