Bluetooth: host: poll on CTLR buffers instead of host TX queue

When there are no buffers, it doesn't make sense to repeatedly try to send
the host TX queue.

Signed-off-by: Jonathan Rico <jonathan.rico@nordicsemi.no>
This commit is contained in:
Jonathan Rico 2022-11-15 12:05:50 +01:00 committed by Fabio Baltieri
commit ef19c64f1b
4 changed files with 31 additions and 7 deletions

View file

@ -513,7 +513,7 @@ static int send_frag(struct bt_conn *conn, struct net_buf *buf, uint8_t flags,
int err = 0;
/* Check if the controller can accept ACL packets */
if (k_sem_take(bt_conn_get_pkts(conn), K_MSEC(100))) {
if (k_sem_take(bt_conn_get_pkts(conn), K_NO_WAIT)) {
/* not `goto fail`, we don't want to free the tx context: in the
* case where it is the original buffer, it will contain the
* callback ptr.
@ -776,10 +776,26 @@ static int conn_prepare_events(struct bt_conn *conn,
LOG_DBG("Adding conn %p to poll list", conn);
k_poll_event_init(&events[0],
K_POLL_TYPE_FIFO_DATA_AVAILABLE,
K_POLL_MODE_NOTIFY_ONLY,
&conn->tx_queue);
bool buffers_available = k_sem_count_get(bt_conn_get_pkts(conn)) > 0;
bool packets_waiting = !k_fifo_is_empty(&conn->tx_queue);
if (packets_waiting && !buffers_available) {
/* Only resume sending when the controller has buffer space
* available for this connection.
*/
LOG_DBG("wait on ctlr buffers");
k_poll_event_init(&events[0],
K_POLL_TYPE_SEM_AVAILABLE,
K_POLL_MODE_NOTIFY_ONLY,
bt_conn_get_pkts(conn));
} else {
/* Wait until there is more data to send. */
LOG_DBG("wait on host fifo");
k_poll_event_init(&events[0],
K_POLL_TYPE_FIFO_DATA_AVAILABLE,
K_POLL_MODE_NOTIFY_ONLY,
&conn->tx_queue);
}
events[0].tag = BT_EVENT_CONN_TX_QUEUE;
return 0;

View file

@ -2465,6 +2465,13 @@ static void process_events(struct k_poll_event *ev, int count)
switch (ev->state) {
case K_POLL_STATE_SIGNALED:
break;
case K_POLL_STATE_SEM_AVAILABLE:
/* After this fn is exec'd, `bt_conn_prepare_events()`
* will be called once again, and this time buffers will
* be available, so the FIFO will be added to the poll
* list instead of the ctlr buffers semaphore.
*/
break;
case K_POLL_STATE_FIFO_DATA_AVAILABLE:
if (ev->tag == BT_EVENT_CMD_TX) {
send_cmd();
@ -2524,6 +2531,7 @@ static void hci_tx_thread(void *p1, void *p2, void *p3)
events[0].state = K_POLL_STATE_NOT_READY;
ev_count = 1;
/* This adds the FIFO per-connection */
if (IS_ENABLED(CONFIG_BT_CONN) || IS_ENABLED(CONFIG_BT_ISO)) {
ev_count += bt_conn_prepare_events(&events[1]);
}