diff --git a/include/haproxy/pool-t.h b/include/haproxy/pool-t.h index 47fa34a5d..460173c6f 100644 --- a/include/haproxy/pool-t.h +++ b/include/haproxy/pool-t.h @@ -118,8 +118,9 @@ struct pool_head { unsigned int failed; /* failed allocations */ unsigned int alloc_sz; /* allocated size (includes hidden fields) */ struct list list; /* list of all known pools */ + void *base_addr; /* allocation address, for free() */ char name[12]; /* name of the pool */ - struct pool_cache_head cache[MAX_THREADS]; /* pool caches */ + struct pool_cache_head cache[MAX_THREADS] THREAD_ALIGNED(64); /* pool caches */ } __attribute__((aligned(64))); #endif /* _HAPROXY_POOL_T_H */ diff --git a/src/pool.c b/src/pool.c index 45c05fa45..441133e7c 100644 --- a/src/pool.c +++ b/src/pool.c @@ -275,11 +275,16 @@ struct pool_head *create_pool(char *name, unsigned int size, unsigned int flags) } if (!pool) { - if (!pool) - pool = calloc(1, sizeof(*pool)); + void *pool_addr; - if (!pool) + pool_addr = calloc(1, sizeof(*pool) + __alignof__(*pool)); + if (!pool_addr) return NULL; + + /* always provide an aligned pool */ + pool = (struct pool_head*)((((size_t)pool_addr) + __alignof__(*pool)) & -(size_t)__alignof__(*pool)); + pool->base_addr = pool_addr; // keep it, it's the address to free later + if (name) strlcpy2(pool->name, name, sizeof(pool->name)); pool->alloc_sz = size + extra; @@ -816,7 +821,7 @@ void *pool_destroy(struct pool_head *pool) if (!pool->users) { LIST_DELETE(&pool->list); /* note that if used == 0, the cache is empty */ - free(pool); + ha_free(&pool->base_addr); } } return NULL;