MINOR: pools: automatically disable malloc_trim() with external allocators
Pierre Cheynier reported some occasional crashes in malloc_trim() on a recent glibc when running with jemalloc(). While in theory there should not be any link between the two, it remains plausible that something allocated early with one is tentatively freed with the other and that attempts to trim end up badly. There's no point calling the glibc specific malloc_trim() with external allocators anyway. However these ones are often enabled at link time or even at run time with LD_PRELOAD, so we cannot rely on build options for this. This patch implements runtime detection for the allocator in use by checking with mallinfo() that a malloc() call is properly accounted for in glibc's malloc. It only enables malloc_trim() in this case, and ignores it for other cases. It's fine to proceed like this because mallinfo() is provided by a wider range of glibcs than malloc_trim(). This could be backported to 2.4 and 2.3. If so, it will also need previous patch "CLEANUP: pools: factor all malloc_trim() calls into trim_all_pools()".
This commit is contained in:
parent
ea3323f62c
commit
157e393039
25
src/pool.c
25
src/pool.c
|
@ -41,6 +41,8 @@ static int mem_fail_rate = 0;
|
|||
#endif
|
||||
|
||||
#if defined(HA_HAVE_MALLOC_TRIM)
|
||||
static int using_libc_allocator = 0;
|
||||
|
||||
/* ask the allocator to trim memory pools */
|
||||
static void trim_all_pools(void)
|
||||
{
|
||||
|
@ -48,11 +50,33 @@ static void trim_all_pools(void)
|
|||
malloc_trim(0);
|
||||
}
|
||||
|
||||
/* check if we're using the same allocator as the one that provides
|
||||
* malloc_trim() and mallinfo(). The principle is that on glibc, both
|
||||
* malloc_trim() and mallinfo() are provided, and using mallinfo() we
|
||||
* can check if malloc() is performed through glibc or any other one
|
||||
* the executable was linked against (e.g. jemalloc).
|
||||
*/
|
||||
static void detect_allocator(void)
|
||||
{
|
||||
struct mallinfo mi1, mi2;
|
||||
void *ptr;
|
||||
|
||||
mi1 = mallinfo();
|
||||
ptr = DISGUISE(malloc(1));
|
||||
mi2 = mallinfo();
|
||||
free(DISGUISE(ptr));
|
||||
|
||||
using_libc_allocator = !!memcmp(&mi1, &mi2, sizeof(mi1));
|
||||
}
|
||||
#else
|
||||
|
||||
static void trim_all_pools(void)
|
||||
{
|
||||
}
|
||||
|
||||
static void detect_allocator(void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Try to find an existing shared pool with the same characteristics and
|
||||
|
@ -511,6 +535,7 @@ static void init_pools()
|
|||
LIST_INIT(&ha_thread_info[thr].pool_lru_head);
|
||||
}
|
||||
#endif
|
||||
detect_allocator();
|
||||
}
|
||||
|
||||
INITCALL0(STG_PREPARE, init_pools);
|
||||
|
|
Loading…
Reference in New Issue