Skip to content

Commit ac91402

Browse files
rlubosdkalowsk
authored andcommitted
net: tcp: Use net_buf pointer directly for out-of-order recv queue
Using net_pkt for TCP out-of-order recv queue was an overshot, as the mechanism mostly used net_buf operations directly anyway. It can be easily replaced with a direct net_buf pointer, so that it's not longer needed to hog one net_pkt per TCP context anymore. Signed-off-by: Robert Lubos <[email protected]> (cherry picked from commit aca511c)
1 parent e58bca8 commit ac91402

File tree

2 files changed

+31
-43
lines changed

2 files changed

+31
-43
lines changed

subsys/net/ip/tcp.c

Lines changed: 30 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -797,7 +797,10 @@ static void tcp_conn_release(struct k_work *work)
797797
tcp_pkt_unref(conn->send_data);
798798

799799
if (CONFIG_NET_TCP_RECV_QUEUE_TIMEOUT) {
800-
tcp_pkt_unref(conn->queue_recv_data);
800+
if (conn->queue_recv_data != NULL) {
801+
net_buf_unref(conn->queue_recv_data);
802+
conn->queue_recv_data = NULL;
803+
}
801804
}
802805

803806
(void)k_work_cancel_delayable(&conn->timewait_timer);
@@ -1136,8 +1139,7 @@ static size_t tcp_check_pending_data(struct tcp *conn, struct net_pkt *pkt,
11361139
{
11371140
size_t pending_len = 0;
11381141

1139-
if (CONFIG_NET_TCP_RECV_QUEUE_TIMEOUT &&
1140-
!net_pkt_is_empty(conn->queue_recv_data)) {
1142+
if (CONFIG_NET_TCP_RECV_QUEUE_TIMEOUT && conn->queue_recv_data != NULL) {
11411143
/* Some potentential cases:
11421144
* Note: MI = MAX_INT
11431145
* Packet | Queued| End off | Gap size | Required handling
@@ -1159,10 +1161,10 @@ static size_t tcp_check_pending_data(struct tcp *conn, struct net_pkt *pkt,
11591161
int32_t gap_size;
11601162
uint32_t end_offset;
11611163

1162-
pending_seq = tcp_get_seq(conn->queue_recv_data->buffer);
1164+
pending_seq = tcp_get_seq(conn->queue_recv_data);
11631165
end_offset = expected_seq - pending_seq;
11641166
gap_size = (int32_t)(pending_seq - th_seq(th) - ((uint32_t)len));
1165-
pending_len = net_pkt_get_len(conn->queue_recv_data);
1167+
pending_len = net_buf_frags_len(conn->queue_recv_data);
11661168
if (end_offset < pending_len) {
11671169
if (end_offset) {
11681170
net_pkt_remove_tail(pkt, end_offset);
@@ -1173,15 +1175,15 @@ static size_t tcp_check_pending_data(struct tcp *conn, struct net_pkt *pkt,
11731175
expected_seq, pending_len);
11741176

11751177
net_buf_frag_add(pkt->buffer,
1176-
conn->queue_recv_data->buffer);
1177-
conn->queue_recv_data->buffer = NULL;
1178+
conn->queue_recv_data);
1179+
conn->queue_recv_data = NULL;
11781180

11791181
k_work_cancel_delayable(&conn->recv_queue_timer);
11801182
} else {
11811183
/* Check if the queued data is just a section of the incoming data */
11821184
if (gap_size <= 0) {
1183-
net_buf_unref(conn->queue_recv_data->buffer);
1184-
conn->queue_recv_data->buffer = NULL;
1185+
net_buf_unref(conn->queue_recv_data);
1186+
conn->queue_recv_data = NULL;
11851187

11861188
k_work_cancel_delayable(&conn->recv_queue_timer);
11871189
}
@@ -1770,11 +1772,11 @@ static void tcp_cleanup_recv_queue(struct k_work *work)
17701772
k_mutex_lock(&conn->lock, K_FOREVER);
17711773

17721774
NET_DBG("Cleanup recv queue conn %p len %zd seq %u", conn,
1773-
net_pkt_get_len(conn->queue_recv_data),
1774-
tcp_get_seq(conn->queue_recv_data->buffer));
1775+
net_buf_frags_len(conn->queue_recv_data),
1776+
tcp_get_seq(conn->queue_recv_data));
17751777

1776-
net_buf_unref(conn->queue_recv_data->buffer);
1777-
conn->queue_recv_data->buffer = NULL;
1778+
net_buf_unref(conn->queue_recv_data);
1779+
conn->queue_recv_data = NULL;
17781780

17791781
k_mutex_unlock(&conn->lock);
17801782
}
@@ -2022,15 +2024,6 @@ static struct tcp *tcp_conn_alloc(void)
20222024

20232025
memset(conn, 0, sizeof(*conn));
20242026

2025-
if (CONFIG_NET_TCP_RECV_QUEUE_TIMEOUT) {
2026-
conn->queue_recv_data = tcp_rx_pkt_alloc(conn, 0);
2027-
if (conn->queue_recv_data == NULL) {
2028-
NET_ERR("Cannot allocate %s queue for conn %p", "recv",
2029-
conn);
2030-
goto fail;
2031-
}
2032-
}
2033-
20342027
conn->send_data = tcp_pkt_alloc(conn, 0);
20352028
if (conn->send_data == NULL) {
20362029
NET_ERR("Cannot allocate %s queue for conn %p", "send", conn);
@@ -2089,11 +2082,6 @@ static struct tcp *tcp_conn_alloc(void)
20892082
return conn;
20902083

20912084
fail:
2092-
if (CONFIG_NET_TCP_RECV_QUEUE_TIMEOUT && conn->queue_recv_data) {
2093-
tcp_pkt_unref(conn->queue_recv_data);
2094-
conn->queue_recv_data = NULL;
2095-
}
2096-
20972085
k_mem_slab_free(&tcp_conns_slab, (void *)conn);
20982086
return NULL;
20992087
}
@@ -2545,7 +2533,7 @@ static void tcp_queue_recv_data(struct tcp *conn, struct net_pkt *pkt,
25452533
NET_DBG("Queuing data: conn %p", conn);
25462534
}
25472535

2548-
if (!net_pkt_is_empty(conn->queue_recv_data)) {
2536+
if (conn->queue_recv_data != NULL) {
25492537
/* Place the data to correct place in the list. If the data
25502538
* would not be sequential, then drop this packet.
25512539
*
@@ -2575,9 +2563,9 @@ static void tcp_queue_recv_data(struct tcp *conn, struct net_pkt *pkt,
25752563
uint32_t end_offset;
25762564
size_t pending_len;
25772565

2578-
pending_seq = tcp_get_seq(conn->queue_recv_data->buffer);
2566+
pending_seq = tcp_get_seq(conn->queue_recv_data);
25792567
end_offset = seq - pending_seq;
2580-
pending_len = net_pkt_get_len(conn->queue_recv_data);
2568+
pending_len = net_buf_frags_len(conn->queue_recv_data);
25812569
if (end_offset < pending_len) {
25822570
if (end_offset < len) {
25832571
if (end_offset) {
@@ -2586,16 +2574,16 @@ static void tcp_queue_recv_data(struct tcp *conn, struct net_pkt *pkt,
25862574

25872575
/* Put new data before the pending data */
25882576
net_buf_frag_add(pkt->buffer,
2589-
conn->queue_recv_data->buffer);
2577+
conn->queue_recv_data);
25902578
NET_DBG("Adding at before queue, end_offset %i, pending_len %zu",
25912579
end_offset, pending_len);
2592-
conn->queue_recv_data->buffer = pkt->buffer;
2580+
conn->queue_recv_data = pkt->buffer;
25932581
inserted = true;
25942582
}
25952583
} else {
25962584
struct net_buf *last;
25972585

2598-
last = net_buf_frag_last(conn->queue_recv_data->buffer);
2586+
last = net_buf_frag_last(conn->queue_recv_data);
25992587
pending_seq = tcp_get_seq(last);
26002588

26012589
start_offset = pending_seq - seq_start;
@@ -2607,20 +2595,20 @@ static void tcp_queue_recv_data(struct tcp *conn, struct net_pkt *pkt,
26072595
/* The queued data is irrelevant since the new packet overlaps the
26082596
* new packet, take the new packet as contents
26092597
*/
2610-
net_buf_unref(conn->queue_recv_data->buffer);
2611-
conn->queue_recv_data->buffer = pkt->buffer;
2598+
net_buf_unref(conn->queue_recv_data);
2599+
conn->queue_recv_data = pkt->buffer;
26122600
inserted = true;
26132601
} else {
26142602
if (end_offset < len) {
26152603
if (end_offset) {
2616-
net_pkt_remove_tail(conn->queue_recv_data,
2617-
end_offset);
2604+
net_buf_remove_mem(conn->queue_recv_data,
2605+
end_offset);
26182606
}
26192607

26202608
/* Put new data after pending data */
26212609
NET_DBG("Adding at end of queue, start %i, end %i, len %zu",
26222610
start_offset, end_offset, len);
2623-
net_buf_frag_add(conn->queue_recv_data->buffer,
2611+
net_buf_frag_add(conn->queue_recv_data,
26242612
pkt->buffer);
26252613
inserted = true;
26262614
}
@@ -2629,18 +2617,18 @@ static void tcp_queue_recv_data(struct tcp *conn, struct net_pkt *pkt,
26292617

26302618
if (inserted) {
26312619
NET_DBG("All pending data: conn %p", conn);
2632-
if (check_seq_list(conn->queue_recv_data->buffer) == false) {
2620+
if (check_seq_list(conn->queue_recv_data) == false) {
26332621
NET_ERR("Incorrect order in out of order sequence for conn %p",
26342622
conn);
26352623
/* error in sequence list, drop it */
2636-
net_buf_unref(conn->queue_recv_data->buffer);
2637-
conn->queue_recv_data->buffer = NULL;
2624+
net_buf_unref(conn->queue_recv_data);
2625+
conn->queue_recv_data = NULL;
26382626
}
26392627
} else {
26402628
NET_DBG("Cannot add new data to queue");
26412629
}
26422630
} else {
2643-
net_pkt_append_buffer(conn->queue_recv_data, pkt->buffer);
2631+
conn->queue_recv_data = pkt->buffer;
26442632
inserted = true;
26452633
}
26462634

subsys/net/ip/tcp_private.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ struct tcp { /* TCP connection */
259259
sys_snode_t next;
260260
struct net_context *context;
261261
struct net_pkt *send_data;
262-
struct net_pkt *queue_recv_data;
262+
struct net_buf *queue_recv_data;
263263
struct net_if *iface;
264264
void *recv_user_data;
265265
sys_slist_t send_queue;

0 commit comments

Comments
 (0)