Skip to content

Commit bc71d39

Browse files
cvinayakcarlescufi
authored andcommitted
Bluetooth: controller: Fix free Rx PDU queue starvation
Fix for scenarios where in active PHY Update Procedure or Connection Update Procedure could cause temporary depletion of the free Rx PDUs in the queue between LL/HCI thread context to LLL context. Symptoms being on-air NACKing during the above said procedures, causing supervision timeouts due to procedures not completing at instants. Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
1 parent 2a99857 commit bc71d39

File tree

1 file changed

+21
-14
lines changed
  • subsys/bluetooth/controller/ll_sw

1 file changed

+21
-14
lines changed

subsys/bluetooth/controller/ll_sw/ull.c

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1723,57 +1723,64 @@ static inline void rx_alloc(uint8_t max)
17231723
{
17241724
uint8_t idx;
17251725

1726-
#if defined(CONFIG_BT_CONN)
1727-
while (mem_link_rx.quota_pdu &&
1728-
MFIFO_ENQUEUE_IDX_GET(ll_pdu_rx_free, &idx)) {
1726+
if (max > mem_link_rx.quota_pdu) {
1727+
max = mem_link_rx.quota_pdu;
1728+
}
1729+
1730+
while ((max--) && MFIFO_ENQUEUE_IDX_GET(pdu_rx_free, &idx)) {
17291731
memq_link_t *link;
17301732
struct node_rx_hdr *rx;
17311733

17321734
link = mem_acquire(&mem_link_rx.free);
17331735
if (!link) {
1734-
break;
1736+
return;
17351737
}
17361738

17371739
rx = mem_acquire(&mem_pdu_rx.free);
17381740
if (!rx) {
17391741
mem_release(link, &mem_link_rx.free);
1740-
break;
1742+
return;
17411743
}
17421744

1743-
link->mem = NULL;
17441745
rx->link = link;
17451746

1746-
MFIFO_BY_IDX_ENQUEUE(ll_pdu_rx_free, idx, rx);
1747+
MFIFO_BY_IDX_ENQUEUE(pdu_rx_free, idx, rx);
17471748

17481749
ll_rx_link_inc_quota(-1);
17491750
}
1750-
#endif /* CONFIG_BT_CONN */
17511751

1752-
if (max > mem_link_rx.quota_pdu) {
1753-
max = mem_link_rx.quota_pdu;
1752+
#if defined(CONFIG_BT_CONN)
1753+
if (!max) {
1754+
return;
17541755
}
17551756

1756-
while ((max--) && MFIFO_ENQUEUE_IDX_GET(pdu_rx_free, &idx)) {
1757+
/* Replenish the ULL to LL/HCI free Rx PDU queue after LLL to ULL free
1758+
* Rx PDU queue has been filled.
1759+
*/
1760+
while (mem_link_rx.quota_pdu &&
1761+
MFIFO_ENQUEUE_IDX_GET(ll_pdu_rx_free, &idx)) {
17571762
memq_link_t *link;
17581763
struct node_rx_hdr *rx;
17591764

17601765
link = mem_acquire(&mem_link_rx.free);
17611766
if (!link) {
1762-
break;
1767+
return;
17631768
}
17641769

17651770
rx = mem_acquire(&mem_pdu_rx.free);
17661771
if (!rx) {
17671772
mem_release(link, &mem_link_rx.free);
1768-
break;
1773+
return;
17691774
}
17701775

1776+
link->mem = NULL;
17711777
rx->link = link;
17721778

1773-
MFIFO_BY_IDX_ENQUEUE(pdu_rx_free, idx, rx);
1779+
MFIFO_BY_IDX_ENQUEUE(ll_pdu_rx_free, idx, rx);
17741780

17751781
ll_rx_link_inc_quota(-1);
17761782
}
1783+
#endif /* CONFIG_BT_CONN */
17771784
}
17781785

17791786
static void rx_demux(void *param)

0 commit comments

Comments
 (0)