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.
This commit is contained in:
Willy Tarreau 2025-08-11 15:24:33 +02:00
parent 5e2837cfb4
commit d240f387ca
2 changed files with 14 additions and 12 deletions

View File

@ -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 */
};

View File

@ -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 <ptr> 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 <ptr> 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 <ptr> 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 <ptr> 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 <ptr> 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 <ptr> 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