Hi here a little patch for FreeBSD to support memory arenas trimming.
Thanks. regards.
From 1d6386a626f56ca64c25e2dfbf2f9d90a81bd7ae Mon Sep 17 00:00:00 2001 From: David Carlier <devne...@gmail.com> Date: Wed, 24 Nov 2021 20:02:41 +0000 Subject: [PATCH] MEDIUM: pool: trimming arenas on FreeBSD. FreeBSD uses a slighty simplified version of jemalloc as libc allocator since many years (there is thoughts to eventually switch to snmalloc but not before a long time). We detect the libc in the least hacky way in this case aiming as jemalloc specific API then we try to purge arenas as much as we can. --- include/haproxy/compat.h | 2 +- src/pool.c | 32 ++++++++++++++++++++++++-------- 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/include/haproxy/compat.h b/include/haproxy/compat.h index 25b15a1f0..daa58be5d 100644 --- a/include/haproxy/compat.h +++ b/include/haproxy/compat.h @@ -269,7 +269,7 @@ typedef struct { } empty_t; #endif /* FreeBSD also has malloc_usable_size() but it requires malloc_np.h */ -#if defined(USE_MEMORY_PROFILING) && defined(__FreeBSD__) && (__FreeBSD_version >= 700002) +#if defined(__FreeBSD__) && (__FreeBSD_version >= 700002) #include <malloc_np.h> #endif diff --git a/src/pool.c b/src/pool.c index af46b4469..f3ea8c7a7 100644 --- a/src/pool.c +++ b/src/pool.c @@ -42,8 +42,8 @@ int mem_poison_byte = -1; static int mem_fail_rate = 0; #endif -#if defined(HA_HAVE_MALLOC_TRIM) static int using_libc_allocator = 0; +#if defined(HA_HAVE_MALLOC_TRIM) /* ask the allocator to trim memory pools */ static void trim_all_pools(void) @@ -82,26 +82,42 @@ static void detect_allocator(void) using_libc_allocator = !!memcmp(&mi1, &mi2, sizeof(mi1)); } - -static int is_trim_enabled(void) -{ - return using_libc_allocator; -} #else +#if defined(__FreeBSD__) +extern void sdallocx(void *, size_t, int) __attribute__((weak)); +#endif + static void trim_all_pools(void) { +#if defined(__FreeBSD__) + if (using_libc_allocator) { + unsigned int narenas = 0; + size_t len = sizeof(narenas); + + if (mallctl("arenas.narenas", &narenas, &len, NULL, 0) == 0) { + for (unsigned int i = 0; i < narenas; i ++) { + char mib[32] = {0}; + snprintf(mib, sizeof(mib), "arena.%u.purge", i); + (void)mallctl(mib, NULL, NULL, NULL, 0); + } + } + } +#endif } static void detect_allocator(void) { +#if defined(__FreeBSD__) + using_libc_allocator = (sdallocx != NULL); +#endif } +#endif static int is_trim_enabled(void) { - return 0; + return using_libc_allocator; } -#endif /* Try to find an existing shared pool with the same characteristics and * returns it, otherwise creates this one. NULL is returned if no memory -- 2.33.1