From d240f387ca16177f12d5a02ba102740e45c1a18a Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Mon, 11 Aug 2025 15:24:33 +0200 Subject: [PATCH] MINOR: pools: distinguish the requested alignment from the type-specific one We're letting users request an alignment but that can violate one imposed by a type, especially if we start seeing REGISTER_TYPED_POOL() grow in adoption, encouraging users to specify alignment on their types. On the other hand, if we ask the user to always specify the alignment, no control is possible and the error is easy. Let's have a second field in the pool registration, for the type-specific one. We'll set it to zero when unknown, and to the types's alignment when known. This way it will become possible to compare them at startup time to detect conflicts. For now no macro permits to set both separately so this is not visible. --- include/haproxy/pool-t.h | 1 + include/haproxy/pool.h | 25 +++++++++++++------------ 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/include/haproxy/pool-t.h b/include/haproxy/pool-t.h index 883d4d5bc..a9ef9e828 100644 --- a/include/haproxy/pool-t.h +++ b/include/haproxy/pool-t.h @@ -75,6 +75,7 @@ struct pool_registration { unsigned int line; /* line in the file where the pool is declared, 0 if none */ unsigned int size; /* expected object size */ unsigned int flags; /* MEM_F_* */ + unsigned int type_align; /* type-imposed alignment; 0=unspecified */ unsigned int align; /* expected alignment; 0=unspecified */ }; diff --git a/include/haproxy/pool.h b/include/haproxy/pool.h index fdfd89225..5abe8c25b 100644 --- a/include/haproxy/pool.h +++ b/include/haproxy/pool.h @@ -33,13 +33,14 @@ /* This creates a pool_reg registers a call to create_pool_callback(ptr) with it. * Do not use this one, use REGISTER_POOL() instead. */ -#define __REGISTER_POOL(_line, _ptr, _name, _size, _align) \ +#define __REGISTER_POOL(_line, _ptr, _name, _size, _type_align, _align) \ static struct pool_registration __pool_reg_##_line = { \ .name = _name, \ .file = __FILE__, \ .line = __LINE__, \ .size = _size, \ .flags = MEM_F_STATREG, \ + .type_align = _type_align, \ .align = _align, \ }; \ INITCALL3(STG_POOL, create_pool_callback, (_ptr), (_name), &__pool_reg_##_line); @@ -47,54 +48,54 @@ /* intermediary level for line number resolution, do not use this one, use * REGISTER_POOL() instead. */ -#define _REGISTER_POOL(line, ptr, name, size, align) \ - __REGISTER_POOL(line, ptr, name, size, align) +#define _REGISTER_POOL(line, ptr, name, size, align, type_align) \ + __REGISTER_POOL(line, ptr, name, size, align, type_align) /* This registers a call to create_pool_callback(ptr) with these args */ #define REGISTER_POOL(ptr, name, size) \ - _REGISTER_POOL(__LINE__, ptr, name, size, 0) + _REGISTER_POOL(__LINE__, ptr, name, size, 0, 0) /* This macro declares a pool head and registers its creation */ #define DECLARE_POOL(ptr, name, size) \ struct pool_head *(ptr) __read_mostly = NULL; \ - _REGISTER_POOL(__LINE__, &ptr, name, size, 0) + _REGISTER_POOL(__LINE__, &ptr, name, size, 0, 0) /* This macro declares a static pool head and registers its creation */ #define DECLARE_STATIC_POOL(ptr, name, size) \ static struct pool_head *(ptr) __read_mostly; \ - _REGISTER_POOL(__LINE__, &ptr, name, size, 0) + _REGISTER_POOL(__LINE__, &ptr, name, size, 0, 0) /*** below are the aligned pool macros, taking one extra arg for alignment ***/ /* This registers a call to create_pool_callback(ptr) with these args */ #define REGISTER_ALIGNED_POOL(ptr, name, size, align) \ - _REGISTER_POOL(__LINE__, ptr, name, size, align) + _REGISTER_POOL(__LINE__, ptr, name, size, 0, align) /* This macro declares an aligned pool head and registers its creation */ #define DECLARE_ALIGNED_POOL(ptr, name, size, align) \ struct pool_head *(ptr) __read_mostly = NULL; \ - _REGISTER_POOL(__LINE__, &ptr, name, size, align) + _REGISTER_POOL(__LINE__, &ptr, name, size, 0, align) /* This macro declares a static aligned pool head and registers its creation */ #define DECLARE_STATIC_ALIGNED_POOL(ptr, name, size, align) \ static struct pool_head *(ptr) __read_mostly; \ - _REGISTER_POOL(__LINE__, &ptr, name, size, align) + _REGISTER_POOL(__LINE__, &ptr, name, size, 0, align) /*** below are the typed pool macros, taking a type and an extra size ***/ /* This registers a call to create_pool_callback(ptr) with these args */ #define REGISTER_TYPED_POOL(ptr, name, type, extra) \ - _REGISTER_POOL(__LINE__, ptr, name, sizeof(type) + extra, __alignof__(type)) + _REGISTER_POOL(__LINE__, ptr, name, sizeof(type) + extra, __alignof__(type), __alignof__(type)) /* This macro declares an aligned pool head and registers its creation */ #define DECLARE_TYPED_POOL(ptr, name, type, extra) \ struct pool_head *(ptr) __read_mostly = NULL; \ - _REGISTER_POOL(__LINE__, &ptr, name, sizeof(type) + extra, __alignof__(type)) + _REGISTER_POOL(__LINE__, &ptr, name, sizeof(type) + extra, __alignof__(type), __alignof__(type)) /* This macro declares a static aligned pool head and registers its creation */ #define DECLARE_STATIC_TYPED_POOL(ptr, name, type, extra) \ static struct pool_head *(ptr) __read_mostly; \ - _REGISTER_POOL(__LINE__, &ptr, name, sizeof(type) + extra, __alignof__(type)) + _REGISTER_POOL(__LINE__, &ptr, name, sizeof(type) + extra, __alignof__(type), __alignof__(type)) /* By default, free objects are linked by a pointer stored at the beginning of * the memory area. When DEBUG_MEMORY_POOLS is set, the allocated area is