mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-02-28 16:40:37 +00:00
MINOR: pools: work around possibly slow malloc_trim() during gc
During 2.4-dev, support for malloc_trim() was implemented to ease release of memory in a stopping process. This was found to be quite effective and later backported to 2.3.7. Then it was found that sometimes malloc_trim() could take a huge time to complete it if was competing with other threads still allocating and releasing memory, reason why it was decided in 2.5-dev to move malloc_trim() under the thread isolation that was already in place in the shared pool version of pool_gc() (this was commit26ed1835
). However, other instances of pool_gc() that used to call malloc_trim() were not updated since they were not using thread isolation. Currently we have two other such instances, one for when there is absolutely no pool and one for when there are only thread-local pools. Christian Ruppert reported in GH issue #1490 that he's sometimes seeing and old process die upon reload when upgrading from 2.3 to 2.4, and that this happens inside malloc_trim(). The problem is that since 2.4-dev11 with commit0bae07592
we detect modern libc that provide a faster thread-aware allocator and do not maintain shared pools anymore. As such we're using again the simpler pool_gc() implementations that do not use thread isolation around the malloc_trim() call. All this code was cleaned up recently and the call moved to a new function trim_all_pools(). This patch implements explicit thread isolation inside that function so that callers do not have to care about this anymore. The thread isolation is conditional so that this doesn't affect the one already in place in the larger version of pool_gc(). This way it will solve the problem for all callers. This patch must be backported as far as 2.3. It may possibly require some adaptations. If trim_all_pools() is not present, copy-pasting the tests in each version of pool_gc() will have the same effect. Thanks to Christian for his detailed report and his testing.
This commit is contained in:
parent
2c15a66b61
commit
0d93a81863
15
src/pool.c
15
src/pool.c
@ -45,9 +45,19 @@ static int mem_fail_rate = 0;
|
||||
static int using_default_allocator = 1;
|
||||
static int(*my_mallctl)(const char *, void *, size_t *, void *, size_t) = NULL;
|
||||
|
||||
/* ask the allocator to trim memory pools */
|
||||
/* ask the allocator to trim memory pools.
|
||||
* This must run under thread isolation so that competing threads trying to
|
||||
* allocate or release memory do not prevent the allocator from completing
|
||||
* its job. We just have to be careful as callers might already be isolated
|
||||
* themselves.
|
||||
*/
|
||||
static void trim_all_pools(void)
|
||||
{
|
||||
int isolated = thread_isolated();
|
||||
|
||||
if (!isolated)
|
||||
thread_isolate();
|
||||
|
||||
if (my_mallctl) {
|
||||
unsigned int i, narenas = 0;
|
||||
size_t len = sizeof(narenas);
|
||||
@ -80,6 +90,9 @@ static void trim_all_pools(void)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!isolated)
|
||||
thread_release();
|
||||
}
|
||||
|
||||
/* check if we're using the same allocator as the one that provides
|
||||
|
Loading…
Reference in New Issue
Block a user