You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2023/02/20 01:06:55 UTC

[nuttx] 02/12: Improvements in UDP connections allocation.

This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit 7f3591b9cc39ea8bbceb000eb4699534451fe48d
Author: Fotis Panagiotopoulos <f....@amco.gr>
AuthorDate: Thu Feb 2 16:20:55 2023 +0200

    Improvements in UDP connections allocation.
---
 .../sama5d3-xplained/configs/bridge/defconfig      |  2 +-
 .../arm/sama5/sama5d4-ek/configs/bridge/defconfig  |  2 +-
 boards/arm/stm32/viewtool-stm32f107/README.txt     |  2 +-
 include/nuttx/net/netconfig.h                      | 12 +----
 net/udp/Kconfig                                    | 41 +++++++++++++++--
 net/udp/udp_conn.c                                 | 51 +++++++++++++++++-----
 6 files changed, 81 insertions(+), 29 deletions(-)

diff --git a/boards/arm/sama5/sama5d3-xplained/configs/bridge/defconfig b/boards/arm/sama5/sama5d3-xplained/configs/bridge/defconfig
index d501178b58..aac7dd5c3e 100644
--- a/boards/arm/sama5/sama5d3-xplained/configs/bridge/defconfig
+++ b/boards/arm/sama5/sama5d3-xplained/configs/bridge/defconfig
@@ -42,7 +42,7 @@ CONFIG_NET_BROADCAST=y
 CONFIG_NET_ICMP=y
 CONFIG_NET_SOCKOPTS=y
 CONFIG_NET_UDP=y
-CONFIG_NET_UDP_CONNS=16
+CONFIG_NET_UDP_PREALLOC_CONNS=16
 CONFIG_PREALLOC_TIMERS=4
 CONFIG_RAM_SIZE=268435456
 CONFIG_RAM_START=0x20000000
diff --git a/boards/arm/sama5/sama5d4-ek/configs/bridge/defconfig b/boards/arm/sama5/sama5d4-ek/configs/bridge/defconfig
index 70e7b19beb..91c1d651b5 100644
--- a/boards/arm/sama5/sama5d4-ek/configs/bridge/defconfig
+++ b/boards/arm/sama5/sama5d4-ek/configs/bridge/defconfig
@@ -40,7 +40,7 @@ CONFIG_NET_BROADCAST=y
 CONFIG_NET_ICMP=y
 CONFIG_NET_SOCKOPTS=y
 CONFIG_NET_UDP=y
-CONFIG_NET_UDP_CONNS=16
+CONFIG_NET_UDP_PREALLOC_CONNS=16
 CONFIG_PREALLOC_TIMERS=4
 CONFIG_RAM_SIZE=268435456
 CONFIG_RAM_START=0x20000000
diff --git a/boards/arm/stm32/viewtool-stm32f107/README.txt b/boards/arm/stm32/viewtool-stm32f107/README.txt
index 0b1ca0b6a7..c0b25ea7b9 100644
--- a/boards/arm/stm32/viewtool-stm32f107/README.txt
+++ b/boards/arm/stm32/viewtool-stm32f107/README.txt
@@ -377,7 +377,7 @@ ViewTool DP83848 Ethernet Module
       CONFIG_NET_NTCP_READAHEAD_BUFFERS=8
 
       CONFIG_NET_UDP=y                       : UDP support
-      CONFIG_NET_UDP_CONNS=8
+      CONFIG_NET_UDP_PREALLOC_CONNS=8
 
       CONFIG_NET_ICMP=y                      : ICMP support
       CONFIG_NET_ICMP_SOCKET=y
diff --git a/include/nuttx/net/netconfig.h b/include/nuttx/net/netconfig.h
index 93e8e80cb8..732bc5d00f 100644
--- a/include/nuttx/net/netconfig.h
+++ b/include/nuttx/net/netconfig.h
@@ -288,16 +288,6 @@
 
 /* UDP configuration options */
 
-/* The maximum amount of concurrent UDP connection, Default: 10 */
-
-#ifndef CONFIG_NET_UDP_CONNS
-#  ifdef CONFIG_NET_UDP
-#    define CONFIG_NET_UDP_CONNS 10
-#  else
-#    define CONFIG_NET_UDP_CONNS  0
-#  endif
-#endif
-
 /* The UDP maximum packet size. This should not be set to more than
  * NETDEV_PKTSIZE(d) - NET_LL_HDRLEN(dev) - __UDP_HDRLEN - IPv*_HDRLEN.
  */
@@ -432,7 +422,7 @@
 
 #ifndef CONFIG_NET_NACTIVESOCKETS
 #  define CONFIG_NET_NACTIVESOCKETS (CONFIG_NET_TCP_PREALLOC_CONNS + \
