net: buf: move user_data
to flexible arr member
Transition the `user_data` field in `struct net_buf` to be a flexible array member instead of a hardcoded array. Compile-time asserts are introduced at the location of the intermediate struct usage to ensure that the assumptions utilised in runtime code hold true. The primary assumptions are that the two `user_data` fields exist at the same memory offset, and that the instantiated struct size can be determined from the generic struct size and the length of the user data. `net_buf_id` and `pool_get_uninit` must now use manual address calculations as the `__bufs` type is no longer the actual size of the instantiated variable. Signed-off-by: Jordan Yates <jordan.yates@data61.csiro.au>
This commit is contained in:
parent
8d21e61df9
commit
bb780eff99
2 changed files with 25 additions and 10 deletions
|
@ -963,7 +963,7 @@ struct net_buf {
|
||||||
};
|
};
|
||||||
|
|
||||||
/** System metadata for this buffer. */
|
/** System metadata for this buffer. */
|
||||||
uint8_t user_data[CONFIG_NET_BUF_USER_DATA_SIZE] __net_buf_align;
|
uint8_t user_data[] __net_buf_align;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct net_buf_data_cb {
|
struct net_buf_data_cb {
|
||||||
|
@ -1033,7 +1033,7 @@ struct net_buf_pool {
|
||||||
.name = STRINGIFY(_pool), \
|
.name = STRINGIFY(_pool), \
|
||||||
.destroy = _destroy, \
|
.destroy = _destroy, \
|
||||||
.alloc = _alloc, \
|
.alloc = _alloc, \
|
||||||
.__bufs = _bufs, \
|
.__bufs = (struct net_buf *)_bufs, \
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
#define NET_BUF_POOL_INITIALIZER(_pool, _alloc, _bufs, _count, _ud_size, _destroy) \
|
#define NET_BUF_POOL_INITIALIZER(_pool, _alloc, _bufs, _count, _ud_size, _destroy) \
|
||||||
|
@ -1045,12 +1045,21 @@ struct net_buf_pool {
|
||||||
.user_data_size = _ud_size, \
|
.user_data_size = _ud_size, \
|
||||||
.destroy = _destroy, \
|
.destroy = _destroy, \
|
||||||
.alloc = _alloc, \
|
.alloc = _alloc, \
|
||||||
.__bufs = _bufs, \
|
.__bufs = (struct net_buf *)_bufs, \
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_NET_BUF_POOL_USAGE */
|
#endif /* CONFIG_NET_BUF_POOL_USAGE */
|
||||||
|
|
||||||
#define _NET_BUF_ARRAY_DEFINE(_name, _count) \
|
#define _NET_BUF_ARRAY_DEFINE(_name, _count, _ud_size) \
|
||||||
static struct net_buf _net_buf_##_name[_count] __noinit
|
struct _net_buf_##_name {struct net_buf b; uint8_t ud[_ud_size]; }; \
|
||||||
|
BUILD_ASSERT(_ud_size <= UINT8_MAX); \
|
||||||
|
BUILD_ASSERT(offsetof(struct net_buf, user_data) == \
|
||||||
|
offsetof(struct _net_buf_##_name, ud), "Invalid offset"); \
|
||||||
|
BUILD_ASSERT(__alignof__(struct net_buf) == \
|
||||||
|
__alignof__(struct _net_buf_##_name), "Invalid alignment"); \
|
||||||
|
BUILD_ASSERT(sizeof(struct _net_buf_##_name) == \
|
||||||
|
ROUND_UP(sizeof(struct net_buf) + _ud_size, __alignof__(struct net_buf)), \
|
||||||
|
"Size cannot be determined"); \
|
||||||
|
static struct _net_buf_##_name _net_buf_##_name[_count] __noinit
|
||||||
|
|
||||||
extern const struct net_buf_data_alloc net_buf_heap_alloc;
|
extern const struct net_buf_data_alloc net_buf_heap_alloc;
|
||||||
/** @endcond */
|
/** @endcond */
|
||||||
|
@ -1082,7 +1091,7 @@ extern const struct net_buf_data_alloc net_buf_heap_alloc;
|
||||||
* @param _destroy Optional destroy callback when buffer is freed.
|
* @param _destroy Optional destroy callback when buffer is freed.
|
||||||
*/
|
*/
|
||||||
#define NET_BUF_POOL_HEAP_DEFINE(_name, _count, _destroy) \
|
#define NET_BUF_POOL_HEAP_DEFINE(_name, _count, _destroy) \
|
||||||
_NET_BUF_ARRAY_DEFINE(_name, _count); \
|
_NET_BUF_ARRAY_DEFINE(_name, _count, CONFIG_NET_BUF_USER_DATA_SIZE); \
|
||||||
static struct net_buf_pool _name __net_buf_align \
|
static struct net_buf_pool _name __net_buf_align \
|
||||||
__in_section(_net_buf_pool, static, _name) = \
|
__in_section(_net_buf_pool, static, _name) = \
|
||||||
NET_BUF_POOL_INITIALIZER(_name, &net_buf_heap_alloc, \
|
NET_BUF_POOL_INITIALIZER(_name, &net_buf_heap_alloc, \
|
||||||
|
@ -1127,7 +1136,7 @@ extern const struct net_buf_data_cb net_buf_fixed_cb;
|
||||||
* @param _destroy Optional destroy callback when buffer is freed.
|
* @param _destroy Optional destroy callback when buffer is freed.
|
||||||
*/
|
*/
|
||||||
#define NET_BUF_POOL_FIXED_DEFINE(_name, _count, _data_size, _destroy) \
|
#define NET_BUF_POOL_FIXED_DEFINE(_name, _count, _data_size, _destroy) \
|
||||||
_NET_BUF_ARRAY_DEFINE(_name, _count); \
|
_NET_BUF_ARRAY_DEFINE(_name, _count, CONFIG_NET_BUF_USER_DATA_SIZE); \
|
||||||
static uint8_t __noinit net_buf_data_##_name[_count][_data_size]; \
|
static uint8_t __noinit net_buf_data_##_name[_count][_data_size]; \
|
||||||
static const struct net_buf_pool_fixed net_buf_fixed_##_name = { \
|
static const struct net_buf_pool_fixed net_buf_fixed_##_name = { \
|
||||||
.data_size = _data_size, \
|
.data_size = _data_size, \
|
||||||
|
@ -1172,7 +1181,7 @@ extern const struct net_buf_data_cb net_buf_var_cb;
|
||||||
* @param _destroy Optional destroy callback when buffer is freed.
|
* @param _destroy Optional destroy callback when buffer is freed.
|
||||||
*/
|
*/
|
||||||
#define NET_BUF_POOL_VAR_DEFINE(_name, _count, _data_size, _destroy) \
|
#define NET_BUF_POOL_VAR_DEFINE(_name, _count, _data_size, _destroy) \
|
||||||
_NET_BUF_ARRAY_DEFINE(_name, _count); \
|
_NET_BUF_ARRAY_DEFINE(_name, _count, CONFIG_NET_BUF_USER_DATA_SIZE); \
|
||||||
K_HEAP_DEFINE(net_buf_mem_pool_##_name, _data_size); \
|
K_HEAP_DEFINE(net_buf_mem_pool_##_name, _data_size); \
|
||||||
static const struct net_buf_data_alloc net_buf_data_alloc_##_name = { \
|
static const struct net_buf_data_alloc net_buf_data_alloc_##_name = { \
|
||||||
.cb = &net_buf_var_cb, \
|
.cb = &net_buf_var_cb, \
|
||||||
|
|
|
@ -58,16 +58,22 @@ static int pool_id(struct net_buf_pool *pool)
|
||||||
int net_buf_id(struct net_buf *buf)
|
int net_buf_id(struct net_buf *buf)
|
||||||
{
|
{
|
||||||
struct net_buf_pool *pool = net_buf_pool_get(buf->pool_id);
|
struct net_buf_pool *pool = net_buf_pool_get(buf->pool_id);
|
||||||
|
size_t struct_size = ROUND_UP(sizeof(struct net_buf) + pool->user_data_size,
|
||||||
|
__alignof__(struct net_buf));
|
||||||
|
ptrdiff_t offset = (uint8_t *)buf - (uint8_t *)pool->__bufs;
|
||||||
|
|
||||||
return buf - pool->__bufs;
|
return offset / struct_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline struct net_buf *pool_get_uninit(struct net_buf_pool *pool,
|
static inline struct net_buf *pool_get_uninit(struct net_buf_pool *pool,
|
||||||
uint16_t uninit_count)
|
uint16_t uninit_count)
|
||||||
{
|
{
|
||||||
|
size_t struct_size = ROUND_UP(sizeof(struct net_buf) + pool->user_data_size,
|
||||||
|
__alignof__(struct net_buf));
|
||||||
|
size_t byte_offset = (pool->buf_count - uninit_count) * struct_size;
|
||||||
struct net_buf *buf;
|
struct net_buf *buf;
|
||||||
|
|
||||||
buf = &pool->__bufs[pool->buf_count - uninit_count];
|
buf = (struct net_buf *)(((uint8_t *)pool->__bufs) + byte_offset);
|
||||||
|
|
||||||
buf->pool_id = pool_id(pool);
|
buf->pool_id = pool_id(pool);
|
||||||
buf->user_data_size = pool->user_data_size;
|
buf->user_data_size = pool->user_data_size;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue