Commit a64d20f6 authored by Aleksander Wasaznik's avatar Aleksander Wasaznik Committed by Anas Nashif
Browse files

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: default avatarAleksander Wasaznik <aleksander.wasaznik@nordicsemi.no>
parent 78ddcdd6
Loading
Loading
Loading
Loading
+0 −12
Original line number Diff line number Diff line
@@ -237,19 +237,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:");
	}
+0 −2
Original line number Diff line number Diff line
@@ -46,8 +46,6 @@ enum {
 * 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.
 *
 * @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.
+12 −1
Original line number Diff line number Diff line
@@ -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);

@@ -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)
{
	if (bt_dev.drv) {