Bluetooth: controller: Improve mem mngt of proc ctx

Move the mem_pool structure to the internal header for wider access.
Introduce a mem_pool owner in the proc_ctx, sch that multiple mem_pool
could be used for memory management of proc_ctx, also static 'foreign'
allocated proc_ctx would be supported by this.

Signed-off-by: Thomas Ebert Hansen <thoh@oticon.com>
This commit is contained in:
Thomas Ebert Hansen 2022-02-09 13:06:15 +01:00 committed by Carles Cufí
commit cecb12e9d9
2 changed files with 34 additions and 21 deletions

View file

@ -43,12 +43,6 @@
#include <soc.h> #include <soc.h>
#include "hal/debug.h" #include "hal/debug.h"
/* LLCP Memory Pool Descriptor */
struct mem_pool {
void *free;
uint8_t *pool;
};
#define LLCTRL_PDU_SIZE (offsetof(struct pdu_data, llctrl) + sizeof(struct pdu_data_llctrl)) #define LLCTRL_PDU_SIZE (offsetof(struct pdu_data, llctrl) + sizeof(struct pdu_data_llctrl))
#define PROC_CTX_BUF_SIZE WB_UP(sizeof(struct proc_ctx)) #define PROC_CTX_BUF_SIZE WB_UP(sizeof(struct proc_ctx))
#define TX_CTRL_BUF_SIZE WB_UP(offsetof(struct node_tx, pdu) + LLCTRL_PDU_SIZE) #define TX_CTRL_BUF_SIZE WB_UP(offsetof(struct node_tx, pdu) + LLCTRL_PDU_SIZE)
@ -62,26 +56,36 @@ static uint8_t common_tx_buffer_alloc;
/* TODO: Determine 'correct' number of tx nodes */ /* TODO: Determine 'correct' number of tx nodes */
static uint8_t buffer_mem_tx[TX_CTRL_BUF_SIZE * LLCP_TX_CTRL_BUF_COUNT]; static uint8_t buffer_mem_tx[TX_CTRL_BUF_SIZE * LLCP_TX_CTRL_BUF_COUNT];
static struct mem_pool mem_tx = { .pool = buffer_mem_tx }; static struct llcp_mem_pool mem_tx = { .pool = buffer_mem_tx };
/* TODO: Determine 'correct' number of ctx */ /* TODO: Determine 'correct' number of ctx */
static uint8_t buffer_mem_ctx[PROC_CTX_BUF_SIZE * CONFIG_BT_CTLR_LLCP_PROC_CTX_BUF_NUM]; static uint8_t buffer_mem_ctx[PROC_CTX_BUF_SIZE * CONFIG_BT_CTLR_LLCP_PROC_CTX_BUF_NUM];
static struct mem_pool mem_ctx = { .pool = buffer_mem_ctx }; static struct llcp_mem_pool mem_ctx = { .pool = buffer_mem_ctx };
/* /*
* LLCP Resource Management * LLCP Resource Management
*/ */
static struct proc_ctx *proc_ctx_acquire(void) static struct proc_ctx *proc_ctx_acquire(struct llcp_mem_pool *owner)
{ {
struct proc_ctx *ctx; struct proc_ctx *ctx;
ctx = (struct proc_ctx *)mem_acquire(&mem_ctx.free); ctx = (struct proc_ctx *)mem_acquire(&owner->free);
if (ctx) {
/* Set the owner */
ctx->owner = owner;
}
return ctx; return ctx;
} }
void llcp_proc_ctx_release(struct proc_ctx *ctx) void llcp_proc_ctx_release(struct proc_ctx *ctx)
{ {
mem_release(ctx, &mem_ctx.free); /* We need to have an owner otherwise the memory allocated would leak */
LL_ASSERT(ctx->owner);
/* Release the memory back to the owner */
mem_release(ctx, &ctx->owner->free);
} }
#if defined(LLCP_TX_CTRL_BUF_QUEUE_ENABLE) #if defined(LLCP_TX_CTRL_BUF_QUEUE_ENABLE)
@ -249,11 +253,11 @@ void llcp_tx_flush(struct ll_conn *conn)
* LLCP Procedure Creation * LLCP Procedure Creation
*/ */
static struct proc_ctx *create_procedure(enum llcp_proc proc) static struct proc_ctx *create_procedure(enum llcp_proc proc, struct llcp_mem_pool *ctx_pool)
{ {
struct proc_ctx *ctx; struct proc_ctx *ctx;
ctx = proc_ctx_acquire(); ctx = proc_ctx_acquire(ctx_pool);
if (!ctx) { if (!ctx) {
return NULL; return NULL;
} }
@ -278,7 +282,7 @@ struct proc_ctx *llcp_create_local_procedure(enum llcp_proc proc)
{ {
struct proc_ctx *ctx; struct proc_ctx *ctx;
ctx = create_procedure(proc); ctx = create_procedure(proc, &mem_ctx);
if (!ctx) { if (!ctx) {
return NULL; return NULL;
} }
@ -346,7 +350,7 @@ struct proc_ctx *llcp_create_remote_procedure(enum llcp_proc proc)
{ {
struct proc_ctx *ctx; struct proc_ctx *ctx;
ctx = create_procedure(proc); ctx = create_procedure(proc, &mem_ctx);
if (!ctx) { if (!ctx) {
return NULL; return NULL;
} }
@ -1042,7 +1046,7 @@ void test_int_mem_proc_ctx(void)
zassert_equal(nr_of_free_ctx, CONFIG_BT_CTLR_LLCP_PROC_CTX_BUF_NUM, NULL); zassert_equal(nr_of_free_ctx, CONFIG_BT_CTLR_LLCP_PROC_CTX_BUF_NUM, NULL);
for (int i = 0U; i < CONFIG_BT_CTLR_LLCP_PROC_CTX_BUF_NUM; i++) { for (int i = 0U; i < CONFIG_BT_CTLR_LLCP_PROC_CTX_BUF_NUM; i++) {
ctx1 = proc_ctx_acquire(); ctx1 = proc_ctx_acquire(&mem_ctx);
/* The previous acquire should be valid */ /* The previous acquire should be valid */
zassert_not_null(ctx1, NULL); zassert_not_null(ctx1, NULL);
@ -1051,7 +1055,7 @@ void test_int_mem_proc_ctx(void)
nr_of_free_ctx = ctx_buffers_free(); nr_of_free_ctx = ctx_buffers_free();
zassert_equal(nr_of_free_ctx, 0, NULL); zassert_equal(nr_of_free_ctx, 0, NULL);
ctx2 = proc_ctx_acquire(); ctx2 = proc_ctx_acquire(&mem_ctx);
/* The last acquire should fail */ /* The last acquire should fail */
zassert_is_null(ctx2, NULL); zassert_is_null(ctx2, NULL);
@ -1060,7 +1064,7 @@ void test_int_mem_proc_ctx(void)
nr_of_free_ctx = ctx_buffers_free(); nr_of_free_ctx = ctx_buffers_free();
zassert_equal(nr_of_free_ctx, 1, NULL); zassert_equal(nr_of_free_ctx, 1, NULL);
ctx1 = proc_ctx_acquire(); ctx1 = proc_ctx_acquire(&mem_ctx);
/* Releasing returns the context to the avilable pool */ /* Releasing returns the context to the avilable pool */
zassert_not_null(ctx1, NULL); zassert_not_null(ctx1, NULL);
@ -1137,7 +1141,7 @@ void test_int_create_proc(void)
ull_cp_init(); ull_cp_init();
ctx = create_procedure(PROC_VERSION_EXCHANGE); ctx = create_procedure(PROC_VERSION_EXCHANGE, &mem_ctx);
zassert_not_null(ctx, NULL); zassert_not_null(ctx, NULL);
zassert_equal(ctx->proc, PROC_VERSION_EXCHANGE, NULL); zassert_equal(ctx->proc, PROC_VERSION_EXCHANGE, NULL);
@ -1146,7 +1150,7 @@ void test_int_create_proc(void)
for (int i = 0U; i < CONFIG_BT_CTLR_LLCP_PROC_CTX_BUF_NUM; i++) { for (int i = 0U; i < CONFIG_BT_CTLR_LLCP_PROC_CTX_BUF_NUM; i++) {
zassert_not_null(ctx, NULL); zassert_not_null(ctx, NULL);
ctx = create_procedure(PROC_VERSION_EXCHANGE); ctx = create_procedure(PROC_VERSION_EXCHANGE, &mem_ctx);
} }
zassert_is_null(ctx, NULL); zassert_is_null(ctx, NULL);

View file

@ -4,6 +4,12 @@
* SPDX-License-Identifier: Apache-2.0 * SPDX-License-Identifier: Apache-2.0
*/ */
/* LLCP Memory Pool Descriptor */
struct llcp_mem_pool {
void *free;
uint8_t *pool;
};
/* LLCP Procedure */ /* LLCP Procedure */
enum llcp_proc { enum llcp_proc {
PROC_UNKNOWN, PROC_UNKNOWN,
@ -114,6 +120,9 @@ struct proc_ctx {
/* Must be the first for sys_slist to work */ /* Must be the first for sys_slist to work */
sys_snode_t node; sys_snode_t node;
/* llcp_mem_pool owner of this context */
struct llcp_mem_pool *owner;
/* PROC_ */ /* PROC_ */
enum llcp_proc proc; enum llcp_proc proc;
@ -335,6 +344,7 @@ struct proc_ctx *llcp_create_remote_procedure(enum llcp_proc proc);
bool llcp_tx_alloc_peek(struct ll_conn *conn, struct proc_ctx *ctx); bool llcp_tx_alloc_peek(struct ll_conn *conn, struct proc_ctx *ctx);
void llcp_tx_alloc_unpeek(struct proc_ctx *ctx); void llcp_tx_alloc_unpeek(struct proc_ctx *ctx);
struct node_tx *llcp_tx_alloc(struct ll_conn *conn, struct proc_ctx *ctx); struct node_tx *llcp_tx_alloc(struct ll_conn *conn, struct proc_ctx *ctx);
void llcp_proc_ctx_release(struct proc_ctx *ctx);
/* /*
* ULL -> LLL Interface * ULL -> LLL Interface
@ -571,7 +581,6 @@ void llcp_pdu_encode_conn_param_rsp(struct proc_ctx *ctx, struct pdu_data *pdu);
void llcp_pdu_decode_conn_param_rsp(struct proc_ctx *ctx, struct pdu_data *pdu); void llcp_pdu_decode_conn_param_rsp(struct proc_ctx *ctx, struct pdu_data *pdu);
void llcp_pdu_encode_conn_update_ind(struct proc_ctx *ctx, struct pdu_data *pdu); void llcp_pdu_encode_conn_update_ind(struct proc_ctx *ctx, struct pdu_data *pdu);
void llcp_pdu_decode_conn_update_ind(struct proc_ctx *ctx, struct pdu_data *pdu); void llcp_pdu_decode_conn_update_ind(struct proc_ctx *ctx, struct pdu_data *pdu);
void llcp_proc_ctx_release(struct proc_ctx *ctx);
/* /*
* Remote Channel Map Update Procedure Helper * Remote Channel Map Update Procedure Helper