-                                     CONFIG_NET_UDP_CONNS)
+                                     CONFIG_NET_UDP_PREALLOC_CONNS)
 #endif
 
 /* The initial retransmission timeout counted in timer pulses.
diff --git a/net/udp/Kconfig b/net/udp/Kconfig
index b2606e1fce..9239367396 100644
--- a/net/udp/Kconfig
+++ b/net/udp/Kconfig
@@ -36,11 +36,46 @@ config NET_UDP_CHECKSUMS
 		Enable/disable UDP checksum support.  UDP checksum support is
 		REQUIRED for IPv6.
 
-config NET_UDP_CONNS
-	int "Number of UDP sockets"
+config NET_UDP_PREALLOC_CONNS
+	int "Preallocated UDP sockets"
 	default 8
 	---help---
-		The maximum amount of open concurrent UDP sockets
+		Number of UDP 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_UDP_ALLOC_CONNS
+	int "Dynamic UDP connections allocation"
+	default 0
+	---help---
+		Dynamic memory allocations for UDP.
+
+		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_UDP_MAX_CONNS
+	int "Maximum number of UDP connections"
+	default 0
+	depends on NET_UDP_ALLOC_CONNS > 0
+	---help---
+		If dynamic connections allocation is selected (NET_UDP_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_UDP_NPOLLWAITERS
 	int "Number of UDP poll waiters"
diff --git a/net/udp/udp_conn.c b/net/udp/udp_conn.c
index 9051bb23c6..6b3cc628f7 100644
--- a/net/udp/udp_conn.c
+++ b/net/udp/udp_conn.c
@@ -76,8 +76,8 @@
 
 /* The array containing all UDP connections. */
 
-#ifndef CONFIG_NET_ALLOC_CONNS
-struct udp_conn_s g_udp_connections[CONFIG_NET_UDP_CONNS];
+#if CONFIG_NET_UDP_PREALLOC_CONNS > 0
+struct udp_conn_s g_udp_connections[CONFIG_NET_UDP_PREALLOC_CONNS];
 #endif
 
 /* A list of all free UDP connections */
@@ -462,7 +462,7 @@ static inline FAR struct udp_conn_s *
  *
  ****************************************************************************/
 
-#ifdef CONFIG_NET_ALLOC_CONNS
+#if CONFIG_NET_UDP_ALLOC_CONNS > 0
 FAR struct udp_conn_s *udp_alloc_conn(void)
 {
   FAR struct udp_conn_s *conn;
@@ -472,8 +472,16 @@ FAR struct udp_conn_s *udp_alloc_conn(void)
 
   if (dq_peek(&g_free_udp_connections) == NULL)
     {
+#if CONFIG_NET_UDP_MAX_CONNS > 0
+      if (dq_count(&g_active_udp_connections) + CONFIG_NET_UDP_ALLOC_CONNS
+          >= CONFIG_NET_UDP_MAX_CONNS)
+        {
+          return NULL;
+        }
+#endif
+
       conn = kmm_zalloc(sizeof(struct udp_conn_s) *
-                        CONFIG_NET_UDP_CONNS);
+                        CONFIG_NET_UDP_ALLOC_CONNS);
       if (conn == NULL)
         {
           return conn;
@@ -481,7 +489,7 @@ FAR struct udp_conn_s *udp_alloc_conn(void)
 
       /* Now initialize each connection structure */
 
-      for (i = 0; i < CONFIG_NET_UDP_CONNS; i++)
+      for (i = 0; i < CONFIG_NET_UDP_ALLOC_CONNS; i++)
         {
           /* Mark the connection closed and move it to the free list */
 
@@ -585,10 +593,10 @@ uint16_t udp_select_port(uint8_t domain, FAR union ip_binding_u *u)
 
 void udp_initialize(void)
 {
-#ifndef CONFIG_NET_ALLOC_CONNS
+#if CONFIG_NET_UDP_PREALLOC_CONNS > 0
   int i;
 
-  for (i = 0; i < CONFIG_NET_UDP_CONNS; i++)
+  for (i = 0; i < CONFIG_NET_UDP_PREALLOC_CONNS; i++)
     {
       /* Mark the connection closed and move it to the free list */
 
@@ -614,11 +622,16 @@ FAR struct udp_conn_s *udp_alloc(uint8_t domain)
   /* The free list is protected by a mutex. */
 
   nxmutex_lock(&g_free_lock);
-#ifndef CONFIG_NET_ALLOC_CONNS
+
   conn = (FAR struct udp_conn_s *)dq_remfirst(&g_free_udp_connections);
-#else
-  conn = udp_alloc_conn();
+
+#if CONFIG_NET_UDP_ALLOC_CONNS > 0
+  if (conn == NULL)
+    {
+      conn = udp_alloc_conn();
+    }
 #endif
+
   if (conn)
     {
       /* Make sure that the connection is marked as uninitialized */
@@ -703,9 +716,23 @@ void udp_free(FAR struct udp_conn_s *conn)
 
   memset(conn, 0, sizeof(*conn));
 
-  /* Free the connection */
+  /* Free the connection.
+   * If this is a preallocated or a batch allocated connection store it in
+   * the free connections list. Else free it.
+   */
+
+#if CONFIG_NET_UDP_ALLOC_CONNS == 1
+  if (conn < g_udp_connections || conn >= (g_udp_connections +
+      CONFIG_NET_UDP_PREALLOC_CONNS))
+    {
+      kmm_free(conn);
+    }
+  else
+#endif
+    {
+      dq_addlast(&conn->sconn.node, &g_free_udp_connections);
+    }
 
-  dq_addlast(&conn->sconn.node, &g_free_udp_connections);
   nxmutex_unlock(&g_free_lock);
 }