Skip to content

Commit aca511c

Browse files
rluboshenrikbrixandersen
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]>
1 parent 71f6840 commit aca511c

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
@@ -869,7 +869,10 @@ static void tcp_conn_release(struct k_work *work)
869869
tcp_pkt_unref(conn->send_data);
870870

871871
if (CONFIG_NET_TCP_RECV_QUEUE_TIMEOUT) {
872-
tcp_pkt_unref(conn->queue_recv_data);
872+
if (conn->queue_recv_data != NULL) {
873+
net_buf_unref(conn->queue_recv_data);
874+
conn->queue_recv_data = NULL;
875+
}
873876
}
874877

875878
(void)k_work_cancel_delayable(&conn->timewait_timer);
@@ -1208,8 +1211,7 @@ static size_t tcp_check_pending_data(struct tcp *conn, struct net_pkt *pkt,
12081211
{
12091212
size_t pending_len = 0;
12101213

1211-
if (CONFIG_NET_TCP_RECV_QUEUE_TIMEOUT &&
1212-
!net_pkt_is_empty(conn->queue_recv_data)) {
1214+
if (CONFIG_NET_TCP_RECV_QUEUE_TIMEOUT && conn->queue_recv_data != NULL) {
12131215
/* Some potentential cases:
12141216
* Note: MI = MAX_INT
12151217
* Packet | Queued| End off | Gap size | Required handling
@@ -1231,10 +1233,10 @@ static size_t tcp_check_pending_data(struct tcp *conn, struct net_pkt *pkt,
12311233
int32_t gap_size;
12321234
uint32_t end_offset;
12331235

1234-
pending_seq = tcp_get_seq(conn->queue_recv_data->buffer);
1236+
pending_seq = tcp_get_seq(conn->queue_recv_data);
12351237
end_offset = expected_seq - pending_seq;
12361238
gap_size = (int32_t)(pending_seq - th_seq(th) - ((uint32_t)len));
1237-
pending_len = net_pkt_get_len(conn->queue_recv_data);
1239+
pending_len = net_buf_frags_len(conn->queue_recv_data);
12381240
if (end_offset < pending_len) {
12391241
if (end_offset) {
12401242
net_pkt_remove_tail(pkt, end_offset);
@@ -1245,15 +1247,15 @@ static size_t tcp_check_pending_data(struct tcp *conn, struct net_pkt *pkt,
12451247
expected_seq, pending_len);
12461248

12471249
net_buf_frag_add(pkt->buffer,
1248-
conn->queue_recv_data->buffer);
1249-
conn->queue_recv_data->buffer = NULL;
1250+
conn->queue_recv_data);
1251+
conn->queue_recv_data = NULL;
12501252

12511253
k_work_cancel_delayable(&conn->recv_queue_timer);
12521254
} else {
12531255
/* Check if the queued data is just a section of the incoming data */
12541256
if (gap_size <= 0) {
1255-
net_buf_unref(conn->queue_recv_data->buffer);
1256-
conn->queue_recv_data->buffer = NULL;
1257+
net_buf_unref(conn->queue_recv_data);
1258+
conn->queue_recv_data = NULL;
12571259

12581260
k_work_cancel_delayable(&conn->recv_queue_timer);
12591261
}
@@ -1899,11 +1901,11 @@ static void tcp_cleanup_recv_queue(struct k_work *work)
18991901
k_mutex_lock(&conn->lock, K_FOREVER);
19001902

19011903
NET_DBG("[%p] cleanup recv queue len %zd seq %u", conn,
1902-
net_pkt_get_len(conn->queue_recv_data),
1903-
tcp_get_seq(conn->queue_recv_data->buffer));
1904+
net_buf_frags_len(conn->queue_recv_data),
1905+
tcp_get_seq(conn->queue_recv_data));
19041906

1905-
net_buf_unref(conn->queue_recv_data->buffer);
1906-
conn->queue_recv_data->buffer = NULL;
1907+
net_buf_unref(conn->queue_recv_data);
1908+
conn->queue_recv_data = NULL;
19071909

19081910
k_mutex_unlock(&conn->lock);
19091911
}
@@ -2154,15 +2156,6 @@ static struct tcp *tcp_conn_alloc(void)
21542156

21552157
memset(conn, 0, sizeof(*conn));
21562158

2157-
if (CONFIG_NET_TCP_RECV_QUEUE_TIMEOUT) {
2158-
conn->queue_recv_data = tcp_rx_pkt_alloc(conn, 0);
2159-
if (conn->queue_recv_data == NULL) {
2160-
NET_ERR("Cannot allocate %s queue for conn %p", "recv",
2161-
conn);
2162-
goto fail;
2163-
}
2164-
}
2165-
21662159
conn->send_data = tcp_pkt_alloc(conn, 0);
21672160
if (conn->send_data == NULL) {
21682161
NET_ERR("Cannot allocate %s queue for conn %p", "send", conn);
@@ -2223,11 +2216,6 @@ static struct tcp *tcp_conn_alloc(void)
22232216
return conn;
22242217

22252218
fail:
2226-
if (CONFIG_NET_TCP_RECV_QUEUE_TIMEOUT && conn->queue_recv_data) {
2227-
tcp_pkt_unref(conn->queue_recv_data);
2228-
conn->queue_recv_data = NULL;
2229-
}
2230-
22312219
k_mem_slab_free(&tcp_conns_slab, (void *)conn);
22322220
return NULL;
22332221
}
@@ -2688,7 +2676,7 @@ static void tcp_queue_recv_data(struct tcp *conn, struct net_pkt *pkt,
26882676
NET_DBG("[%p] Queuing data", conn);
26892677
}
26902678

2691-
if (!net_pkt_is_empty(conn->queue_recv_data)) {
2679+
if (conn->queue_recv_data != NULL) {
26922680
/* Place the data to correct place in the list. If the data
26932681
* would not be sequential, then drop this packet.
26942682
*
@@ -2718,9 +2706,9 @@ static void tcp_queue_recv_data(struct tcp *conn, struct net_pkt *pkt,
27182706
uint32_t end_offset;
27192707
size_t pending_len;
27202708

2721-
pending_seq = tcp_get_seq(conn->queue_recv_data->buffer);
2709+
pending_seq = tcp_get_seq(conn->queue_recv_data);
27222710
end_offset = seq - pending_seq;
2723-
pending_len = net_pkt_get_len(conn->queue_recv_data);
2711+
pending_len = net_buf_frags_len(conn->queue_recv_data);
27242712
if (end_offset < pending_len) {
27252713
if (end_offset < len) {
27262714
if (end_offset) {
@@ -2729,17 +2717,17 @@ static void tcp_queue_recv_data(struct tcp *conn, struct net_pkt *pkt,
27292717

27302718
/* Put new data before the pending data */
27312719
net_buf_frag_add(pkt->buffer,
2732-
conn->queue_recv_data->buffer);
2720+
conn->queue_recv_data);
27332721
NET_DBG("[%p] Adding at before queue, "
27342722
"end_offset %i, pending_len %zu",
27352723
conn, end_offset, pending_len);
2736-
conn->queue_recv_data->buffer = pkt->buffer;
2724+
conn->queue_recv_data = pkt->buffer;
27372725
inserted = true;
27382726
}
27392727
} else {
27402728
struct net_buf *last;
27412729

2742-
last = net_buf_frag_last(conn->queue_recv_data->buffer);
2730+
last = net_buf_frag_last(conn->queue_recv_data);
27432731
pending_seq = tcp_get_seq(last);
27442732

27452733
start_offset = pending_seq - seq_start;
@@ -2751,21 +2739,21 @@ static void tcp_queue_recv_data(struct tcp *conn, struct net_pkt *pkt,
27512739
/* The queued data is irrelevant since the new packet overlaps the
27522740
* new packet, take the new packet as contents
27532741
*/
2754-
net_buf_unref(conn->queue_recv_data->buffer);
2755-
conn->queue_recv_data->buffer = pkt->buffer;
2742+
net_buf_unref(conn->queue_recv_data);
2743+
conn->queue_recv_data = pkt->buffer;
27562744
inserted = true;
27572745
} else {
27582746
if (end_offset < len) {
27592747
if (end_offset) {
2760-
net_pkt_remove_tail(conn->queue_recv_data,
2761-
end_offset);
2748+
net_buf_remove_mem(conn->queue_recv_data,
2749+
end_offset);
27622750
}
27632751

27642752
/* Put new data after pending data */
27652753
NET_DBG("[%p] Adding at end of queue, "
27662754
"start %i, end %i, len %zu",
27672755
conn, start_offset, end_offset, len);
2768-
net_buf_frag_add(conn->queue_recv_data->buffer,
2756+
net_buf_frag_add(conn->queue_recv_data,
27692757
pkt->buffer);
27702758
inserted = true;
27712759
}
@@ -2774,18 +2762,18 @@ static void tcp_queue_recv_data(struct tcp *conn, struct net_pkt *pkt,
27742762

27752763
if (inserted) {
27762764
NET_DBG("[%p] All pending data", conn);
2777-
if (check_seq_list(conn->queue_recv_data->buffer) == false) {
2765+
if (check_seq_list(conn->queue_recv_data) == false) {
27782766
NET_ERR("Incorrect order in out of order sequence for conn %p",
27792767
conn);
27802768
/* error in sequence list, drop it */
2781-
net_buf_unref(conn->queue_recv_data->buffer);
2782-
conn->queue_recv_data->buffer = NULL;
2769+
net_buf_unref(conn->queue_recv_data);
2770+
conn->queue_recv_data = NULL;
27832771
}
27842772
} else {
27852773
NET_DBG("[%p] Cannot add new data to queue", conn);
27862774
}
27872775
} else {
2788-
net_pkt_append_buffer(conn->queue_recv_data, pkt->buffer);
2776+
conn->queue_recv_data = pkt->buffer;
27892777
inserted = true;
27902778
}
27912779

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)