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;
|
} mem_link_done;
|
||||||
|
|
||||||
#if defined(CONFIG_BT_CTLR_PHY) && defined(CONFIG_BT_CTLR_DATA_LENGTH)
|
#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
|
#else
|
||||||
#define LL_PDU_RX_CNT 1
|
#define LL_PDU_RX_CNT 2
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define PDU_RX_CNT (CONFIG_BT_CTLR_RX_BUFFERS + 3)
|
#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 */
|
/* Acquire Rx node */
|
||||||
rx = conn->llcp_rx;
|
rx = conn->llcp_rx;
|
||||||
conn->llcp_rx = NULL;
|
|
||||||
|
|
||||||
LL_ASSERT(rx && rx->hdr.link);
|
LL_ASSERT(rx && rx->hdr.link);
|
||||||
|
conn->llcp_rx = rx->hdr.link->mem;
|
||||||
|
|
||||||
/* Prepare the rx packet structure */
|
/* Prepare the rx packet structure */
|
||||||
if ((conn->llcp.conn_upd.interval != lll->interval) ||
|
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 */
|
/* Prepare the rx packet structure */
|
||||||
rx = conn->llcp_rx;
|
rx = conn->llcp_rx;
|
||||||
conn->llcp_rx = NULL;
|
|
||||||
|
|
||||||
LL_ASSERT(rx && rx->hdr.link);
|
LL_ASSERT(rx && rx->hdr.link);
|
||||||
|
conn->llcp_rx = rx->hdr.link->mem;
|
||||||
|
|
||||||
rx->hdr.handle = conn->lll.handle;
|
rx->hdr.handle = conn->lll.handle;
|
||||||
rx->hdr.type = NODE_RX_TYPE_DC_PDU;
|
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 */
|
/* enqueue rx node towards Thread */
|
||||||
ll_rx_put(rx->hdr.link, rx);
|
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();
|
ll_rx_sched();
|
||||||
|
|
||||||
return;
|
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.state = LLCP_CUI_STATE_INPROG;
|
||||||
conn->llcp.conn_upd.is_internal = 0U;
|
conn->llcp.conn_upd.is_internal = 0U;
|
||||||
|
|
||||||
LL_ASSERT(!conn->llcp_rx);
|
link->mem = conn->llcp_rx;
|
||||||
|
|
||||||
(*rx)->hdr.link = link;
|
(*rx)->hdr.link = link;
|
||||||
conn->llcp_rx = *rx;
|
conn->llcp_rx = *rx;
|
||||||
*rx = NULL;
|
*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 =
|
conn->llcp_length.state =
|
||||||
LLCP_LENGTH_STATE_RESIZE;
|
LLCP_LENGTH_STATE_RESIZE;
|
||||||
|
|
||||||
LL_ASSERT(!conn->llcp_rx);
|
link->mem = conn->llcp_rx;
|
||||||
|
|
||||||
(*rx)->hdr.link = link;
|
(*rx)->hdr.link = link;
|
||||||
conn->llcp_rx = *rx;
|
conn->llcp_rx = *rx;
|
||||||
*rx = NULL;
|
*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.instant = instant;
|
||||||
conn->llcp.phy_upd_ind.initiate = 0U;
|
conn->llcp.phy_upd_ind.initiate = 0U;
|
||||||
|
|
||||||
LL_ASSERT(!conn->llcp_rx);
|
|
||||||
|
|
||||||
link->mem = conn->llcp_rx;
|
link->mem = conn->llcp_rx;
|
||||||
(*rx)->hdr.link = link;
|
(*rx)->hdr.link = link;
|
||||||
conn->llcp_rx = *rx;
|
conn->llcp_rx = *rx;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue