Skip to content

Commit

Permalink
Bluetooth: host: sched-lock bt_recv()
Browse files Browse the repository at this point in the history
`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 <[email protected]>
  • Loading branch information
alwa-nordic authored and jhedberg committed Jul 3, 2024
1 parent b27d3a6 commit ca4e65e
Show file tree
Hide file tree
Showing 3 changed files with 12 additions and 15 deletions.
12 changes: 0 additions & 12 deletions drivers/bluetooth/hci/ipc.c
Original file line number Diff line number Diff line change
Expand Up @@ -229,19 +229,7 @@ static void bt_ipc_rx(const uint8_t *data, size_t len)

if (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);
k_sched_unlock();

LOG_HEXDUMP_DBG(buf->data, buf->len, "RX buf payload:");
}
Expand Down
2 changes: 0 additions & 2 deletions include/zephyr/drivers/bluetooth/hci_driver.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,6 @@ static inline uint8_t bt_hci_evt_get_flags(uint8_t evt)
* for so-called high priority HCI events, which should instead be delivered to
* the host stack through bt_recv_prio().
*
* @note This function must only be called from a cooperative thread.
*
* @param buf Network buffer containing data from the controller.
*
* @return 0 on success or negative error number on failure.
Expand Down
13 changes: 12 additions & 1 deletion subsys/bluetooth/host/hci_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -3854,7 +3854,7 @@ static void rx_queue_put(struct net_buf *buf)
}
#endif /* !CONFIG_BT_RECV_BLOCKING */

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

Expand Down Expand Up @@ -3905,6 +3905,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_recv_prio(struct net_buf *buf)
{
bt_monitor_send(bt_monitor_opcode(buf), buf->data, buf->len);
Expand Down

0 comments on commit ca4e65e

Please sign in to comment.