From ef19c64f1b77316ad3bb36ee0921eec4840c8889 Mon Sep 17 00:00:00 2001 From: Jonathan Rico Date: Tue, 15 Nov 2022 12:05:50 +0100 Subject: [PATCH] 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 --- subsys/bluetooth/host/conn.c | 26 +++++++++++++++---- subsys/bluetooth/host/hci_core.c | 8 ++++++ .../bsim_test_l2cap_stress/src/common.h | 2 +- .../tests_scripts/l2cap.sh | 2 +- 4 files changed, 31 insertions(+), 7 deletions(-) diff --git a/subsys/bluetooth/host/conn.c b/subsys/bluetooth/host/conn.c index 227a2724def..accb4aa0a73 100644 --- a/subsys/bluetooth/host/conn.c +++ b/subsys/bluetooth/host/conn.c @@ -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; diff --git a/subsys/bluetooth/host/hci_core.c b/subsys/bluetooth/host/hci_core.c index 028cc715b51..c8bc73bbabc 100644 --- a/subsys/bluetooth/host/hci_core.c +++ b/subsys/bluetooth/host/hci_core.c @@ -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]); } diff --git a/tests/bluetooth/bsim_bt/bsim_test_l2cap_stress/src/common.h b/tests/bluetooth/bsim_bt/bsim_test_l2cap_stress/src/common.h index 199033f78f7..d3b01cd1d68 100644 --- a/tests/bluetooth/bsim_bt/bsim_test_l2cap_stress/src/common.h +++ b/tests/bluetooth/bsim_bt/bsim_test_l2cap_stress/src/common.h @@ -36,7 +36,7 @@ extern enum bst_result_t bst_result; } -#define WAIT_SECONDS 220 /* seconds */ +#define WAIT_SECONDS 270 /* seconds */ #define WAIT_TIME (WAIT_SECONDS * USEC_PER_SEC) /* microseconds*/ #define FAIL(...) \ diff --git a/tests/bluetooth/bsim_bt/bsim_test_l2cap_stress/tests_scripts/l2cap.sh b/tests/bluetooth/bsim_bt/bsim_test_l2cap_stress/tests_scripts/l2cap.sh index dc58d8dc8f9..bd7bbacbcef 100755 --- a/tests/bluetooth/bsim_bt/bsim_test_l2cap_stress/tests_scripts/l2cap.sh +++ b/tests/bluetooth/bsim_bt/bsim_test_l2cap_stress/tests_scripts/l2cap.sh @@ -35,7 +35,7 @@ Execute "${bsim_exe}" -v=${verbosity_level} -s=${simulation_id} -d=4 -testid=per Execute "${bsim_exe}" -v=${verbosity_level} -s=${simulation_id} -d=5 -testid=peripheral -rs=230 Execute "${bsim_exe}" -v=${verbosity_level} -s=${simulation_id} -d=6 -testid=peripheral -rs=9 -Execute ./bs_2G4_phy_v1 -v=${verbosity_level} -s=${simulation_id} -D=7 -sim_length=240e6 $@ +Execute ./bs_2G4_phy_v1 -v=${verbosity_level} -s=${simulation_id} -D=7 -sim_length=270e6 $@ for process_id in $process_ids; do wait $process_id || let "exit_code=$?"