From 147e1fa38576188d4432fbb63b987010028ac986 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Sun, 18 Apr 2021 11:11:14 +0200 Subject: [PATCH] MINOR: pools: create unified pool_{get_from,put_to}_cache() These two functions are now responsible for allocating directly from the cache and releasing to the cache. Now the pool_alloc() function simply does this: if cache enabled return pool_alloc_from_cache() if no NULL return pool_alloc_nocache() otherwise and the pool_free() function does this: if cache enabled pool_put_to_cache() else pool_free_nocache() For now this only introduces these two functions without changing anything else, but the goal is to soon allow to make them implementation-specific. --- include/haproxy/pool.h | 55 +++++++++++++++++++++++++++++++----------- 1 file changed, 41 insertions(+), 14 deletions(-) diff --git a/include/haproxy/pool.h b/include/haproxy/pool.h index df0199196..dc01e1a80 100644 --- a/include/haproxy/pool.h +++ b/include/haproxy/pool.h @@ -260,6 +260,45 @@ static inline void pool_put_to_shared_cache(struct pool_head *pool, void *ptr) #endif /* CONFIG_HAP_LOCKLESS_POOLS */ +/* These are generic cache-aware wrappers that allocate/free from/to the local + * cache first, then from the second level if it exists. + */ + + +/* Tries to allocate from the local cache first, then from the shared cache if + * it exists. Returns the item found or NULL if none was found. + */ +static inline void *pool_get_from_cache(struct pool_head *pool) +{ + void *ptr; + + ptr = pool_get_from_local_cache(pool); + if (!ptr) + ptr = pool_get_from_shared_cache(pool); + return ptr; +} + +/* Releases the object to the cache. Usually the local cache will be used, + * unless it is too crowded in which case the cache may decide to move objects + * to the shared cache, which itself may decide to release some of them to the + * OS. While it is unspecified what the object becomes past this point, it is + * guaranteed to be released from the users' perpective. + */ +static inline void pool_put_to_cache(struct pool_head *pool, void *ptr) +{ + /* put the object back into the cache only if there are not too + * many objects yet in this pool (no more than half of the cached + * is used or this pool uses no more than 1/8 of the cache size). + */ + if ((pool_cache_bytes <= CONFIG_HAP_POOL_CACHE_SIZE * 3 / 4 || + pool->cache[tid].count < 16 + pool_cache_count / 8)) { + pool_put_to_local_cache(pool, ptr); + return; + } + pool_put_to_shared_cache(pool, ptr); +} + + #endif /* CONFIG_HAP_POOLS */ @@ -282,10 +321,7 @@ static inline void *__pool_alloc(struct pool_head *pool, unsigned int flags) #ifdef CONFIG_HAP_POOLS if (!p) - p = pool_get_from_local_cache(pool); - - if (!p) - p = pool_get_from_shared_cache(pool); + p = pool_get_from_cache(pool); #endif if (!p) p = pool_alloc_nocache(pool); @@ -338,16 +374,7 @@ static inline void pool_free(struct pool_head *pool, void *ptr) memset(ptr, mem_poison_byte, pool->size); #ifdef CONFIG_HAP_POOLS - /* put the object back into the cache only if there are not too - * many objects yet in this pool (no more than half of the cached - * is used or this pool uses no more than 1/8 of the cache size). - */ - if ((pool_cache_bytes <= CONFIG_HAP_POOL_CACHE_SIZE * 3 / 4 || - pool->cache[tid].count < 16 + pool_cache_count / 8)) { - pool_put_to_local_cache(pool, ptr); - return; - } - pool_put_to_shared_cache(pool, ptr); + pool_put_to_cache(pool, ptr); #else pool_free_nocache(pool, ptr); #endif