From: Willy Tarreau Date: Mon, 21 Feb 2022 16:16:22 +0000 (+0100) Subject: MINOR: pools: switch the fail-alloc test to runtime only X-Git-Tag: v2.6-dev2~83 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8d0273ed88ceac6d02bc30234d07dd77dee89b11;p=thirdparty%2Fhaproxy.git MINOR: pools: switch the fail-alloc test to runtime only The fail-alloc test used to be enabled/disabled at build time using the DEBUG_FAIL_ALLOC macro, but it happens that the cost of the test is quite cheap and that it can be enabled as one of the pool_debugging options. This patch thus introduces the first POOL_DBG_FAIL_ALLOC option, whose default value depends on DEBUG_FAIL_ALLOC. The mem_should_fail() function is now always built, but it was made static since it's never used outside. --- diff --git a/include/haproxy/pool-t.h b/include/haproxy/pool-t.h index a9234dd3c6..8180bfb158 100644 --- a/include/haproxy/pool-t.h +++ b/include/haproxy/pool-t.h @@ -40,6 +40,9 @@ #define POOL_F_MUST_ZERO 0x00000002 // zero the returned area #define POOL_F_NO_FAIL 0x00000004 // do not randomly fail +/* pool debugging flags */ +#define POOL_DBG_FAIL_ALLOC 0x00000001 // randomly fail memory allocations + /* This is the head of a thread-local cache */ struct pool_cache_head { diff --git a/include/haproxy/pool.h b/include/haproxy/pool.h index 2c3c7db550..541e0d96bf 100644 --- a/include/haproxy/pool.h +++ b/include/haproxy/pool.h @@ -129,7 +129,6 @@ struct pool_head *create_pool(char *name, unsigned int size, unsigned int flags) void create_pool_callback(struct pool_head **ptr, char *name, unsigned int size); void *pool_destroy(struct pool_head *pool); void pool_destroy_all(void); -int mem_should_fail(const struct pool_head *pool); void *__pool_alloc(struct pool_head *pool, unsigned int flags); void __pool_free(struct pool_head *pool, void *ptr); diff --git a/src/pool.c b/src/pool.c index 8462accd03..3c85b08ee6 100644 --- a/src/pool.c +++ b/src/pool.c @@ -37,12 +37,13 @@ THREAD_LOCAL size_t pool_cache_count = 0; /* #cache objects */ static struct list pools __read_mostly = LIST_HEAD_INIT(pools); int mem_poison_byte __read_mostly = -1; -uint pool_debugging __read_mostly = 0; /* set of POOL_DBG_* flags */ - +uint pool_debugging __read_mostly = /* set of POOL_DBG_* flags */ #ifdef DEBUG_FAIL_ALLOC -static int mem_fail_rate __read_mostly = 0; + POOL_DBG_FAIL_ALLOC | #endif + 0; +static int mem_fail_rate __read_mostly = 0; static int using_default_allocator __read_mostly = 1; static int(*my_mallctl)(const char *, void *, size_t *, void *, size_t) = NULL; @@ -151,6 +152,19 @@ static int is_trim_enabled(void) return using_default_allocator; } +static int mem_should_fail(const struct pool_head *pool) +{ + int ret = 0; + + if (mem_fail_rate > 0 && !(global.mode & MODE_STARTING)) { + if (mem_fail_rate > statistical_prng_range(100)) + ret = 1; + else + ret = 0; + } + return ret; +} + /* Try to find an existing shared pool with the same characteristics and * returns it, otherwise creates this one. NULL is returned if no memory * is available for a new creation. Two flags are supported : @@ -619,10 +633,9 @@ void *__pool_alloc(struct pool_head *pool, unsigned int flags) void *p = NULL; void *caller = NULL; -#ifdef DEBUG_FAIL_ALLOC - if (unlikely(!(flags & POOL_F_NO_FAIL) && mem_should_fail(pool))) - return NULL; -#endif + if (unlikely(pool_debugging & POOL_DBG_FAIL_ALLOC)) + if (!(flags & POOL_F_NO_FAIL) && mem_should_fail(pool)) + return NULL; #if defined(DEBUG_POOL_TRACING) caller = __builtin_return_address(0); @@ -898,21 +911,6 @@ static struct cli_kw_list cli_kws = {{ },{ INITCALL1(STG_REGISTER, cli_register_kw, &cli_kws); -#ifdef DEBUG_FAIL_ALLOC - -int mem_should_fail(const struct pool_head *pool) -{ - int ret = 0; - - if (mem_fail_rate > 0 && !(global.mode & MODE_STARTING)) { - if (mem_fail_rate > statistical_prng_range(100)) - ret = 1; - else - ret = 0; - } - return ret; - -} /* config parser for global "tune.fail-alloc" */ static int mem_parse_global_fail_alloc(char **args, int section_type, struct proxy *curpx, @@ -928,13 +926,10 @@ static int mem_parse_global_fail_alloc(char **args, int section_type, struct pro } return 0; } -#endif /* register global config keywords */ static struct cfg_kw_list mem_cfg_kws = {ILH, { -#ifdef DEBUG_FAIL_ALLOC { CFG_GLOBAL, "tune.fail-alloc", mem_parse_global_fail_alloc }, -#endif { 0, NULL, NULL } }};