Skip to content

Commit

Permalink
Bluetooth: host: update l2cap stress test
Browse files Browse the repository at this point in the history
Do these things:
- use the proper macros for reserving the SDU header
- make every L2CAP PDU fragment into 3 ACL packets
- set tx data and verify rx matches the pattern
- measure segment pool usage

Signed-off-by: Jonathan Rico <[email protected]>
(cherry picked from commit 8bc0946)
  • Loading branch information
jori-nordic authored and theob-pro committed Jun 1, 2023
1 parent b84f1fb commit ce7423c
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 15 deletions.
26 changes: 15 additions & 11 deletions tests/bluetooth/bsim_bt/bsim_test_l2cap_stress/prj.conf
Original file line number Diff line number Diff line change
Expand Up @@ -18,28 +18,32 @@ CONFIG_BT_GAP_AUTO_UPDATE_CONN_PARAMS=n
# L2CAP MPS
# 23+27+27=77 makes exactly three full packets
CONFIG_BT_L2CAP_TX_MTU=77
CONFIG_BT_BUF_ACL_TX_SIZE=77

# Use this to send L2CAP PDUs without any fragmentation.
# In this particular case, we prefer fragmenting to test that code path.
# CONFIG_BT_BUF_ACL_TX_SIZE=81

# L2CAP PDUs will be fragmented in 3 ACL packets.
CONFIG_BT_BUF_ACL_TX_SIZE=27

CONFIG_BT_BUF_ACL_TX_COUNT=4

# The minimum value for this is
# L2AP MPS + L2CAP header (4)
CONFIG_BT_BUF_ACL_RX_SIZE=81

# TODO: find out why we can't use 16 buffers. It should fit.

CONFIG_BT_L2CAP_TX_BUF_COUNT=30
# CONFIG_BT_L2CAP_TX_BUF_COUNT=100

CONFIG_BT_BUF_ACL_TX_COUNT=4
# Governs BT_CONN_TX_MAX, and so must be >= than the max number of
# peers, since we attempt to send one SDU per peer. The test execution
# is a bit slowed down by having this at the very minimum, but we want
# to keep it that way as to stress the stack as much as possible.
CONFIG_BT_L2CAP_TX_BUF_COUNT=6

CONFIG_BT_CTLR_DATA_LENGTH_MAX=27
CONFIG_BT_CTLR_RX_BUFFERS=10
# The ring buffer now has space for three times as much data
# (default 27, 3*27=81), so that it does not run out of data
# while waiting for new SDUs to be queued.
CONFIG_BT_CTLR_DATA_LENGTH_MAX=81

CONFIG_BT_MAX_CONN=10

CONFIG_LOG=y
CONFIG_ASSERT=y
CONFIG_BT_DEBUG_LOG=y
CONFIG_NET_BUF_POOL_USAGE=y
43 changes: 39 additions & 4 deletions tests/bluetooth/bsim_bt/bsim_test_l2cap_stress/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,21 @@ CREATE_FLAG(flag_l2cap_connected);
#define INIT_CREDITS 10
#define SDU_NUM 20
#define SDU_LEN 1230
#define NUM_SEGMENTS 10

/* Only one SDU per link will be transmitted at a time */
/* FIXME: decrease size */
NET_BUF_POOL_DEFINE(sdu_tx_pool,
100, BT_L2CAP_BUF_SIZE(SDU_LEN),
CONFIG_BT_MAX_CONN, BT_L2CAP_SDU_BUF_SIZE(SDU_LEN),
8, NULL);

NET_BUF_POOL_DEFINE(segment_pool,
/* MTU + 4 l2cap hdr + 4 ACL hdr */
NUM_SEGMENTS, BT_L2CAP_BUF_SIZE(CONFIG_BT_L2CAP_TX_MTU),
8, NULL);

