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(); }