Bluetooth: host: sched-lock bt_recv()

`bt_recv` is invoked from the BT long work queue, which is preemptible.
The host uses cooperative scheduling to ensure thread safety.

Signed-off-by: Aleksander Wasaznik <aleksander.wasaznik@nordicsemi.no>
This commit is contained in:
Aleksander Wasaznik 2024-04-03 11:11:26 +02:00 committed by Anas Nashif
commit a64d20f6f0
3 changed files with 12 additions and 15 deletions

View file

@ -237,19 +237,7 @@ static void bt_ipc_rx(const uint8_t *data, size_t len)
if (buf) { if (buf) {
LOG_DBG("Calling bt_recv(%p)", buf); LOG_DBG("Calling bt_recv(%p)", buf);
/* The IPC service does not guarantee that the handler thread
* is cooperative. In particular, the OpenAMP implementation is
* preemtible by default. OTOH, the HCI driver interface requires
* that the bt_recv() function is called from a cooperative
* thread.
*
* Calling `k_sched lock()` has the effect of making the current
* thread cooperative.
*/
k_sched_lock();
bt_recv(buf); bt_recv(buf);
k_sched_unlock();
LOG_HEXDUMP_DBG(buf->data, buf->len, "RX buf payload:"); LOG_HEXDUMP_DBG(buf->data, buf->len, "RX buf payload:");
} }

View file

@ -46,8 +46,6 @@ enum {
* host with data from the controller. The buffer needs to have its type * host with data from the controller. The buffer needs to have its type
* set with the help of bt_buf_set_type() before calling this API. * set with the help of bt_buf_set_type() before calling this API.
* *
* @note This function must only be called from a cooperative thread.
*
* @param buf Network buffer containing data from the controller. * @param buf Network buffer containing data from the controller.
* *
* @return 0 on success or negative error number on failure. * @return 0 on success or negative error number on failure.

View file

@ -3900,7 +3900,7 @@ static void rx_queue_put(struct net_buf *buf)
} }
} }
int bt_recv(struct net_buf *buf) static int bt_recv_unsafe(struct net_buf *buf)
{ {
bt_monitor_send(bt_monitor_opcode(buf), buf->data, buf->len); bt_monitor_send(bt_monitor_opcode(buf), buf->data, buf->len);
@ -3939,6 +3939,17 @@ int bt_recv(struct net_buf *buf)
} }
} }
int bt_recv(struct net_buf *buf)
{
int err;
k_sched_lock();
err = bt_recv_unsafe(buf);
k_sched_unlock();
return err;
}
int bt_hci_driver_register(const struct bt_hci_driver *drv) int bt_hci_driver_register(const struct bt_hci_driver *drv)
{ {
if (bt_dev.drv) { if (bt_dev.drv) {