Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

net: Add buffer pool to replace connection allocation #15285

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 17 additions & 62 deletions net/bluetooth/bluetooth_conn.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,19 @@
#include <nuttx/net/bluetooth.h>

#include "devif/devif.h"
#include "utils/utils.h"
#include "bluetooth/bluetooth.h"

#ifdef CONFIG_NET_BLUETOOTH

/****************************************************************************
* Pre-processor Definitions
****************************************************************************/

#ifndef CONFIG_NET_BLUETOOTH_MAX_CONNS
# define CONFIG_NET_BLUETOOTH_MAX_CONNS 0
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@wengzhe why to use 0 as max connections? Please for logic reasoning use 1 and later in your logic operation decrease 1

#endif

/****************************************************************************
* Private Data
****************************************************************************/
Expand All @@ -54,14 +63,10 @@
* network lock.
*/

#if CONFIG_NET_BLUETOOTH_PREALLOC_CONNS > 0
static struct bluetooth_conn_s
g_bluetooth_connections[CONFIG_NET_BLUETOOTH_PREALLOC_CONNS];
#endif

/* A list of all free packet socket connections */

static dq_queue_t g_free_bluetooth_connections;
NET_BUFPOOL_DECLARE(g_bluetooth_connections, sizeof(struct bluetooth_conn_s),
CONFIG_NET_BLUETOOTH_PREALLOC_CONNS,
CONFIG_NET_BLUETOOTH_ALLOC_CONNS,
CONFIG_NET_BLUETOOTH_MAX_CONNS);

/* A list of all allocated packet socket connections */

Expand Down Expand Up @@ -90,17 +95,7 @@ static const bt_addr_t g_any_addr =

void bluetooth_conn_initialize(void)
{
#if CONFIG_NET_BLUETOOTH_PREALLOC_CONNS > 0
int i;

for (i = 0; i < CONFIG_NET_BLUETOOTH_PREALLOC_CONNS; i++)
{
/* Link each pre-allocated connection structure into the free list. */

dq_addlast(&g_bluetooth_connections[i].bc_conn.node,
&g_free_bluetooth_connections);
}
#endif
NET_BUFPOOL_INIT(g_bluetooth_connections);
}

/****************************************************************************
Expand All @@ -115,39 +110,12 @@ void bluetooth_conn_initialize(void)
FAR struct bluetooth_conn_s *bluetooth_conn_alloc(void)
{
FAR struct bluetooth_conn_s *conn;
#if CONFIG_NET_BLUETOOTH_ALLOC_CONNS > 0
int i;
#endif

/* The free list is protected by the network lock */

net_lock();
#if CONFIG_NET_BLUETOOTH_ALLOC_CONNS > 0
if (dq_peek(&g_active_bluetooth_connections) == NULL)
{
#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_ALLOC_CONNS; i++)
{
dq_addlast(&conn[i].bc_conn.node,
&g_active_bluetooth_connections);
}
}
}
#endif

conn = (FAR struct bluetooth_conn_s *)
dq_remfirst(&g_free_bluetooth_connections);
conn = NET_BUFPOOL_TRYALLOC(g_bluetooth_connections);
if (conn)
{
/* Mark as unbound */
Expand Down Expand Up @@ -207,22 +175,9 @@ void bluetooth_conn_free(FAR struct bluetooth_conn_s *conn)
bluetooth_container_free(container);
}

/* If this is a preallocated or a batch allocated connection store it in
* the free connections list. Else free it.
*/
/* Free the connection structure */

#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
{
memset(conn, 0, sizeof(*conn));
dq_addlast(&conn->bc_conn.node, &g_free_bluetooth_connections);
}
NET_BUFPOOL_FREE(g_bluetooth_connections, conn);

net_unlock();
}
Expand Down
73 changes: 15 additions & 58 deletions net/can/can_conn.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,18 +46,22 @@
#ifdef CONFIG_NET_CAN

/****************************************************************************
* Private Data
* Pre-processor Definitions
****************************************************************************/

/* The array containing all NetLink connections. */

#if CONFIG_CAN_PREALLOC_CONNS > 0
static struct can_conn_s g_can_connections[CONFIG_CAN_PREALLOC_CONNS];
#ifndef CONFIG_CAN_MAX_CONNS
# define CONFIG_CAN_MAX_CONNS 0
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto

#endif

/* A list of all free NetLink connections */
/****************************************************************************
* Private Data
****************************************************************************/

/* The array containing all NetLink connections. */

static dq_queue_t g_free_can_connections;
NET_BUFPOOL_DECLARE(g_can_connections, sizeof(struct can_conn_s),
CONFIG_CAN_PREALLOC_CONNS, CONFIG_CAN_ALLOC_CONNS,
CONFIG_CAN_MAX_CONNS);
static mutex_t g_free_lock = NXMUTEX_INITIALIZER;

/* A list of all allocated NetLink connections */
Expand All @@ -79,16 +83,7 @@ static dq_queue_t g_active_can_connections;

void can_initialize(void)
{
#if CONFIG_CAN_PREALLOC_CONNS > 0
int i;

for (i = 0; i < CONFIG_CAN_PREALLOC_CONNS; i++)
{
/* Mark the connection closed and move it to the free list */

dq_addlast(&g_can_connections[i].sconn.node, &g_free_can_connections);
}
#endif
NET_BUFPOOL_INIT(g_can_connections);
}

/****************************************************************************
Expand All @@ -103,37 +98,12 @@ void can_initialize(void)
FAR struct can_conn_s *can_alloc(void)
{
FAR struct can_conn_s *conn;
#if CONFIG_CAN_ALLOC_CONNS > 0
int i;
#endif

/* The free list is protected by a a mutex. */

