From owner-svn-src-all@freebsd.org Mon Jan 6 02:51:20 2020 Return-Path: Delivered-To: svn-src-all@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 9A9931EE7BC; Mon, 6 Jan 2020 02:51:20 +0000 (UTC) (envelope-from jeff@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 47rg4m3cgPz452G; Mon, 6 Jan 2020 02:51:20 +0000 (UTC) (envelope-from jeff@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 5EAD079F3; Mon, 6 Jan 2020 02:51:20 +0000 (UTC) (envelope-from jeff@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id 0062pKPb067927; Mon, 6 Jan 2020 02:51:20 GMT (envelope-from jeff@FreeBSD.org) Received: (from jeff@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 0062pJe9067924; Mon, 6 Jan 2020 02:51:19 GMT (envelope-from jeff@FreeBSD.org) Message-Id: <202001060251.0062pJe9067924@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: jeff set sender to jeff@FreeBSD.org using -f From: Jeff Roberson Date: Mon, 6 Jan 2020 02:51:19 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r356393 - head/sys/vm X-SVN-Group: head X-SVN-Commit-Author: jeff X-SVN-Commit-Paths: head/sys/vm X-SVN-Commit-Revision: 356393 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 06 Jan 2020 02:51:20 -0000 Author: jeff Date: Mon Jan 6 02:51:19 2020 New Revision: 356393 URL: https://svnweb.freebsd.org/changeset/base/356393 Log: Fix uma boot pages calculations on NUMA machines that also don't have MD_UMA_SMALL_ALLOC. This is unusual but not impossible. Fix the alignemnt of zones while here. This was already correct because uz_cpu strongly aligned the zone structure but the specified alignment did not match reality and involved redundant defines. Reviewed by: markj, rlibby Differential Revision: https://reviews.freebsd.org/D23046 Modified: head/sys/vm/uma_core.c head/sys/vm/uma_int.h head/sys/vm/vm_page.c Modified: head/sys/vm/uma_core.c ============================================================================== --- head/sys/vm/uma_core.c Mon Jan 6 01:51:23 2020 (r356392) +++ head/sys/vm/uma_core.c Mon Jan 6 02:51:19 2020 (r356393) @@ -2508,27 +2508,28 @@ zone_foreach(void (*zfunc)(uma_zone_t, void *arg), voi * zone of zones and zone of kegs are accounted separately. */ #define UMA_BOOT_ZONES 11 -/* Zone of zones and zone of kegs have arbitrary alignment. */ -#define UMA_BOOT_ALIGN 32 static int zsize, ksize; int uma_startup_count(int vm_zones) { int zones, pages; + u_int zppera, zipers; + u_int kppera, kipers; size_t space, size; ksize = sizeof(struct uma_keg) + (sizeof(struct uma_domain) * vm_ndomains); + ksize = roundup(ksize, UMA_SUPER_ALIGN); zsize = sizeof(struct uma_zone) + (sizeof(struct uma_cache) * (mp_maxid + 1)) + (sizeof(struct uma_zone_domain) * vm_ndomains); + zsize = roundup(zsize, UMA_SUPER_ALIGN); /* - * Memory for the zone of kegs and its keg, - * and for zone of zones. + * Memory for the zone of kegs and its keg, and for zone + * of zones. Allocated directly in uma_startup(). */ - pages = howmany(roundup(zsize, CACHE_LINE_SIZE) * 2 + - roundup(ksize, CACHE_LINE_SIZE), PAGE_SIZE); + pages = howmany(zsize * 2 + ksize, PAGE_SIZE); #ifdef UMA_MD_SMALL_ALLOC zones = UMA_BOOT_ZONES; @@ -2542,23 +2543,33 @@ uma_startup_count(int vm_zones) /* Memory for the rest of startup zones, UMA and VM, ... */ if (zsize > space) { /* See keg_large_init(). */ - u_int ppera; + zppera = howmany(zsize + slab_sizeof(1), PAGE_SIZE); + zipers = 1; + zones += vm_zones; + } else { + zppera = 1; + zipers = space / zsize; + } + pages += howmany(zones, zipers) * zppera; - ppera = howmany(roundup2(zsize, UMA_BOOT_ALIGN), PAGE_SIZE); - if (PAGE_SIZE * ppera - roundup2(zsize, UMA_BOOT_ALIGN) < size) - ppera++; - pages += (zones + vm_zones) * ppera; - } else if (roundup2(zsize, UMA_BOOT_ALIGN) > space) - /* See keg_small_init() special case for uk_ppera = 1. */ - pages += zones; - else - pages += howmany(zones, - space / roundup2(zsize, UMA_BOOT_ALIGN)); - /* ... and their kegs. Note that zone of zones allocates a keg! */ - pages += howmany(zones + 1, - space / roundup2(ksize, UMA_BOOT_ALIGN)); + if (ksize > space) { + /* See keg_large_init(). */ + kppera = howmany(ksize + slab_sizeof(1), PAGE_SIZE); + kipers = 1; + } else { + kppera = 1; + kipers = space / ksize; + } + pages += howmany(zones + 1, kipers) * kppera; + /* + * Allocate an additional slab for zones and kegs on NUMA + * systems. The round-robin allocation policy will populate at + * least one slab per-domain. + */ + pages += (vm_ndomains - 1) * (zppera + kppera); + return (pages); } @@ -2578,11 +2589,11 @@ uma_startup(void *mem, int npages) /* Use bootpages memory for the zone of zones and zone of kegs. */ m = (uintptr_t)mem; zones = (uma_zone_t)m; - m += roundup(zsize, CACHE_LINE_SIZE); + m += zsize; kegs = (uma_zone_t)m; - m += roundup(zsize, CACHE_LINE_SIZE); + m += zsize; masterkeg = (uma_keg_t)m; - m += roundup(ksize, CACHE_LINE_SIZE); + m += ksize; m = roundup(m, PAGE_SIZE); npages -= (m - (uintptr_t)mem) / PAGE_SIZE; mem = (void *)m; @@ -2596,7 +2607,7 @@ uma_startup(void *mem, int npages) args.uminit = zero_init; args.fini = NULL; args.keg = masterkeg; - args.align = UMA_BOOT_ALIGN - 1; + args.align = UMA_SUPER_ALIGN - 1; args.flags = UMA_ZFLAG_INTERNAL; zone_ctor(kegs, zsize, &args, M_WAITOK); @@ -2610,7 +2621,7 @@ uma_startup(void *mem, int npages) args.uminit = zero_init; args.fini = NULL; args.keg = NULL; - args.align = UMA_BOOT_ALIGN - 1; + args.align = UMA_SUPER_ALIGN - 1; args.flags = UMA_ZFLAG_INTERNAL; zone_ctor(zones, zsize, &args, M_WAITOK); @@ -4295,10 +4306,7 @@ uma_zone_reserve_kva(uma_zone_t zone, int count) KEG_ASSERT_COLD(keg); ZONE_ASSERT_COLD(zone); - pages = count / keg->uk_ipers; - if (pages * keg->uk_ipers < count) - pages++; - pages *= keg->uk_ppera; + pages = howmany(count, keg->uk_ipers) * keg->uk_ppera; #ifdef UMA_MD_SMALL_ALLOC if (keg->uk_ppera > 1) { @@ -4340,9 +4348,7 @@ uma_prealloc(uma_zone_t zone, int items) int aflags, domain, slabs; KEG_GET(zone, keg); - slabs = items / keg->uk_ipers; - if (slabs * keg->uk_ipers < items) - slabs++; + slabs = howmany(items, keg->uk_ipers); while (slabs-- > 0) { aflags = M_NOWAIT; vm_domainset_iter_policy_ref_init(&di, &keg->uk_dr, &domain, Modified: head/sys/vm/uma_int.h ============================================================================== --- head/sys/vm/uma_int.h Mon Jan 6 01:51:23 2020 (r356392) +++ head/sys/vm/uma_int.h Mon Jan 6 02:51:19 2020 (r356393) @@ -166,14 +166,17 @@ struct uma_hash { }; /* - * align field or structure to cache line + * Align field or structure to cache 'sector' in intel terminology. This + * is more efficient with adjacent line prefetch. */ #if defined(__amd64__) || defined(__powerpc64__) -#define UMA_ALIGN __aligned(128) +#define UMA_SUPER_ALIGN (CACHE_LINE_SIZE * 2) #else -#define UMA_ALIGN __aligned(CACHE_LINE_SIZE) +#define UMA_SUPER_ALIGN CACHE_LINE_SIZE #endif +#define UMA_ALIGN __aligned(UMA_SUPER_ALIGN) + /* * The uma_bucket structure is used to queue and manage buckets divorced * from per-cpu caches. They are loaded into uma_cache_bucket structures @@ -532,7 +535,7 @@ struct uma_zone { KASSERT(uma_zone_get_allocs((z)) == 0, \ ("zone %s initialization after use.", (z)->uz_name)) -#undef UMA_ALIGN +#undef UMA_ALIGN #ifdef _KERNEL /* Internal prototypes */ Modified: head/sys/vm/vm_page.c ============================================================================== --- head/sys/vm/vm_page.c Mon Jan 6 01:51:23 2020 (r356392) +++ head/sys/vm/vm_page.c Mon Jan 6 02:51:19 2020 (r356393) @@ -613,10 +613,17 @@ vm_page_startup(vm_offset_t vaddr) slab_ipers(sizeof(struct vm_map), UMA_ALIGN_PTR)); /* - * Before going fully functional kmem_init() does allocation - * from "KMAP ENTRY" and vmem_create() does allocation from "vmem". + * Before we are fully boot strapped we need to account for the + * following allocations: + * + * "KMAP ENTRY" from kmem_init() + * "vmem btag" from vmem_startup() + * "vmem" from vmem_create() + * "KMAP" from vm_map_startup() + * + * Each needs at least one page per-domain. */ - boot_pages += 2; + boot_pages += 4 * vm_ndomains; #endif /* * CTFLAG_RDTUN doesn't work during the early boot process, so we must