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 c5cc70a8b176680ffcbcd0ee6a5f4d1ef687c372
Author: Fotis Panagiotopoulos <f.pa...@amco.gr>
AuthorDate: Sat Feb 11 16:50:03 2023 +0200

    Improvements in Bluetooth connections allocation.
---
 net/bluetooth/Kconfig          | 41 +++++++++++++++++++++++++++++++++++++++--
 net/bluetooth/bluetooth_conn.c | 42 +++++++++++++++++++++++++++++++-----------
 2 files changed, 70 insertions(+), 13 deletions(-)

diff --git a/net/bluetooth/Kconfig b/net/bluetooth/Kconfig
index 65e8e5d804..768a6396da 100644
--- a/net/bluetooth/Kconfig
+++ b/net/bluetooth/Kconfig
@@ -22,9 +22,46 @@ config NET_BLUETOOTH
 
 if NET_BLUETOOTH
 
-config NET_BLUETOOTH_NCONNS
-       int "Max Bluetooth sockets"
+config NET_BLUETOOTH_PREALLOC_CONNS
+       int "Preallocated Bluetooth sockets"
        default 4
+       ---help---
+               Number of Bluetooth 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_BLUETOOTH_ALLOC_CONNS
+       int "Dynamic Bluetooth connections allocation"
+       default 0
+       ---help---
+               Dynamic memory allocations for Bluetooth.
+
+               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_BLUETOOTH_MAX_CONNS
+       int "Maximum number of Bluetooth connections"
+       default 0
+       depends on NET_BLUETOOTH_ALLOC_CONNS > 0
+       ---help---
+               If dynamic connections allocation is selected 
(NET_BLUETOOTH_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_BLUETOOTH_NCONTAINERS
        int "Number of pre-allocated frame containers"
diff --git a/net/bluetooth/bluetooth_conn.c b/net/bluetooth/bluetooth_conn.c
index d5c086fb82..9851710d9b 100644
--- a/net/bluetooth/bluetooth_conn.c
+++ b/net/bluetooth/bluetooth_conn.c
@@ -52,9 +52,9 @@
  * network lock.
  */
 
-#ifndef CONFIG_NET_ALLOC_CONNS
+#if CONFIG_NET_BLUETOOTH_PREALLOC_CONNS > 0
 static struct bluetooth_conn_s
-  g_bluetooth_connections[CONFIG_NET_BLUETOOTH_NCONNS];
+  g_bluetooth_connections[CONFIG_NET_BLUETOOTH_PREALLOC_CONNS];
 #endif
 
 /* A list of all free packet socket connections */
@@ -88,10 +88,10 @@ static const bt_addr_t g_any_addr =
 
 void bluetooth_conn_initialize(void)
 {
-#ifndef CONFIG_NET_ALLOC_CONNS
+#if CONFIG_NET_BLUETOOTH_PREALLOC_CONNS > 0
   int i;
 
-  for (i = 0; i < CONFIG_NET_BLUETOOTH_NCONNS; i++)
+  for (i = 0; i < CONFIG_NET_BLUETOOTH_PREALLOC_CONNS; i++)
     {
       /* Link each pre-allocated connection structure into the free list. */
 
@@ -113,20 +113,29 @@ void bluetooth_conn_initialize(void)
 FAR struct bluetooth_conn_s *bluetooth_conn_alloc(void)
 {
   FAR struct bluetooth_conn_s *conn;
-#ifdef CONFIG_NET_ALLOC_CONNS
+#if CONFIG_NET_BLUETOOTH_ALLOC_CONNS > 0
   int i;
 #endif
 
   /* The free list is protected by the network lock */
 
   net_lock();
-#ifdef CONFIG_NET_ALLOC_CONNS
+#if CONFIG_NET_BLUETOOTH_ALLOC_CONNS > 0
   if (dq_peek(&g_active_bluetooth_connections) == NULL)
     {
-      conn = kmm_zalloc(sizeof(*conn) * CONFIG_NET_BLUETOOTH_NCONNS);
+#if CONFIG_NET_BLUETOOTH_MAX_CONNS > 0
+      if (dq_count(&g_active_bluetooth_connections) +
+          CONFIG_NET_BLUETOOTH_ALLOC_CONNS >= CONFIG_NET_BLUETOOTH_MAX_CONNS)
+        {
+          net_unlock();
+          return NULL;
+        }
+#endif
+
+      conn = kmm_zalloc(sizeof(*conn) * CONFIG_NET_BLUETOOTH_ALLOC_CONNS);
       if (conn != NULL)
         {
-          for (i = 0; i < CONFIG_NET_BLUETOOTH_NCONNS; i++)
+          for (i = 0; i < CONFIG_NET_BLUETOOTH_ALLOC_CONNS; i++)
             {
               dq_addlast(&conn[i].bc_conn.node,
                          &g_active_bluetooth_connections);
@@ -200,9 +209,20 @@ void bluetooth_conn_free(FAR struct bluetooth_conn_s *conn)
 
   memset(conn, 0, sizeof(*conn));
 
-  /* Free the connection */
-
-  dq_addlast(&conn->bc_conn.node, &g_free_bluetooth_connections);
+  /* If this is a preallocated or a batch allocated connection store it in
+   * the free connections list. Else free it.
+   */
+#if CONFIG_NET_BLUETOOTH_ALLOC_CONNS == 1
+  if (conn < g_bluetooth_connections || conn >= (g_bluetooth_connections +
+      CONFIG_NET_BLUETOOTH_PREALLOC_CONNS))
+    {
+      kmm_free(conn);
+    }
+  else
+#endif
+    {
+      dq_addlast(&conn->bc_conn.node, &g_free_bluetooth_connections);
+    }
 
   net_unlock();
 }

Reply via email to