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:
parent
c3e5fabbf1
commit
ef19c64f1b
4 changed files with 31 additions and 7 deletions
|
@ -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;
|
||||
|
|
|
@ -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]);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue