Skip to content

Commit 87b0639

Browse files
rlubosdkalowsk
authored andcommitted
net: tcp: Preallocate TX packet for TCP context
TCP context cannot operate w/o a TX packet for buffering transmitted data. So far this net_pkt was allocated at runtime from the common packet pool, but this created some not-obvious memory requirement on TCP and could lead to TX packet starvation in case many TCP connections are open in parallel. Therefore, allocate this packet structure statically, as a part of the TCP context instead. This increases the memory requirement of the TCP context by ~64 bytes, however if that's a concern for the application, the maximum number of TX packets can be lowered instead. In return, we get a clear separation between the number of TCP connections opened, and the amount of packets that can be transmitted. Signed-off-by: Robert Lubos <[email protected]> (cherry picked from commit eda76ad)
1 parent 9800d46 commit 87b0639

File tree

2 files changed

+10
-17
lines changed

2 files changed

+10
-17
lines changed

subsys/net/ip/tcp.c

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -794,7 +794,9 @@ static void tcp_conn_release(struct k_work *work)
794794
tcp_send_queue_flush(conn);
795795

796796
(void)k_work_cancel_delayable(&conn->send_data_timer);
797-
tcp_pkt_unref(conn->send_data);
797+
if (conn->send_data.frags != NULL) {
798+
net_pkt_frag_unref(conn->send_data.frags);
799+
}
798800

799801
if (CONFIG_NET_TCP_RECV_QUEUE_TIMEOUT) {
800802
if (conn->queue_recv_data != NULL) {
@@ -1686,7 +1688,7 @@ static int tcp_send_data(struct tcp *conn)
16861688
goto out;
16871689
}
16881690

1689-
ret = tcp_pkt_peek(pkt, conn->send_data, conn->unacked_len, len);
1691+
ret = tcp_pkt_peek(pkt, &conn->send_data, conn->unacked_len, len);
16901692
if (ret < 0) {
16911693
tcp_pkt_unref(pkt);
16921694
ret = -ENOBUFS;
@@ -2023,12 +2025,7 @@ static struct tcp *tcp_conn_alloc(void)
20232025
}
20242026

20252027
memset(conn, 0, sizeof(*conn));
2026-
2027-
conn->send_data = tcp_pkt_alloc(conn, 0);
2028-
if (conn->send_data == NULL) {
2029-
NET_ERR("Cannot allocate %s queue for conn %p", "send", conn);
2030-
goto fail;
2031-
}
2028+
net_pkt_tx_init(&conn->send_data);
20322029

20332030
k_mutex_init(&conn->lock);
20342031
k_fifo_init(&conn->recv_data);
@@ -2080,10 +2077,6 @@ static struct tcp *tcp_conn_alloc(void)
20802077
NET_DBG("conn: %p", conn);
20812078

20822079
return conn;
2083-
2084-
fail:
2085-
k_mem_slab_free(&tcp_conns_slab, (void *)conn);
2086-
return NULL;
20872080
}
20882081

20892082
int net_tcp_get(struct net_context *context)
@@ -3153,7 +3146,7 @@ static enum net_verdict tcp_in(struct tcp *conn, struct net_pkt *pkt)
31533146
NET_DBG("conn: %p len_acked=%u", conn, len_acked);
31543147

31553148
if ((conn->send_data_total < len_acked) ||
3156-
(tcp_pkt_pull(conn->send_data,
3149+
(tcp_pkt_pull(&conn->send_data,
31573150
len_acked) < 0)) {
31583151
NET_ERR("conn: %p, Invalid len_acked=%u "
31593152
"(total=%zu)", conn, len_acked,
@@ -3642,7 +3635,7 @@ int net_tcp_queue(struct net_context *context, const void *data, size_t len,
36423635
for (int i = 0; i < msg->msg_iovlen; i++) {
36433636
int iovlen = MIN(msg->msg_iov[i].iov_len, len);
36443637

3645-
ret = tcp_pkt_append(conn->send_data,
3638+
ret = tcp_pkt_append(&conn->send_data,
36463639
msg->msg_iov[i].iov_base,
36473640
iovlen);
36483641
if (ret < 0) {
@@ -3661,7 +3654,7 @@ int net_tcp_queue(struct net_context *context, const void *data, size_t len,
36613654
}
36623655
}
36633656
} else {
3664-
ret = tcp_pkt_append(conn->send_data, data, len);
3657+
ret = tcp_pkt_append(&conn->send_data, data, len);
36653658
if (ret < 0) {
36663659
goto out;
36673660
}

subsys/net/ip/tcp_private.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@
149149
({ \
150150
NET_DBG("conn: %p total=%zd, unacked_len=%d, " \
151151
"send_win=%hu, mss=%hu", \
152-
(_conn), net_pkt_get_len((_conn)->send_data), \
152+
(_conn), net_pkt_get_len(&(_conn)->send_data), \
153153
_conn->unacked_len, _conn->send_win, \
154154
(uint16_t)conn_mss((_conn))); \
155155
NET_DBG("conn: %p send_data_timer=%hu, send_data_retries=%hu", \
@@ -258,7 +258,7 @@ typedef void (*net_tcp_closed_cb_t)(struct tcp *conn, void *user_data);
258258
struct tcp { /* TCP connection */
259259
sys_snode_t next;
260260
struct net_context *context;
261-
struct net_pkt *send_data;
261+
struct net_pkt send_data;
262262
struct net_buf *queue_recv_data;
263263
struct net_if *iface;
264264
void *recv_user_data;

0 commit comments

Comments
 (0)