nxmutex_lock(&g_free_lock);
#if CONFIG_CAN_ALLOC_CONNS > 0
if (dq_peek(&g_free_can_connections) == NULL)
{
#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_ALLOC_CONNS; i++)
{
dq_addlast(&conn[i].sconn.node, &g_free_can_connections);
}
}
}
#endif

conn = (FAR struct can_conn_s *)dq_remfirst(&g_free_can_connections);
conn = NET_BUFPOOL_TRYALLOC(g_can_connections);
if (conn != NULL)
{
/* FIXME SocketCAN default behavior enables loopback */
Expand Down Expand Up @@ -184,22 +154,9 @@ void can_free(FAR struct can_conn_s *conn)

dq_rem(&conn->sconn.node, &g_active_can_connections);

/* If this is a preallocated or a batch allocated connection store it in
* the free connections list. Else free it.
*/
/* Free the connection. */

#if CONFIG_CAN_ALLOC_CONNS == 1
if (conn < g_can_connections || conn >= (g_can_connections +
CONFIG_CAN_PREALLOC_CONNS))
{
kmm_free(conn);
}
else
#endif
{
memset(conn, 0, sizeof(*conn));
dq_addlast(&conn->sconn.node, &g_free_can_connections);
}
NET_BUFPOOL_FREE(g_can_connections, conn);

nxmutex_unlock(&g_free_lock);
}
Expand Down
69 changes: 10 additions & 59 deletions net/devif/devif_callback.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
#include <nuttx/net/netdev.h>

#include "netdev/netdev.h"
#include "utils/utils.h"
#include "devif/devif.h"

/****************************************************************************
Expand All @@ -52,11 +53,9 @@
* Private Data
****************************************************************************/

#if CONFIG_NET_PREALLOC_DEVIF_CALLBACKS > 0
static struct devif_callback_s
g_cbprealloc[CONFIG_NET_PREALLOC_DEVIF_CALLBACKS];
#endif
static FAR struct devif_callback_s *g_cbfreelist = NULL;
NET_BUFPOOL_DECLARE(g_cbprealloc, sizeof(struct devif_callback_s),
CONFIG_NET_PREALLOC_DEVIF_CALLBACKS,
CONFIG_NET_ALLOC_DEVIF_CALLBACKS, 0);

/****************************************************************************
* Private Functions
Expand Down Expand Up @@ -88,7 +87,7 @@ static void devif_callback_free(FAR struct net_driver_s *dev,
#ifdef CONFIG_DEBUG_FEATURES
/* Check for double freed callbacks */

curr = g_cbfreelist;
curr = (FAR struct devif_callback_s *)g_cbprealloc.freebuffers.head;

while (curr != NULL)
{
Expand Down Expand Up @@ -187,23 +186,9 @@ static void devif_callback_free(FAR struct net_driver_s *dev,
}
}

/* If this is a preallocated or a batch allocated callback store it in
* the free callbacks list. Else free it.
*/
/* Free the callback structure */

#if CONFIG_NET_ALLOC_DEVIF_CALLBACKS == 1
if (cb < g_cbprealloc || cb >= (g_cbprealloc +
CONFIG_NET_PREALLOC_DEVIF_CALLBACKS))
{
kmm_free(cb);
}
else
#endif
{
cb->nxtconn = g_cbfreelist;
cb->nxtdev = NULL;
g_cbfreelist = cb;
}
NET_BUFPOOL_FREE(g_cbprealloc, cb);

net_unlock();
}
Expand Down Expand Up @@ -266,15 +251,7 @@ static bool devif_event_trigger(uint16_t events, uint16_t triggers)

void devif_callback_init(void)
{
#if CONFIG_NET_PREALLOC_DEVIF_CALLBACKS > 0
int i;

for (i = 0; i < CONFIG_NET_PREALLOC_DEVIF_CALLBACKS; i++)
{
g_cbprealloc[i].nxtconn = g_cbfreelist;
g_cbfreelist = &g_cbprealloc[i];
}
#endif
NET_BUFPOOL_INIT(g_cbprealloc);
}

/****************************************************************************
Expand All @@ -299,9 +276,6 @@ FAR struct devif_callback_s *
FAR struct devif_callback_s **list_tail)
{
FAR struct devif_callback_s *ret;
#if CONFIG_NET_ALLOC_DEVIF_CALLBACKS > 0
int i;
#endif

net_lock();

Expand All @@ -324,34 +298,11 @@ FAR struct devif_callback_s *
return NULL;
}

/* Allocate the callback entry from heap */
/* Get a callback structure */

#if CONFIG_NET_ALLOC_DEVIF_CALLBACKS > 0
if (g_cbfreelist == NULL)
{
ret = kmm_zalloc(sizeof(struct devif_callback_s) *
CONFIG_NET_ALLOC_DEVIF_CALLBACKS);
if (ret != NULL)
{
for (i = 0; i < CONFIG_NET_ALLOC_DEVIF_CALLBACKS; i++)
{
ret[i].nxtconn = g_cbfreelist;
g_cbfreelist = &ret[i];
}
}
}
#endif

/* Check the head of the free list */

ret = g_cbfreelist;
ret = NET_BUFPOOL_TRYALLOC(g_cbprealloc);
if (ret)
{
/* Remove the next instance from the head of the free list */

g_cbfreelist = ret->nxtconn;
memset(ret, 0, sizeof(struct devif_callback_s));

/* Add the newly allocated instance to the head of the device event
* list.
*/
Expand Down
Loading
Loading