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 a9234dd..8180bfb 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 2c3c7db..541e0d9 100644
--- a/include/haproxy/pool.h
+++ b/include/haproxy/pool.h
@@ -129,7 +129,6 @@
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 8462acc..3c85b08 100644
--- a/src/pool.c
+++ b/src/pool.c
@@ -37,12 +37,13 @@
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 @@
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 *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 @@
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 @@
}
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 }
}};