diff --git a/include/haproxy/pool.h b/include/haproxy/pool.h index a12990d24..d88b23fae 100644 --- a/include/haproxy/pool.h +++ b/include/haproxy/pool.h @@ -102,6 +102,8 @@ extern int mem_poison_byte; extern uint pool_debugging; int is_trim_enabled(void); +int malloc_trim(size_t pad); + void *pool_get_from_os(struct pool_head *pool); void pool_put_to_os(struct pool_head *pool, void *ptr); void *pool_alloc_nocache(struct pool_head *pool); diff --git a/src/pool.c b/src/pool.c index 908b3340f..aff858125 100644 --- a/src/pool.c +++ b/src/pool.c @@ -108,6 +108,7 @@ static int mem_fail_rate __read_mostly = 0; static int using_default_allocator __read_mostly = 1; static int disable_trim __read_mostly = 0; static int(*my_mallctl)(const char *, void *, size_t *, void *, size_t) = NULL; +static int(*_malloc_trim)(size_t) = NULL; /* ask the allocator to trim memory pools. * This must run under thread isolation so that competing threads trying to @@ -209,6 +210,9 @@ static void detect_allocator(void) using_default_allocator = (malloc_default_zone() != NULL); #endif } + + /* detect presence of malloc_trim() */ + _malloc_trim = get_sym_next_addr("malloc_trim"); } int is_trim_enabled(void) @@ -216,6 +220,23 @@ int is_trim_enabled(void) return !disable_trim && using_default_allocator; } +/* replace the libc's malloc_trim() so that we can also intercept the calls + * from child libraries when the allocator is not the default one. + */ +int malloc_trim(size_t pad) +{ + int ret = 0; + + if (disable_trim) + return ret; + + if (_malloc_trim && using_default_allocator) { + /* we're typically on glibc and not overridden */ + ret = _malloc_trim(pad); + } + return ret; +} + static int mem_should_fail(const struct pool_head *pool) { int ret = 0; @@ -1185,7 +1206,7 @@ INITCALL0(STG_PREPARE, init_pools); /* Report in build options if trim is supported */ static void pools_register_build_options(void) { - if (is_trim_enabled()) { + if (is_trim_enabled() && _malloc_trim) { char *ptr = NULL; memprintf(&ptr, "Support for malloc_trim() is enabled."); hap_register_build_opts(ptr, 1);