diff --git a/subsys/bluetooth/controller/ll_sw/ull_llcp.c b/subsys/bluetooth/controller/ll_sw/ull_llcp.c index e7dca267f8a..a6928b603da 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_llcp.c +++ b/subsys/bluetooth/controller/ll_sw/ull_llcp.c @@ -43,12 +43,6 @@ #include #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 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) @@ -62,26 +56,36 @@ static uint8_t common_tx_buffer_alloc; /* TODO: Determine 'correct' number of tx nodes */ 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 */ 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 */ -static struct proc_ctx *proc_ctx_acquire(void) +static struct proc_ctx *proc_ctx_acquire(struct llcp_mem_pool *owner) { 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; } 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) @@ -249,11 +253,11 @@ void llcp_tx_flush(struct ll_conn *conn) * 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; - ctx = proc_ctx_acquire(); + ctx = proc_ctx_acquire(ctx_pool); if (!ctx) { return NULL; } @@ -278,7 +282,7 @@ struct proc_ctx *llcp_create_local_procedure(enum llcp_proc proc) { struct proc_ctx *ctx; - ctx = create_procedure(proc); + ctx = create_procedure(proc, &mem_ctx); if (!ctx) { return NULL; } @@ -346,7 +350,7 @@ struct proc_ctx *llcp_create_remote_procedure(enum llcp_proc proc) { struct proc_ctx *ctx; - ctx = create_procedure(proc); + ctx = create_procedure(proc, &mem_ctx); if (!ctx) { 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); 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 */ zassert_not_null(ctx1, NULL); @@ -1051,7 +1055,7 @@ void test_int_mem_proc_ctx(void) nr_of_free_ctx = ctx_buffers_free(); zassert_equal(nr_of_free_ctx, 0, NULL); - ctx2 = proc_ctx_acquire(); + ctx2 = proc_ctx_acquire(&mem_ctx); /* The last acquire should fail */ zassert_is_null(ctx2, NULL); @@ -1060,7 +1064,7 @@ void test_int_mem_proc_ctx(void) nr_of_free_ctx = ctx_buffers_free(); 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 */ zassert_not_null(ctx1, NULL); @@ -1137,7 +1141,7 @@ void test_int_create_proc(void) ull_cp_init(); - ctx = create_procedure(PROC_VERSION_EXCHANGE); + ctx = create_procedure(PROC_VERSION_EXCHANGE, &mem_ctx); zassert_not_null(ctx, 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++) { zassert_not_null(ctx, NULL); - ctx = create_procedure(PROC_VERSION_EXCHANGE); + ctx = create_procedure(PROC_VERSION_EXCHANGE, &mem_ctx); } zassert_is_null(ctx, NULL); diff --git a/subsys/bluetooth/controller/ll_sw/ull_llcp_internal.h b/subsys/bluetooth/controller/ll_sw/ull_llcp_internal.h index 7055d612c82..e7cafdc39e2 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_llcp_internal.h +++ b/subsys/bluetooth/controller/ll_sw/ull_llcp_internal.h @@ -4,6 +4,12 @@ * SPDX-License-Identifier: Apache-2.0 */ +/* LLCP Memory Pool Descriptor */ +struct llcp_mem_pool { + void *free; + uint8_t *pool; +}; + /* LLCP Procedure */ enum llcp_proc { PROC_UNKNOWN, @@ -114,6 +120,9 @@ struct proc_ctx { /* Must be the first for sys_slist to work */ sys_snode_t node; + /* llcp_mem_pool owner of this context */ + struct llcp_mem_pool *owner; + /* 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); void llcp_tx_alloc_unpeek(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 @@ -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_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_proc_ctx_release(struct proc_ctx *ctx); /* * Remote Channel Map Update Procedure Helper