Improvements in TCP connections allocation.

This commit is contained in:
Fotis Panagiotopoulos
2022-11-04 12:38:07 +02:00
committed by Xiang Xiao
parent 7d3a9b1cbc
commit 8f9dfe0be1
51 changed files with 128 additions and 78 deletions
+38 -3
View File
@@ -50,11 +50,46 @@ config NET_TCPURGDATA
compiled in. Urgent data (out-of-band data) is a rarely used TCP feature
that is very seldom would be required.
config NET_TCP_CONNS
int "Number of TCP/IP connections"
config NET_TCP_PREALLOC_CONNS
int "Preallocated TCP/IP connections"
default 8
---help---
Maximum number of TCP/IP connections (all tasks)
Number of TCP/IP connections (all tasks).
This number of connections will be pre-allocated during system boot.
If dynamic connections allocation is enabled, more connections may
be allocated at a later time, as the system needs them. Else this
will be the maximum number of connections available to the system
at all times.
Set to 0 to disable (and rely only on dynamic allocations).
config NET_TCP_ALLOC_CONNS
int "Dynamic TCP/IP connections allocation"
default 0
---help---
Dynamic memory allocations for TCP/IP.
When set to 0 all dynamic allocations are disabled.
When set to 1 a new connection will be allocated every time,
and it will be free'd when no longer needed.
Setting this to 2 or more will allocate the connections in
batches (with batch size equal to this config). When a
connection is no longer needed, it will be returned to the
free connections pool, and it will never be deallocated!
config NET_TCP_MAX_CONNS
int "Maximum number of TCP/IP connections"
default 0
depends on NET_TCP_ALLOC_CONNS > 0
---help---
If dynamic connections allocation is selected (NET_TCP_ALLOC_CONNS > 0)
this will limit the number of connections that can be allocated.
This is useful in case the system is under very heavy load (or
under attack), ensuring that the heap will not be exhausted.
config NET_TCP_NPOLLWAITERS
int "Number of TCP poll waiters"
+40 -11
View File
@@ -76,8 +76,8 @@
/* The array containing all TCP connections. */
#ifndef CONFIG_NET_ALLOC_CONNS
static struct tcp_conn_s g_tcp_connections[CONFIG_NET_TCP_CONNS];
#if CONFIG_NET_TCP_PREALLOC_CONNS > 0
static struct tcp_conn_s g_tcp_connections[CONFIG_NET_TCP_PREALLOC_CONNS];
#endif
/* A list of all free TCP connections */
@@ -439,7 +439,7 @@ static inline int tcp_ipv6_bind(FAR struct tcp_conn_s *conn,
*
****************************************************************************/
#ifdef CONFIG_NET_ALLOC_CONNS
#if CONFIG_NET_TCP_ALLOC_CONNS > 0
FAR struct tcp_conn_s *tcp_alloc_conn(void)
{
FAR struct tcp_conn_s *conn;
@@ -449,8 +449,16 @@ FAR struct tcp_conn_s *tcp_alloc_conn(void)
if (dq_peek(&g_free_tcp_connections) == NULL)
{
#if CONFIG_NET_TCP_MAX_CONNS > 0
if (dq_count(&g_active_tcp_connections) + CONFIG_NET_TCP_ALLOC_CONNS
>= CONFIG_NET_TCP_MAX_CONNS)
{
return NULL;
}
#endif
conn = kmm_zalloc(sizeof(struct tcp_conn_s) *
CONFIG_NET_TCP_CONNS);
CONFIG_NET_TCP_ALLOC_CONNS);
if (conn == NULL)
{
return conn;
@@ -458,7 +466,7 @@ FAR struct tcp_conn_s *tcp_alloc_conn(void)
/* Now initialize each connection structure */
for (i = 0; i < CONFIG_NET_TCP_CONNS; i++)
for (i = 0; i < CONFIG_NET_TCP_ALLOC_CONNS; i++)
{
/* Mark the connection closed and move it to the free list */
@@ -597,10 +605,10 @@ int tcp_selectport(uint8_t domain,
void tcp_initialize(void)
{
#ifndef CONFIG_NET_ALLOC_CONNS
#if CONFIG_NET_TCP_PREALLOC_CONNS > 0
int i;
for (i = 0; i < CONFIG_NET_TCP_CONNS; i++)
for (i = 0; i < CONFIG_NET_TCP_PREALLOC_CONNS; i++)
{
/* Mark the connection closed and move it to the free list */
@@ -700,7 +708,12 @@ FAR struct tcp_conn_s *tcp_alloc(uint8_t domain)
tcp_free(conn);
/* Now there is guaranteed to be one free connection. Get it! */
/* Now there should be one free connection. If dynamic connections
* allocation is disabled, it is guaranteed so. In case that
* dynamic connections are used, it may be already in the free
* list, or at least there should be enough space in the heap for
* a new connection.
*/
conn = (FAR struct tcp_conn_s *)
dq_remfirst(&g_free_tcp_connections);
@@ -710,7 +723,7 @@ FAR struct tcp_conn_s *tcp_alloc(uint8_t domain)
/* Allocate the connect entry from heap */
#ifdef CONFIG_NET_ALLOC_CONNS
#if CONFIG_NET_TCP_ALLOC_CONNS > 0
if (conn == NULL)
{
conn = tcp_alloc_conn();
@@ -876,10 +889,26 @@ void tcp_free(FAR struct tcp_conn_s *conn)
}
#endif
/* Mark the connection available and put it into the free list */
/* Mark the connection available. */
conn->tcpstateflags = TCP_CLOSED;
dq_addlast(&conn->sconn.node, &g_free_tcp_connections);
/* If this is a preallocated or a batch allocated connection store it in
* the free connections list. Else free it.
*/
#if CONFIG_NET_TCP_ALLOC_CONNS == 1
if (conn < g_tcp_connections || conn >= (g_tcp_connections +
CONFIG_NET_TCP_PREALLOC_CONNS))
{
kmm_free(conn);
}
else
#endif
{
dq_addlast(&conn->sconn.node, &g_free_tcp_connections);
}
net_unlock();
}