Skip to content

Commit d57a6ca

Browse files
jori-nordiccvinayak
authored andcommitted
[nrf fromtree] Revert "Bluetooth: att: re-use REQ buf for RSP"
This reverts commit aa7954bd4725bbd46e974a03c0d0312b7e9a483f. Signed-off-by: Jonathan Rico <[email protected]> (cherry picked from commit 946aed54febdec53afabce843eb036a4216cfe89)
1 parent 749c09e commit d57a6ca

File tree

4 files changed

+36
-73
lines changed

4 files changed

+36
-73
lines changed

subsys/bluetooth/host/att.c

Lines changed: 11 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,6 @@ struct bt_att_chan {
103103
ATOMIC_DEFINE(flags, ATT_NUM_FLAGS);
104104
struct bt_att_req *req;
105105
struct k_fifo tx_queue;
106-
struct net_buf *rsp_buf;
107106
struct bt_att_tx_meta_data rsp_meta;
108107
struct k_work_delayable timeout_work;
109108
sys_snode_t node;
@@ -660,7 +659,7 @@ static struct net_buf *bt_att_chan_create_pdu(struct bt_att_chan *chan, uint8_t
660659
struct net_buf *buf;
661660
struct bt_att_tx_meta_data *data;
662661
k_timeout_t timeout;
663-
bool re_use = false;
662+
bool is_rsp = false;
664663

665664
if (len + sizeof(op) > bt_att_mtu(chan)) {
666665
LOG_WRN("ATT MTU exceeded, max %u, wanted %zu", bt_att_mtu(chan),
@@ -673,23 +672,19 @@ static struct net_buf *bt_att_chan_create_pdu(struct bt_att_chan *chan, uint8_t
673672
case ATT_CONFIRMATION:
674673
/* Use a timeout only when responding/confirming */
675674
timeout = BT_ATT_TIMEOUT;
676-
re_use = true;
675+
is_rsp = true;
677676
break;
678677
default:
679678
timeout = K_FOREVER;
680679
}
681680

682-
if (IS_ENABLED(CONFIG_BT_GATT_READ_MULTIPLE) &&
683-
(op == BT_ATT_OP_READ_MULT_RSP ||
684-
op == BT_ATT_OP_READ_MULT_VL_RSP)) {
685-
/* We can't re-use the REQ buffer (see below) for these two
686-
* opcodes, as the handler will read from it _after_ allocating
687-
* the RSP buffer.
688-
*/
689-
re_use = false;
681+
buf = bt_l2cap_create_pdu_timeout(NULL, 0, timeout);
682+
if (!buf) {
683+
LOG_ERR("Unable to allocate buffer for op 0x%02x", op);
684+
return NULL;
690685
}
691686

692-
if (re_use) {
687+
if (is_rsp) {
693688
/* There can only ever be one transaction at a time on a
694689
* bearer/channel. Use a dedicated channel meta-data to ensure
695690
* we can always queue an (error) RSP for each REQ. The ATT
@@ -706,27 +701,8 @@ static struct net_buf *bt_att_chan_create_pdu(struct bt_att_chan *chan, uint8_t
706701
return NULL;
707702
}
708703
data = &chan->rsp_meta;
709-
710-
/* Re-use REQ buf to avoid dropping the REQ and timing out.
711-
* This only works if the bearer used to RX REQs is the same as
712-
* for sending the RSP. That should always be the case
713-
* (per-spec).
714-
*/
715-
__ASSERT_NO_MSG(chan->rsp_buf);
716-
buf = net_buf_ref(chan->rsp_buf);
717-
718-
net_buf_reset(buf);
719-
net_buf_reserve(buf, BT_L2CAP_BUF_SIZE(0));
720-
721-
LOG_DBG("re-using REQ buf %p for RSP", buf);
704+
LOG_INF("alloc rsp meta");
722705
} else {
723-
LOG_DBG("alloc buf & meta from global pools");
724-
buf = bt_l2cap_create_pdu_timeout(NULL, 0, timeout);
725-
if (!buf) {
726-
LOG_ERR("Unable to allocate buffer for op 0x%02x", op);
727-
return NULL;
728-
}
729-
730706
data = tx_meta_data_alloc(timeout);
731707
if (!data) {
732708
LOG_WRN("Unable to allocate ATT TX meta");
@@ -810,7 +786,6 @@ static void send_err_rsp(struct bt_att_chan *chan, uint8_t req, uint16_t handle,
810786

811787
buf = bt_att_chan_create_pdu(chan, BT_ATT_OP_ERROR_RSP, sizeof(*rsp));
812788
if (!buf) {
813-
LOG_ERR("unable to allocate buf for error response");
814789
return;
815790
}
816791

@@ -2894,40 +2869,26 @@ static int bt_att_recv(struct bt_l2cap_chan *chan, struct net_buf *buf)
28942869
}
28952870
}
28962871

2897-
/* Thread-local variable, shouldn't be used by anything else */
2898-
__ASSERT_NO_MSG(!att_chan->rsp_buf);
2899-
2900-
/* Mark buffer free for re-use by the opcode handler.
2901-
*
2902-
* This allows ATT to always be able to send a RSP (or err RSP)
2903-
* to the peer, regardless of the TX buffer usage by other stack
2904-
* users (e.g. GATT notifications, L2CAP using global pool, SMP,
2905-
* etc..), avoiding an ATT timeout due to resource usage.
2906-
*
2907-
* The ref is taken by `bt_att_chan_create_pdu`.
2908-
*/
2909-
att_chan->rsp_buf = net_buf_ref(buf);
2910-
29112872
if (!handler) {
29122873
LOG_WRN("Unhandled ATT code 0x%02x", hdr->code);
29132874
if (att_op_get_type(hdr->code) != ATT_COMMAND &&
29142875
att_op_get_type(hdr->code) != ATT_INDICATION) {
29152876
send_err_rsp(att_chan, hdr->code, 0,
29162877
BT_ATT_ERR_NOT_SUPPORTED);
29172878
}
2918-
goto exit;
2879+
return 0;
29192880
}
29202881

29212882
if (IS_ENABLED(CONFIG_BT_ATT_ENFORCE_FLOW)) {
29222883
if (handler->type == ATT_REQUEST &&
29232884
atomic_test_and_set_bit(att_chan->flags, ATT_PENDING_RSP)) {
29242885
LOG_WRN("Ignoring unexpected request");
2925-
goto exit;
2886+
return 0;
29262887
} else if (handler->type == ATT_INDICATION &&
29272888
atomic_test_and_set_bit(att_chan->flags,
29282889
ATT_PENDING_CFM)) {
29292890
LOG_WRN("Ignoring unexpected indication");
2930-
goto exit;
2891+
return 0;
29312892
}
29322893
}
29332894

@@ -2943,10 +2904,6 @@ static int bt_att_recv(struct bt_l2cap_chan *chan, struct net_buf *buf)
29432904
send_err_rsp(att_chan, hdr->code, 0, err);
29442905
}
29452906

2946-
exit:
2947-
net_buf_unref(att_chan->rsp_buf);
2948-
att_chan->rsp_buf = NULL;
2949-
29502907
return 0;
29512908
}
29522909

subsys/bluetooth/host/buf.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,15 +43,14 @@ NET_BUF_POOL_FIXED_DEFINE(discardable_pool, CONFIG_BT_BUF_EVT_DISCARDABLE_COUNT,
4343
#if defined(CONFIG_BT_HCI_ACL_FLOW_CONTROL)
4444
NET_BUF_POOL_DEFINE(acl_in_pool, CONFIG_BT_BUF_ACL_RX_COUNT,
4545
BT_BUF_ACL_SIZE(CONFIG_BT_BUF_ACL_RX_SIZE),
46-
MAX(sizeof(struct bt_buf_data), CONFIG_BT_CONN_TX_USER_DATA_SIZE),
47-
bt_hci_host_num_completed_packets);
46+
sizeof(struct acl_data), bt_hci_host_num_completed_packets);
4847

4948
NET_BUF_POOL_FIXED_DEFINE(evt_pool, CONFIG_BT_BUF_EVT_RX_COUNT,
5049
BT_BUF_EVT_RX_SIZE, 8,
5150
NULL);
5251
#else
5352
NET_BUF_POOL_FIXED_DEFINE(hci_rx_pool, BT_BUF_RX_COUNT,
54-
BT_BUF_RX_SIZE, CONFIG_BT_CONN_TX_USER_DATA_SIZE,
53+
BT_BUF_RX_SIZE, 8,
5554
NULL);
5655
#endif /* CONFIG_BT_HCI_ACL_FLOW_CONTROL */
5756

subsys/bluetooth/host/conn_internal.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,17 @@ struct bt_conn_tx {
146146
uint32_t pending_no_cb;
147147
};
148148

149+
struct acl_data {
150+
/* Extend the bt_buf user data */
151+
struct bt_buf_data buf_data;
152+
153+
/* Index into the bt_conn storage array */
154+
uint8_t index;
155+
156+
/** ACL connection handle */
157+
uint16_t handle;
158+
};
159+
149160
struct bt_conn {
150161
uint16_t handle;
151162
enum bt_conn_type type;

subsys/bluetooth/host/hci_core.c

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -111,16 +111,8 @@ struct cmd_data {
111111

112112
static struct cmd_data cmd_data[CONFIG_BT_BUF_CMD_TX_COUNT];
113113

114-
#if defined(CONFIG_BT_CONN)
115-
struct acl_data {
116-
uint16_t acl_handle;
117-
};
118-
119-
static struct acl_data acl_data[CONFIG_BT_BUF_ACL_RX_COUNT];
120-
#endif
121-
122114
#define cmd(buf) (&cmd_data[net_buf_id(buf)])
123-
#define acl(buf) (&acl_data[net_buf_id(buf)])
115+
#define acl(buf) ((struct acl_data *)net_buf_user_data(buf))
124116

125117
void bt_hci_cmd_state_set_init(struct net_buf *buf,
126118
struct bt_hci_cmd_state_set *state,
@@ -209,9 +201,10 @@ void bt_hci_host_num_completed_packets(struct net_buf *buf)
209201
{
210202

211203
struct bt_hci_cp_host_num_completed_packets *cp;
212-
uint16_t handle = acl(buf)->acl_handle;
204+
uint16_t handle = acl(buf)->handle;
213205
struct bt_hci_handle_count *hc;
214206
struct bt_conn *conn;
207+
uint8_t index = acl(buf)->index;
215208

216209
net_buf_destroy(buf);
217210

@@ -220,9 +213,9 @@ void bt_hci_host_num_completed_packets(struct net_buf *buf)
220213
return;
221214
}
222215

223-
conn = bt_conn_lookup_handle(handle, BT_CONN_TYPE_ALL);
216+
conn = bt_conn_lookup_index(index);
224217
if (!conn) {
225-
LOG_WRN("Unable to look up conn with ACL handle %u", handle);
218+
LOG_WRN("Unable to look up conn with index 0x%02x", index);
226219
return;
227220
}
228221

@@ -516,23 +509,26 @@ static void hci_acl(struct net_buf *buf)
516509
handle = sys_le16_to_cpu(hdr->handle);
517510
flags = bt_acl_flags(handle);
518511

519-
acl(buf)->acl_handle = bt_acl_handle(handle);
512+
acl(buf)->handle = bt_acl_handle(handle);
513+
acl(buf)->index = BT_CONN_INDEX_INVALID;
520514

521-
LOG_DBG("handle %u len %u flags %u", acl(buf)->acl_handle, len, flags);
515+
LOG_DBG("handle %u len %u flags %u", acl(buf)->handle, len, flags);
522516

523517
if (buf->len != len) {
524518
LOG_ERR("ACL data length mismatch (%u != %u)", buf->len, len);
525519
net_buf_unref(buf);
526520
return;
527521
}
528522

529-
conn = bt_conn_lookup_handle(acl(buf)->acl_handle, BT_CONN_TYPE_ALL);
523+
conn = bt_conn_lookup_handle(acl(buf)->handle, BT_CONN_TYPE_ALL);
530524
if (!conn) {
531-
LOG_ERR("Unable to find conn for handle %u", acl(buf)->acl_handle);
525+
LOG_ERR("Unable to find conn for handle %u", acl(buf)->handle);
532526
net_buf_unref(buf);
533527
return;
534528
}
535529

530+
acl(buf)->index = bt_conn_index(conn);
531+
536532
bt_conn_recv(conn, buf, flags);
537533
bt_conn_unref(conn);
538534
}

0 commit comments

Comments
 (0)