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>