diff options
author | mav <mav@FreeBSD.org> | 2014-01-04 23:42:24 +0000 |
---|---|---|
committer | mav <mav@FreeBSD.org> | 2014-01-04 23:42:24 +0000 |
commit | 00fb1dac34b7ee3eb3cb779e348afd1794b9ae55 (patch) | |
tree | f3b49ae07014b500e7b5bb73b4d82e9a69d37de4 /sys/vm/uma_core.c | |
parent | 91cfd3a7cc7cf9c59406b5a004d657fa9212d2c6 (diff) | |
download | FreeBSD-src-00fb1dac34b7ee3eb3cb779e348afd1794b9ae55.zip FreeBSD-src-00fb1dac34b7ee3eb3cb779e348afd1794b9ae55.tar.gz |
MFC r258693:
Make UMA to not blindly force offpage slab header allocation for large
(> PAGE_SIZE) zones. If zone is not multiple to PAGE_SIZE, there may
be enough space for the header at the last page, so we may avoid extra
header memory allocation and hash table update/lookup.
ZFS creates bunch of odd-sized UMA zones (5120, 6144, 7168, 10240, 14336).
This change gives good use to at least some of otherwise lost memory there.
Diffstat (limited to 'sys/vm/uma_core.c')
-rw-r--r-- | sys/vm/uma_core.c | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/sys/vm/uma_core.c b/sys/vm/uma_core.c index cc1c2c2..c131360 100644 --- a/sys/vm/uma_core.c +++ b/sys/vm/uma_core.c @@ -1318,6 +1318,7 @@ keg_small_init(uma_keg_t keg) static void keg_large_init(uma_keg_t keg) { + u_int shsize; KASSERT(keg != NULL, ("Keg is null in keg_large_init")); KASSERT((keg->uk_flags & UMA_ZFLAG_CACHEONLY) == 0, @@ -1334,8 +1335,21 @@ keg_large_init(uma_keg_t keg) if (keg->uk_flags & UMA_ZFLAG_INTERNAL) return; - keg->uk_flags |= UMA_ZONE_OFFPAGE; - if ((keg->uk_flags & UMA_ZONE_VTOSLAB) == 0) + /* Check whether we have enough space to not do OFFPAGE. */ + if ((keg->uk_flags & UMA_ZONE_OFFPAGE) == 0) { + shsize = sizeof(struct uma_slab); + if (keg->uk_flags & UMA_ZONE_REFCNT) + shsize += keg->uk_ipers * sizeof(uint32_t); + if (shsize & UMA_ALIGN_PTR) + shsize = (shsize & ~UMA_ALIGN_PTR) + + (UMA_ALIGN_PTR + 1); + + if ((PAGE_SIZE * keg->uk_ppera) - keg->uk_rsize < shsize) + keg->uk_flags |= UMA_ZONE_OFFPAGE; + } + + if ((keg->uk_flags & UMA_ZONE_OFFPAGE) && + (keg->uk_flags & UMA_ZONE_VTOSLAB) == 0) keg->uk_flags |= UMA_ZONE_HASH; } |