Skip to content

Commit fc2fcd1

Browse files
Johan Hedbergjhedberg
authored andcommitted
Bluetooth: Add dedicated pool for HCI_Num_Completed_Packets HCI event
This event is a priority one, so it's not safe to have it use the RX buffer pool which may be depleted due to non-priority events (e.g. advertising events). Since the event is consumed synchronously it's safe to have a single-buffer pool for it. Also introduce a new bt_buf_get_evt() API for HCI drivers to simplify the driver-side code, this effectively also deprecates bt_buf_get_cmd_complete() which now has no in-tree HCI driver users anymore. Fixes #16864 Signed-off-by: Johan Hedberg <[email protected]>
1 parent 766ad9f commit fc2fcd1

File tree

12 files changed

+75
-41
lines changed

12 files changed

+75
-41
lines changed

drivers/bluetooth/hci/h4.c

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -161,16 +161,11 @@ static struct net_buf *get_rx(int timeout)
161161
{
162162
BT_DBG("type 0x%02x, evt 0x%02x", rx.type, rx.evt.evt);
163163

164-
if (rx.type == H4_EVT && (rx.evt.evt == BT_HCI_EVT_CMD_COMPLETE ||
165-
rx.evt.evt == BT_HCI_EVT_CMD_STATUS)) {
166-
return bt_buf_get_cmd_complete(timeout);
164+
if (rx.type == H4_EVT) {
165+
return bt_buf_get_evt(rx.evt.evt, timeout);
167166
}
168167

169-
if (rx.type == H4_ACL) {
170-
return bt_buf_get_rx(BT_BUF_ACL_IN, timeout);
171-
} else {
172-
return bt_buf_get_rx(BT_BUF_EVT, timeout);
173-
}
168+
return bt_buf_get_rx(BT_BUF_ACL_IN, timeout);
174169
}
175170

176171
static void rx_thread(void *p1, void *p2, void *p3)

drivers/bluetooth/hci/h5.c

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -408,16 +408,7 @@ static inline struct net_buf *get_evt_buf(u8_t evt)
408408
{
409409
struct net_buf *buf;
410410

411-
switch (evt) {
412-
case BT_HCI_EVT_CMD_COMPLETE:
413-
case BT_HCI_EVT_CMD_STATUS:
414-
buf = bt_buf_get_cmd_complete(K_NO_WAIT);
415-
break;
416-
default:
417-
buf = bt_buf_get_rx(BT_BUF_EVT, K_NO_WAIT);
418-
break;
419-
}
420-
411+
buf = bt_buf_get_evt(evt, K_NO_WAIT);
421412
if (buf) {
422413
net_buf_add_u8(h5.rx_buf, evt);
423414
}

drivers/bluetooth/hci/ipm_stm32wb.c

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -114,12 +114,8 @@ void TM_EvtReceivedCb(TL_EvtPacket_t *hcievt)
114114
BT_ERR("Unknown evtcode type 0x%02x",
115115
hcievt->evtserial.evt.evtcode);
116116
goto out;
117-
case BT_HCI_EVT_CMD_COMPLETE:
118-
case BT_HCI_EVT_CMD_STATUS:
119-
buf = bt_buf_get_cmd_complete(K_FOREVER);
120-
break;
121117
default:
122-
buf = bt_buf_get_rx(BT_BUF_EVT, K_FOREVER);
118+
buf = bt_buf_get_evt(evtserial.evt.evtcode, K_FOREVER);
123119
break;
124120
}
125121
net_buf_add_mem(buf, &hcievt->evtserial.evt,

drivers/bluetooth/hci/spi.c

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -353,12 +353,9 @@ static void bt_spi_rx_thread(void)
353353
/* Vendor events are currently unsupported */
354354
bt_spi_handle_vendor_evt(rxmsg);
355355
continue;
356-
case BT_HCI_EVT_CMD_COMPLETE:
357-
case BT_HCI_EVT_CMD_STATUS:
358-
buf = bt_buf_get_cmd_complete(K_FOREVER);
359-
break;
360356
default:
361-
buf = bt_buf_get_rx(BT_BUF_EVT, K_FOREVER);
357+
buf = bt_buf_get_evt(rxmsg[EVT_HEADER_EVENT],
358+
K_FOREVER);
362359
break;
363360
}
364361

drivers/bluetooth/hci/userchan.c

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -57,16 +57,11 @@ static int bt_dev_index = -1;
5757

5858
static struct net_buf *get_rx(const u8_t *buf)
5959
{
60-
if (buf[0] == H4_EVT && (buf[1] == BT_HCI_EVT_CMD_COMPLETE ||
61-
buf[1] == BT_HCI_EVT_CMD_STATUS)) {
62-
return bt_buf_get_cmd_complete(K_FOREVER);
60+
if (buf[0] == H4_EVT) {
61+
return bt_buf_get_evt(buf[1], K_FOREVER);
6362
}
6463

65-
if (buf[0] == H4_ACL) {
66-
return bt_buf_get_rx(BT_BUF_ACL_IN, K_FOREVER);
67-
} else {
68-
return bt_buf_get_rx(BT_BUF_EVT, K_FOREVER);
69-
}
64+
return bt_buf_get_rx(BT_BUF_ACL_IN, K_FOREVER);
7065
}
7166

7267
static bool uc_ready(void)

include/bluetooth/buf.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,18 @@ struct net_buf *bt_buf_get_rx(enum bt_buf_type type, s32_t timeout);
6464
*/
6565
struct net_buf *bt_buf_get_cmd_complete(s32_t timeout);
6666

67+
/** Allocate a buffer for an HCI Event
68+
*
69+
* This will set the buffer type so bt_buf_set_type() does not need to
70+
* be explicitly called before bt_recv_prio() or bt_recv().
71+
*
72+
* @param evt HCI event code
73+
* @param timeout Timeout in milliseconds, or one of the special values
74+
* K_NO_WAIT and K_FOREVER.
75+
* @return A new buffer.
76+
*/
77+
struct net_buf *bt_buf_get_evt(u8_t evt, s32_t timeout);
78+
6779
/** Set the buffer type
6880
*
6981
* @param buf Bluetooth buffer

subsys/bluetooth/controller/hci/hci.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ void *hci_cmd_complete(struct net_buf **buf, u8_t plen)
120120
{
121121
struct bt_hci_evt_cmd_complete *cc;
122122

123-
*buf = bt_buf_get_cmd_complete(K_FOREVER);
123+
*buf = bt_buf_get_evt(BT_HCI_EVT_CMD_COMPLETE, K_FOREVER);
124124

125125
hci_evt_create(*buf, BT_HCI_EVT_CMD_COMPLETE, sizeof(*cc) + plen);
126126

@@ -137,7 +137,7 @@ static struct net_buf *cmd_status(u8_t status)
137137
struct bt_hci_evt_cmd_status *cs;
138138
struct net_buf *buf;
139139

140-
buf = bt_buf_get_cmd_complete(K_FOREVER);
140+
buf = bt_buf_get_evt(BT_HCI_EVT_CMD_STATUS, K_FOREVER);
141141
hci_evt_create(buf, BT_HCI_EVT_CMD_STATUS, sizeof(*cs));
142142

143143
cs = net_buf_add(buf, sizeof(*cs));

subsys/bluetooth/controller/hci/hci_driver.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,8 @@ static void prio_recv_thread(void *p1, void *p2, void *p3)
9090
#if defined(CONFIG_BT_CONN)
9191
struct net_buf *buf;
9292

93-
buf = bt_buf_get_rx(BT_BUF_EVT, K_FOREVER);
93+
buf = bt_buf_get_evt(BT_HCI_EVT_NUM_COMPLETED_PACKETS,
94+
K_FOREVER);
9495
hci_num_cmplt_encode(buf, handle, num_cmplt);
9596
BT_DBG("Num Complete: 0x%04x:%u", handle, num_cmplt);
9697
bt_recv_prio(buf);

subsys/bluetooth/host/hci_core.c

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,16 @@ NET_BUF_POOL_DEFINE(hci_cmd_pool, CONFIG_BT_HCI_CMD_COUNT,
138138
NET_BUF_POOL_DEFINE(hci_rx_pool, CONFIG_BT_RX_BUF_COUNT,
139139
BT_BUF_RX_SIZE, BT_BUF_USER_DATA_MIN, NULL);
140140

141+
#if defined(CONFIG_BT_CONN)
142+
/* Dedicated pool for HCI_Number_of_Completed_Packets. This event is always
143+
* consumed synchronously by bt_recv_prio() so a single buffer is enough.
144+
* Having a dedicated pool for it ensures that exhaustion of the RX pool
145+
* cannot block the delivery of this priority event.
146+
*/
147+
NET_BUF_POOL_DEFINE(num_complete_pool, 1, BT_BUF_RX_SIZE,
148+
BT_BUF_USER_DATA_MIN, NULL);
149+
#endif /* CONFIG_BT_CONN */
150+
141151
struct event_handler {
142152
u8_t event;
143153
u8_t min_len;
@@ -5662,6 +5672,31 @@ struct net_buf *bt_buf_get_cmd_complete(s32_t timeout)
56625672
return bt_buf_get_rx(BT_BUF_EVT, timeout);
56635673
}
56645674

5675+
struct net_buf *bt_buf_get_evt(u8_t evt, s32_t timeout)
5676+
{
5677+
switch (evt) {
5678+
#if defined(CONFIG_BT_CONN)
5679+
case BT_HCI_EVT_NUM_COMPLETED_PACKETS:
5680+
{
5681+
struct net_buf *buf;
5682+
5683+
buf = net_buf_alloc(&num_complete_pool, timeout);
5684+
if (buf) {
5685+
net_buf_reserve(buf, CONFIG_BT_HCI_RESERVE);
5686+
bt_buf_set_type(buf, BT_BUF_EVT);
5687+
}
5688+
5689+
return buf;
5690+
}
5691+
#endif /* CONFIG_BT_CONN */
5692+
case BT_HCI_EVT_CMD_COMPLETE:
5693+
case BT_HCI_EVT_CMD_STATUS:
5694+
return bt_buf_get_cmd_complete(timeout);
5695+
default:
5696+
return bt_buf_get_rx(BT_BUF_EVT, timeout);
5697+
}
5698+
}
5699+
56655700
#if defined(CONFIG_BT_BREDR)
56665701
static int br_start_inquiry(const struct bt_br_discovery_param *param)
56675702
{

subsys/bluetooth/host/hci_ecc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ static void send_cmd_status(u16_t opcode, u8_t status)
8484

8585
BT_DBG("opcode %x status %x", opcode, status);
8686

87-
buf = bt_buf_get_cmd_complete(K_FOREVER);
87+
buf = bt_buf_get_evt(BT_HCI_EVT_CMD_STATUS, K_FOREVER);
8888
bt_buf_set_type(buf, BT_BUF_EVT);
8989

9090
hdr = net_buf_add(buf, sizeof(*hdr));

0 commit comments

Comments
 (0)