diff options
author | Gleb Smirnoff <glebius@FreeBSD.org> | 2018-11-28 19:54:02 +0000 |
---|---|---|
committer | Gleb Smirnoff <glebius@FreeBSD.org> | 2018-11-28 19:54:02 +0000 |
commit | 0b2e3aead3e6db5027c8a437922185d8a7b5235a (patch) | |
tree | c73f8f947d52651937dd5306b72464bc65eabca2 /sys/vm | |
parent | 3d5e3df73f5321725313a2d917407e894ef72a5e (diff) | |
download | src-0b2e3aead3e6db5027c8a437922185d8a7b5235a.tar.gz src-0b2e3aead3e6db5027c8a437922185d8a7b5235a.zip |
Fix yet another edge case in uma_startup_count(). If zone size fits into
several pages, but leaves no space for struct uma_slab at the end we
miscalculate number of pages by one. Totally mimic keg_large_init() math
here to cover that problem.
Reported by: gallatin
Notes
Notes:
svn path=/head/; revision=341163
Diffstat (limited to 'sys/vm')
-rw-r--r-- | sys/vm/uma_core.c | 15 |
1 files changed, 11 insertions, 4 deletions
diff --git a/sys/vm/uma_core.c b/sys/vm/uma_core.c index 9ea36890803d..ba5ec807404c 100644 --- a/sys/vm/uma_core.c +++ b/sys/vm/uma_core.c @@ -1991,10 +1991,17 @@ uma_startup_count(int vm_zones) #endif /* Memory for the rest of startup zones, UMA and VM, ... */ - if (zsize > UMA_SLAB_SPACE) - pages += (zones + vm_zones) * - howmany(roundup2(zsize, UMA_BOOT_ALIGN), UMA_SLAB_SIZE); - else if (roundup2(zsize, UMA_BOOT_ALIGN) > UMA_SLAB_SPACE) + if (zsize > UMA_SLAB_SPACE) { + /* See keg_large_init(). */ + u_int ppera; + + ppera = howmany(roundup2(zsize, UMA_BOOT_ALIGN), PAGE_SIZE); + if (PAGE_SIZE * ppera - roundup2(zsize, UMA_BOOT_ALIGN) < + SIZEOF_UMA_SLAB) + ppera++; + pages += (zones + vm_zones) * ppera; + } else if (roundup2(zsize, UMA_BOOT_ALIGN) > UMA_SLAB_SPACE) + /* See keg_small_init() special case for uk_ppera = 1. */ pages += zones; else pages += howmany(zones, |