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:
Vinayak Kariappa Chettimada 2019-10-10 17:00:35 +05:30 committed by Carles Cufí
commit af696bdd4c
2 changed files with 20 additions and 12 deletions

View file

@ -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)

View file

@ -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;