Bluetooth: controller: split: Fix buffer leak on disconnect
Fix pending Tx control buffer leak on supervision timeout. Queued tx buffers in LLL consists of both data and control PDUs but only data buffers got correctly released. Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
This commit is contained in:
parent
ac8e810d94
commit
3e56c2cf16
3 changed files with 32 additions and 34 deletions
|
@ -1350,37 +1350,26 @@ static inline void rx_demux_conn_tx_ack(u8_t ack_last, u16_t handle,
|
|||
#if !defined(CONFIG_BT_CTLR_LOW_LAT_ULL)
|
||||
do {
|
||||
#endif /* CONFIG_BT_CTLR_LOW_LAT_ULL */
|
||||
struct ll_conn *conn;
|
||||
|
||||
/* Dequeue node */
|
||||
ull_conn_ack_dequeue();
|
||||
|
||||
if (handle != 0xFFFF) {
|
||||
struct ll_conn *conn;
|
||||
/* Process Tx ack */
|
||||
conn = ull_conn_tx_ack(handle, link, node_tx);
|
||||
|
||||
/* Get the conn instance */
|
||||
conn = ll_conn_get(handle);
|
||||
/* Release link mem */
|
||||
ull_conn_link_tx_release(link);
|
||||
|
||||
/* Process Tx ack */
|
||||
ull_conn_tx_ack(conn, link, node_tx);
|
||||
/* De-mux 1 tx node from FIFO */
|
||||
ull_conn_tx_demux(1);
|
||||
|
||||
/* Release link mem */
|
||||
ull_conn_link_tx_release(link);
|
||||
|
||||
/* De-mux 1 tx node from FIFO */
|
||||
ull_conn_tx_demux(1);
|
||||
|
||||
/* Enqueue towards LLL */
|
||||
/* Enqueue towards LLL */
|
||||
if (conn) {
|
||||
ull_conn_tx_lll_enqueue(conn, 1);
|
||||
} else {
|
||||
/* Pass through Tx ack */
|
||||
ll_tx_ack_put(0xFFFF, node_tx);
|
||||
|
||||
/* Release link mem */
|
||||
ull_conn_link_tx_release(link);
|
||||
|
||||
/* De-mux 1 tx node from FIFO */
|
||||
ull_conn_tx_demux(1);
|
||||
}
|
||||
|
||||
/* check for more rx ack */
|
||||
link = ull_conn_ack_by_last_peek(ack_last, &handle, &node_tx);
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_LOW_LAT_ULL)
|
||||
|
|
|
@ -1308,7 +1308,6 @@ void ull_conn_lll_tx_flush(void *param)
|
|||
link = memq_dequeue(lll->memq_tx.tail, &lll->memq_tx.head,
|
||||
(void **)&tx);
|
||||
while (link) {
|
||||
struct pdu_data *p;
|
||||
struct lll_tx *lll_tx;
|
||||
u8_t idx;
|
||||
|
||||
|
@ -1319,8 +1318,6 @@ void ull_conn_lll_tx_flush(void *param)
|
|||
lll_tx->node = tx;
|
||||
link->next = tx->next;
|
||||
tx->link = link;
|
||||
p = (void *)tx->pdu;
|
||||
p->ll_id = PDU_DATA_LLID_RESV;
|
||||
|
||||
MFIFO_ENQUEUE(conn_ack, idx);
|
||||
|
||||
|
@ -1329,27 +1326,39 @@ void ull_conn_lll_tx_flush(void *param)
|
|||
}
|
||||
}
|
||||
|
||||
void ull_conn_tx_ack(struct ll_conn *conn, memq_link_t *link,
|
||||
struct node_tx *tx)
|
||||
struct ll_conn *ull_conn_tx_ack(u16_t handle, memq_link_t *link,
|
||||
struct node_tx *tx)
|
||||
{
|
||||
struct ll_conn *conn = NULL;
|
||||
struct pdu_data *pdu_tx;
|
||||
|
||||
pdu_tx = (void *)tx->pdu;
|
||||
LL_ASSERT(pdu_tx->len);
|
||||
|
||||
if (pdu_tx->ll_id == PDU_DATA_LLID_CTRL) {
|
||||
ctrl_tx_ack(conn, &tx, pdu_tx);
|
||||
if (handle != 0xFFFF) {
|
||||
conn = ll_conn_get(handle);
|
||||
|
||||
ctrl_tx_ack(conn, &tx, pdu_tx);
|
||||
}
|
||||
|
||||
/* release mem if points to itself */
|
||||
if (link->next == (void *)tx) {
|
||||
mem_release(tx, &mem_conn_tx_ctrl.free);
|
||||
return;
|
||||
|
||||
return conn;
|
||||
} else if (!tx) {
|
||||
return;
|
||||
return conn;
|
||||
}
|
||||
} else if (handle != 0xFFFF) {
|
||||
conn = ll_conn_get(handle);
|
||||
} else {
|
||||
pdu_tx->ll_id = PDU_DATA_LLID_RESV;
|
||||
}
|
||||
|
||||
ll_tx_ack_put(conn->lll.handle, tx);
|
||||
ll_tx_ack_put(handle, tx);
|
||||
|
||||
return conn;
|
||||
}
|
||||
|
||||
u8_t ull_conn_llcp_req(void *conn)
|
||||
|
@ -1564,7 +1573,7 @@ static void ctrl_tx_enqueue(struct ll_conn *conn, struct node_tx *tx)
|
|||
}
|
||||
|
||||
/* Update last pointer if ctrl added at end of tx list */
|
||||
if (tx->next == 0) {
|
||||
if (!tx->next) {
|
||||
conn->tx_data_last = tx;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,6 +45,6 @@ memq_link_t *ull_conn_ack_by_last_peek(u8_t last, u16_t *handle,
|
|||
struct node_tx **tx);
|
||||
void *ull_conn_ack_dequeue(void);
|
||||
void ull_conn_lll_tx_flush(void *param);
|
||||
void ull_conn_tx_ack(struct ll_conn *conn, memq_link_t *link,
|
||||
struct node_tx *tx);
|
||||
struct ll_conn *ull_conn_tx_ack(u16_t handle, memq_link_t *link,
|
||||
struct node_tx *tx);
|
||||
u8_t ull_conn_llcp_req(void *conn);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue