From d613f7e35a915cd7dea18799e483a8e971934c6c Mon Sep 17 00:00:00 2001 From: Aleksander Wasaznik Date: Wed, 3 Apr 2024 11:11:26 +0200 Subject: [PATCH] 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 --- drivers/bluetooth/hci/rpmsg.c | 12 ------------ include/zephyr/drivers/bluetooth/hci_driver.h | 2 -- subsys/bluetooth/host/hci_core.c | 13 ++++++++++++- 3 files changed, 12 insertions(+), 15 deletions(-) diff --git a/drivers/bluetooth/hci/rpmsg.c b/drivers/bluetooth/hci/rpmsg.c index b3611f5f3e2c26..0f501c9143c03a 100644 --- a/drivers/bluetooth/hci/rpmsg.c +++ b/drivers/bluetooth/hci/rpmsg.c @@ -229,19 +229,7 @@ static void bt_rpmsg_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:"); } diff --git a/include/zephyr/drivers/bluetooth/hci_driver.h b/include/zephyr/drivers/bluetooth/hci_driver.h index c305ecc37c3889..3774c8264adb4a 100644 --- a/include/zephyr/drivers/bluetooth/hci_driver.h +++ b/include/zephyr/drivers/bluetooth/hci_driver.h @@ -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. diff --git a/subsys/bluetooth/host/hci_core.c b/subsys/bluetooth/host/hci_core.c index c7235d62291c69..37e9e793bfb572 100644 --- a/subsys/bluetooth/host/hci_core.c +++ b/subsys/bluetooth/host/hci_core.c @@ -3758,7 +3758,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); @@ -3809,6 +3809,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);