Bluetooth: controller: split: Fix ctrl proc rx node starvation
Rx nodes are reserved during control procedures for generation of HCI event on completion. Fix the allocation and reservation in the form of a linked list per connection context. Worst case, this list will hold one rx node for overlapping non-instant control procedure (Data Length Update) plus two rx node for control procedure with instant (PHY update with Data Length Update support). Fixes #19198. Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
This commit is contained in:
parent
3b67130334
commit
af696bdd4c
2 changed files with 20 additions and 12 deletions
|
@ -147,9 +147,9 @@ static struct {
|
|||
} mem_link_done;
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_PHY) && defined(CONFIG_BT_CTLR_DATA_LENGTH)
|
||||
#define LL_PDU_RX_CNT 2
|
||||
#define LL_PDU_RX_CNT 3
|
||||
#else
|
||||
#define LL_PDU_RX_CNT 1
|
||||
#define LL_PDU_RX_CNT 2
|
||||
#endif
|
||||
|
||||
#define PDU_RX_CNT (CONFIG_BT_CTLR_RX_BUFFERS + 3)
|
||||
|
|
|
@ -1968,9 +1968,8 @@ static inline int event_conn_upd_prep(struct ll_conn *conn, u16_t lazy,
|
|||
|
||||
/* Acquire Rx node */
|
||||
rx = conn->llcp_rx;
|
||||
conn->llcp_rx = NULL;
|
||||
|
||||
LL_ASSERT(rx && rx->hdr.link);
|
||||
conn->llcp_rx = rx->hdr.link->mem;
|
||||
|
||||
/* Prepare the rx packet structure */
|
||||
if ((conn->llcp.conn_upd.interval != lll->interval) ||
|
||||
|
@ -2924,9 +2923,8 @@ static inline void event_len_prep(struct ll_conn *conn)
|
|||
|
||||
/* Prepare the rx packet structure */
|
||||
rx = conn->llcp_rx;
|
||||
conn->llcp_rx = NULL;
|
||||
|
||||
LL_ASSERT(rx && rx->hdr.link);
|
||||
conn->llcp_rx = rx->hdr.link->mem;
|
||||
|
||||
rx->hdr.handle = conn->lll.handle;
|
||||
rx->hdr.type = NODE_RX_TYPE_DC_PDU;
|
||||
|
@ -3241,6 +3239,20 @@ static inline void event_phy_upd_ind_prep(struct ll_conn *conn,
|
|||
|
||||
/* enqueue rx node towards Thread */
|
||||
ll_rx_put(rx->hdr.link, rx);
|
||||
|
||||
if (IS_ENABLED(CONFIG_BT_CTLR_DATA_LENGTH)) {
|
||||
/* get the DLE rx node reserved for ULL->LL */
|
||||
rx = conn->llcp_rx;
|
||||
LL_ASSERT(rx && rx->hdr.link);
|
||||
conn->llcp_rx = rx->hdr.link->mem;
|
||||
|
||||
/* Mark for buffer for release */
|
||||
rx->hdr.type = NODE_RX_TYPE_DC_PDU_RELEASE;
|
||||
|
||||
/* enqueue rx node towards Thread */
|
||||
ll_rx_put(rx->hdr.link, rx);
|
||||
}
|
||||
|
||||
ll_rx_sched();
|
||||
|
||||
return;
|
||||
|
@ -3348,8 +3360,7 @@ static u8_t conn_upd_recv(struct ll_conn *conn, memq_link_t *link,
|
|||
conn->llcp.conn_upd.state = LLCP_CUI_STATE_INPROG;
|
||||
conn->llcp.conn_upd.is_internal = 0U;
|
||||
|
||||
LL_ASSERT(!conn->llcp_rx);
|
||||
|
||||
link->mem = conn->llcp_rx;
|
||||
(*rx)->hdr.link = link;
|
||||
conn->llcp_rx = *rx;
|
||||
*rx = NULL;
|
||||
|
@ -4188,8 +4199,7 @@ static inline int length_req_rsp_recv(struct ll_conn *conn, memq_link_t *link,
|
|||
conn->llcp_length.state =
|
||||
LLCP_LENGTH_STATE_RESIZE;
|
||||
|
||||
LL_ASSERT(!conn->llcp_rx);
|
||||
|
||||
link->mem = conn->llcp_rx;
|
||||
(*rx)->hdr.link = link;
|
||||
conn->llcp_rx = *rx;
|
||||
*rx = NULL;
|
||||
|
@ -4426,8 +4436,6 @@ static inline u8_t phy_upd_ind_recv(struct ll_conn *conn, memq_link_t *link,
|
|||
conn->llcp.phy_upd_ind.instant = instant;
|
||||
conn->llcp.phy_upd_ind.initiate = 0U;
|
||||
|
||||
LL_ASSERT(!conn->llcp_rx);
|
||||
|
||||
link->mem = conn->llcp_rx;
|
||||
(*rx)->hdr.link = link;
|
||||
conn->llcp_rx = *rx;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue