Improvements in CAN connections allocation.

This commit is contained in:
Fotis Panagiotopoulos 2023-02-13 19:15:37 +02:00 committed by Xiang Xiao
parent 9b4d784307
commit b5b7d24ba1
3 changed files with 71 additions and 14 deletions

View File

@ -25,7 +25,7 @@ CONFIG_BOARD_LOOPSPERMSEC=43103
CONFIG_BUILTIN=y
CONFIG_CANUTILS_CANDUMP=y
CONFIG_CANUTILS_CANSEND=y
CONFIG_CAN_CONNS=2
CONFIG_CAN_PREALLOC_CONNS=2
CONFIG_DEBUG_ERROR=y
CONFIG_DEBUG_FEATURES=y
CONFIG_DEBUG_INFO=y

View File

@ -30,11 +30,46 @@ config NET_CAN_HAVE_ERRORS
bool
default n
config CAN_CONNS
int "Max number of CAN socket connections"
config CAN_PREALLOC_CONNS
int "Preallocated CAN socket connections"
default 4
---help---
Maximum number of CAN connections (all tasks).
Number of CAN 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 CAN_ALLOC_CONNS
int "Dynamic CAN connections allocation"
default 0
---help---
Dynamic memory allocations for CAN.
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 CAN_MAX_CONNS
int "Maximum number of CAN connections"
default 0
depends on CAN_ALLOC_CONNS > 0
---help---
If dynamic connections allocation is selected (CAN_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_CAN_EXTID
bool "Enable CAN extended IDs"

View File

@ -49,8 +49,8 @@
/* The array containing all NetLink connections. */
#ifndef CONFIG_NET_ALLOC_CONNS
static struct can_conn_s g_can_connections[CONFIG_CAN_CONNS];
#if CONFIG_CAN_PREALLOC_CONNS > 0
static struct can_conn_s g_can_connections[CONFIG_CAN_PREALLOC_CONNS];
#endif
/* A list of all free NetLink connections */
@ -77,10 +77,10 @@ static dq_queue_t g_active_can_connections;
void can_initialize(void)
{
#ifndef CONFIG_NET_ALLOC_CONNS
#if CONFIG_CAN_PREALLOC_CONNS > 0
int i;
for (i = 0; i < CONFIG_CAN_CONNS; i++)
for (i = 0; i < CONFIG_CAN_PREALLOC_CONNS; i++)
{
/* Mark the connection closed and move it to the free list */
@ -101,20 +101,29 @@ void can_initialize(void)
FAR struct can_conn_s *can_alloc(void)
{
FAR struct can_conn_s *conn;
#ifdef CONFIG_NET_ALLOC_CONNS
#if CONFIG_CAN_ALLOC_CONNS > 0
int i;
#endif
/* The free list is protected by a a mutex. */
nxmutex_lock(&g_free_lock);
#ifdef CONFIG_NET_ALLOC_CONNS
#if CONFIG_CAN_ALLOC_CONNS > 0
if (dq_peek(&g_free_can_connections) == NULL)
{
conn = kmm_zalloc(sizeof(*conn) * CONFIG_CAN_CONNS);
#if CONFIG_CAN_MAX_CONNS > 0
if (dq_count(&g_active_can_connections) + CONFIG_CAN_ALLOC_CONNS
>= CONFIG_CAN_MAX_CONNS)
{
nxmutex_unlock(&g_free_lock);
return NULL;
}
#endif
conn = kmm_zalloc(sizeof(*conn) * CONFIG_CAN_ALLOC_CONNS);
if (conn != NULL)
{
for (i = 0; i < CONFIG_CAN_CONNS; i++)
for (i = 0; i < CONFIG_CAN_ALLOC_CONNS; i++)
{
dq_addlast(&conn[i].sconn.node, &g_free_can_connections);
}
@ -177,9 +186,22 @@ void can_free(FAR struct can_conn_s *conn)
memset(conn, 0, sizeof(*conn));
/* 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_CAN_ALLOC_CONNS == 1
if (conn < g_can_connections || conn >= (g_can_connections +
CONFIG_CAN_PREALLOC_CONNS))
{
kmm_free(conn);
}
else
#endif
{
dq_addlast(&conn->sconn.node, &g_free_can_connections);
}
dq_addlast(&conn->sconn.node, &g_free_can_connections);
nxmutex_unlock(&g_free_lock);
}