diff options
author | Mathieu Desnoyers <mathieu.desnoyers@efficios.com> | 2024-03-07 16:12:37 -0500 |
---|---|---|
committer | Mathieu Desnoyers <mathieu.desnoyers@efficios.com> | 2024-03-07 16:12:37 -0500 |
commit | d6acc8aac98139340f010efde53c6e71239ae1fa (patch) | |
tree | e9ed8d9e0bc0fd5f79bf779ce7586f9166acd84c | |
parent | 8118247ec2f3912f2fb59db3a77eca5b3723f330 (diff) | |
download | librseq-d6acc8aac98139340f010efde53c6e71239ae1fa.tar.gz |
percpu pool: Move robust flag to atttribute
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Change-Id: Ie83fff22b71dc9be39d90e4be97d094b90542715
-rw-r--r-- | include/rseq/percpu-alloc.h | 34 | ||||
-rw-r--r-- | src/rseq-percpu-alloc.c | 24 | ||||
-rw-r--r-- | tests/param_test.c | 12 |
3 files changed, 45 insertions, 25 deletions
diff --git a/include/rseq/percpu-alloc.h b/include/rseq/percpu-alloc.h index 1532ed6..d3b1149 100644 --- a/include/rseq/percpu-alloc.h +++ b/include/rseq/percpu-alloc.h @@ -65,17 +65,14 @@ struct rseq_percpu_pool; * next power of two). The reserved allocation size is @percpu_len, and * the maximum CPU value expected is (@max_nr_cpus - 1). * - * The @pool_attr pointer used to specify the pool attributes. If NULL, - * use a default attribute values. The @pool_attr can be destroyed - * immediately after rseq_percpu_pool_create() returns. The caller keeps - * ownership of @pool_attr. + * The @attr pointer used to specify the pool attributes. If NULL, use a + * default attribute values. The @attr can be destroyed immediately + * after rseq_percpu_pool_create() returns. The caller keeps ownership + * of @attr. * * The argument @pool_name can be used to given a name to the pool for * debugging purposes. It can be NULL if no name is given. * - * Argument @flags is a bitwise-or'd selector of: - * - RSEQ_POOL_ROBUST - * * Returns a pointer to the created percpu pool. Return NULL on error, * with errno set accordingly: * EINVAL: Invalid argument. @@ -90,8 +87,7 @@ struct rseq_percpu_pool; */ struct rseq_percpu_pool *rseq_percpu_pool_create(const char *pool_name, size_t item_len, size_t percpu_len, int max_nr_cpus, - const struct rseq_pool_attr *attr, - int flags); + const struct rseq_pool_attr *attr); /* * rseq_percpu_pool_destroy: Destroy a per-cpu memory pool. @@ -311,6 +307,26 @@ int rseq_pool_attr_set_mmap(struct rseq_pool_attr *attr, int (*munmap_func)(void *priv, void *ptr, size_t len), void *mmap_priv); +/* + * rseq_pool_attr_set_robust: Set pool robust attribute. + * + * The robust pool attribute enables runtime validation of the pool: + * + * - Check for double-free of pointers. + * + * - Detect memory leaks on pool destruction. + * + * - Detect free-list corruption on pool destruction. + * + * There is a marginal runtime overhead on malloc/free operations. + * + * The memory overhead is (pool->percpu_len / pool->item_len) / CHAR_BIT + * bytes, over the lifetime of the pool. + * + * Returns 0 on success, -1 with errno=EINVAL if arguments are invalid. + */ +int rseq_pool_attr_set_robust(struct rseq_pool_attr *attr); + #ifdef __cplusplus } #endif diff --git a/src/rseq-percpu-alloc.c b/src/rseq-percpu-alloc.c index daccf86..0a509c6 100644 --- a/src/rseq-percpu-alloc.c +++ b/src/rseq-percpu-alloc.c @@ -66,8 +66,6 @@ */ #define FIRST_POOL 1 -#define RSEQ_POOL_FLAGS (RSEQ_POOL_ROBUST) - #define BIT_PER_ULONG (8 * sizeof(unsigned long)) struct free_list_node; @@ -84,6 +82,8 @@ struct rseq_pool_attr { void *(*mmap_func)(void *priv, size_t len); int (*munmap_func)(void *priv, void *ptr, size_t len); void *mmap_priv; + + bool robust_set; }; struct rseq_percpu_pool { @@ -342,8 +342,7 @@ int rseq_percpu_pool_destroy(struct rseq_percpu_pool *pool) struct rseq_percpu_pool *rseq_percpu_pool_create(const char *pool_name, size_t item_len, size_t percpu_len, int max_nr_cpus, - const struct rseq_pool_attr *_attr, - int flags) + const struct rseq_pool_attr *_attr) { struct rseq_percpu_pool *pool; struct rseq_pool_attr attr = {}; @@ -351,11 +350,6 @@ struct rseq_percpu_pool *rseq_percpu_pool_create(const char *pool_name, unsigned int i; int order; - if (flags & ~RSEQ_POOL_FLAGS) { - errno = EINVAL; - return NULL; - } - /* Make sure each item is large enough to contain free list pointers. */ if (item_len < sizeof(void *)) item_len = sizeof(void *); @@ -415,7 +409,7 @@ found_empty: goto error_alloc; } - if (RSEQ_POOL_ROBUST & flags) { + if (attr.robust_set) { if (create_alloc_bitmap(pool)) goto error_alloc; } @@ -666,3 +660,13 @@ int rseq_pool_attr_set_mmap(struct rseq_pool_attr *attr, attr->mmap_priv = mmap_priv; return 0; } + +int rseq_pool_attr_set_robust(struct rseq_pool_attr *attr) +{ + if (!attr) { + errno = EINVAL; + return -1; + } + attr->robust_set = true; + return 0; +} diff --git a/tests/param_test.c b/tests/param_test.c index a3a338c..3ed1981 100644 --- a/tests/param_test.c +++ b/tests/param_test.c @@ -501,7 +501,7 @@ static void test_percpu_spinlock(void) mempool = rseq_percpu_pool_create("spinlock_test_data", sizeof(struct spinlock_test_data), - PERCPU_POOL_LEN, CPU_SETSIZE, NULL, 0); + PERCPU_POOL_LEN, CPU_SETSIZE, NULL); if (!mempool) { perror("rseq_percpu_pool_create"); abort(); @@ -597,7 +597,7 @@ static void test_percpu_inc(void) mempool = rseq_percpu_pool_create("inc_test_data", sizeof(struct inc_test_data), - PERCPU_POOL_LEN, CPU_SETSIZE, NULL, 0); + PERCPU_POOL_LEN, CPU_SETSIZE, NULL); if (!mempool) { perror("rseq_percpu_pool_create"); abort(); @@ -770,7 +770,7 @@ static void test_percpu_list(void) struct rseq_percpu_pool *mempool; mempool = rseq_percpu_pool_create("percpu_list", sizeof(struct percpu_list), - PERCPU_POOL_LEN, CPU_SETSIZE, NULL, 0); + PERCPU_POOL_LEN, CPU_SETSIZE, NULL); if (!mempool) { perror("rseq_percpu_pool_create"); abort(); @@ -981,7 +981,7 @@ static void test_percpu_buffer(void) struct rseq_percpu_pool *mempool; mempool = rseq_percpu_pool_create("percpu_buffer", sizeof(struct percpu_buffer), - PERCPU_POOL_LEN, CPU_SETSIZE, NULL, 0); + PERCPU_POOL_LEN, CPU_SETSIZE, NULL); if (!mempool) { perror("rseq_percpu_pool_create"); abort(); @@ -1222,7 +1222,7 @@ static void test_percpu_memcpy_buffer(void) mempool = rseq_percpu_pool_create("percpu_memcpy_buffer", sizeof(struct percpu_memcpy_buffer), - PERCPU_POOL_LEN, CPU_SETSIZE, NULL, 0); + PERCPU_POOL_LEN, CPU_SETSIZE, NULL); if (!mempool) { perror("rseq_percpu_pool_create"); abort(); @@ -1468,7 +1468,7 @@ void *test_membarrier_manager_thread(void *arg) long long total_count = 0; mempool = rseq_percpu_pool_create("percpu_list", sizeof(struct percpu_list), - PERCPU_POOL_LEN, CPU_SETSIZE, NULL, 0); + PERCPU_POOL_LEN, CPU_SETSIZE, NULL); if (!mempool) { perror("rseq_percpu_pool_create"); abort(); |