Skip to content

Commit eda76ad

Browse files
rluboshenrikbrixandersen
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]>
1 parent b8c7984 commit eda76ad

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
@@ -866,7 +866,9 @@ static void tcp_conn_release(struct k_work *work)
866866
tcp_send_queue_flush(conn);
867867

868868
(void)k_work_cancel_delayable(&conn->send_data_timer);
869-
tcp_pkt_unref(conn->send_data);
869+
if (conn->send_data.frags != NULL) {
870+
net_pkt_frag_unref(conn->send_data.frags);
871+
}
870872

871873
if (CONFIG_NET_TCP_RECV_QUEUE_TIMEOUT) {
872874
if (conn->queue_recv_data != NULL) {
@@ -1815,7 +1817,7 @@ static int tcp_send_data(struct tcp *conn)
18151817
goto out;
18161818
}
18171819

1818-
ret = tcp_pkt_peek(pkt, conn->send_data, conn->unacked_len, len);
1820+
ret = tcp_pkt_peek(pkt, &conn->send_data, conn->unacked_len, len);
18191821
if (ret < 0) {
18201822
tcp_pkt_unref(pkt);
18211823
ret = -ENOBUFS;
@@ -2155,12 +2157,7 @@ static struct tcp *tcp_conn_alloc(void)
21552157
}
21562158

21572159
memset(conn, 0, sizeof(*conn));
2158-
2159-
conn->send_data = tcp_pkt_alloc(conn, 0);
2160-
if (conn->send_data == NULL) {
2161-
NET_ERR("Cannot allocate %s queue for conn %p", "send", conn);
2162-
goto fail;
2163-
}
2160+
net_pkt_tx_init(&conn->send_data);
21642161

21652162
atomic_clear(&conn->backlog);
21662163

@@ -2214,10 +2211,6 @@ static struct tcp *tcp_conn_alloc(void)
22142211
NET_DBG("[%p] Allocated", conn);
22152212

22162213
return conn;
2217-
2218-
fail:
2219-
k_mem_slab_free(&tcp_conns_slab, (void *)conn);
2220-
return NULL;
22212214
}
22222215

22232216
int net_tcp_get(struct net_context *context)
@@ -3304,7 +3297,7 @@ static enum net_verdict tcp_in(struct tcp *conn, struct net_pkt *pkt)
33043297
NET_DBG("[%p] len_acked=%u", conn, len_acked);
33053298

33063299
if ((conn->send_data_total < len_acked) ||
3307-
(tcp_pkt_pull(conn->send_data,
3300+
(tcp_pkt_pull(&conn->send_data,
33083301
len_acked) < 0)) {
33093302
NET_ERR("[%p] Invalid len_acked=%u "
33103303
"(total=%zu)", conn, len_acked,
@@ -3815,7 +3808,7 @@ int net_tcp_queue(struct net_context *context, const void *data, size_t len,
38153808
for (int i = 0; i < msg->msg_iovlen; i++) {
38163809
int iovlen = MIN(msg->msg_iov[i].iov_len, len);
38173810

3818-
ret = tcp_pkt_append(conn->send_data,
3811+
ret = tcp_pkt_append(&conn->send_data,
38193812
msg->msg_iov[i].iov_base,
38203813
iovlen);
38213814
if (ret < 0) {
@@ -3834,7 +3827,7 @@ int net_tcp_queue(struct net_context *context, const void *data, size_t len,
38343827
}
38353828
}
38363829
} else {
3837-
ret = tcp_pkt_append(conn->send_data, data, len);
3830+
ret = tcp_pkt_append(&conn->send_data, data, len);
38383831
if (ret < 0) {
38393832
goto out;
38403833
}

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("[%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("[%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)