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:
parent
78ddcdd6fa
commit
a64d20f6f0
3 changed files with 12 additions and 15 deletions
|
@ -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:");
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue