From 5687eda8b66d02244d067497508a2788c546eb02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Imre=20Vad=C3=A1sz?= Date: Mon, 6 Jul 2015 01:02:50 +0200 Subject: [PATCH] libc -- nmalloc: Fix realloc bug causing lots of unnecessary mmap/munmap * The broken if condition fixed by this change would cause the memory area to be munmap-ped and mmap-ed again, although the size of the mmap-ped memory area didn't change. For the size comparison we need to take the rounding-up to the next odd multiple of 4K into account. * This change only fixes the extremely bad behaviour caused by munmap-ing and mmap-ing repeatedly for the same memory size. This broken behaviour was introduced by change 8120f5e2a46e669c06a7afdd7de60fa6d6996f9d. Performance is still visibly bad when an array is incrementally grown in small steps using realloc (as done by gdb), because an munmap and mmap to the new size is done for every 8Kb of growth. * This problem was most visible when running gdb on very large core dumps, e.g. when chromium crashes. --- lib/libc/stdlib/nmalloc.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/lib/libc/stdlib/nmalloc.c b/lib/libc/stdlib/nmalloc.c index 0e46e3d..fdecbe6 100644 --- a/lib/libc/stdlib/nmalloc.c +++ b/lib/libc/stdlib/nmalloc.c @@ -1058,7 +1058,16 @@ _slabrealloc(void *ptr, size_t size) if (big->base == ptr) { size = (size + PAGE_MASK) & ~(size_t)PAGE_MASK; bigbytes = big->bytes; - if (bigbytes == size) { + /* + * We need to take the cache-coloring + * optimization into account. Also, if + * size is <= 2*PAGE_SIZE, _slaballoc wants + * to use the slab allocator instead of + * bigalloc. + */ + if (bigbytes == size || + (size > 2*PAGE_SIZE && (size & 8191) == 0 && + bigbytes == size + 4096)) { bigalloc_unlock(ptr); return(ptr); } -- 2.4.2