/* Only one SDU per link will be received at a time */
NET_BUF_POOL_DEFINE(sdu_rx_pool,
CONFIG_BT_MAX_CONN, BT_L2CAP_BUF_SIZE(SDU_LEN),
CONFIG_BT_MAX_CONN, BT_L2CAP_SDU_BUF_SIZE(SDU_LEN),
8, NULL);

static struct bt_l2cap_le_chan l2cap_channels[L2CAP_CHANS];
Expand All @@ -40,6 +45,7 @@ static uint8_t tx_data[SDU_LEN];
static uint8_t tx_left[L2CAP_CHANS];
static uint16_t rx_cnt;
static uint8_t disconnect_counter;
static uint32_t max_seg_allocated;

int l2cap_chan_send(struct bt_l2cap_chan *chan, uint8_t *data, size_t len)
{
Expand All @@ -52,7 +58,7 @@ int l2cap_chan_send(struct bt_l2cap_chan *chan, uint8_t *data, size_t len)
return -ENOMEM;
}

net_buf_reserve(buf, BT_L2CAP_CHAN_SEND_RESERVE);
net_buf_reserve(buf, BT_L2CAP_SDU_CHAN_SEND_RESERVE);
net_buf_add_mem(buf, data, len);

int ret = bt_l2cap_chan_send(chan, buf);
Expand All @@ -66,6 +72,19 @@ int l2cap_chan_send(struct bt_l2cap_chan *chan, uint8_t *data, size_t len)
return ret;
}

struct net_buf *alloc_seg_cb(struct bt_l2cap_chan *chan)
{
struct net_buf *buf = net_buf_alloc(&segment_pool, K_NO_WAIT);

if ((NUM_SEGMENTS - segment_pool.avail_count) > max_seg_allocated) {
max_seg_allocated++;
}

ASSERT(buf, "Ran out of segment buffers");

return buf;
}

struct net_buf *alloc_buf_cb(struct bt_l2cap_chan *chan)
{
return net_buf_alloc(&sdu_rx_pool, K_NO_WAIT);
Expand Down Expand Up @@ -108,6 +127,9 @@ int recv_cb(struct bt_l2cap_chan *chan, struct net_buf *buf)
LOG_DBG("len %d", buf->len);
rx_cnt++;

/* Verify SDU data matches TX'd data. */
ASSERT(memcmp(buf->data, tx_data, buf->len) == 0, "RX data doesn't match TX");

return 0;
}

Expand Down Expand Up @@ -137,6 +159,7 @@ static struct bt_l2cap_chan_ops ops = {
.connected = l2cap_chan_connected_cb,
.disconnected = l2cap_chan_disconnected_cb,
.alloc_buf = alloc_buf_cb,
.alloc_seg = alloc_seg_cb,
.recv = recv_cb,
.sent = sent_cb,
};
Expand Down Expand Up @@ -253,6 +276,11 @@ static void test_peripheral_main(void)
LOG_DBG("*L2CAP STRESS Peripheral started*");
int err;

/* Prepare tx_data */
for (size_t i = 0; i < sizeof(tx_data); i++) {
tx_data[i] = (uint8_t)i;
}

err = bt_enable(NULL);
if (err) {
FAIL("Can't enable Bluetooth (err %d)", err);
Expand Down Expand Up @@ -358,6 +386,11 @@ static void test_central_main(void)
LOG_DBG("*L2CAP STRESS Central started*");
int err;

/* Prepare tx_data */
for (size_t i = 0; i < sizeof(tx_data); i++) {
tx_data[i] = (uint8_t)i;
}

err = bt_enable(NULL);
ASSERT(err == 0, "Can't enable Bluetooth (err %d)\n", err);
LOG_DBG("Central Bluetooth initialized.");
Expand Down Expand Up @@ -395,6 +428,8 @@ static void test_central_main(void)
}
LOG_DBG("All peripherals disconnected.");

LOG_DBG("Max segment pool usage: %u bufs", max_seg_allocated);

PASS("L2CAP STRESS Central passed\n");
}

Expand Down

0 comments on commit ce7423c

Please sign in to comment.