Skip to content

Commit 1fe07d0

Browse files
wengzheAlan C. Assis
authored andcommitted
net: Add buffer pool to replace connection allocation
Our net socket connection allocations are powerful but redundant because they're implemented once in each protocol. This is not good for further optimizing and extending to other allocations, so maybe we can add a common implementation for the usage. Impact: 1. We add a `struct net_bufpool_s` as pool descriptor, which may use a little bit more memory than previous implementation (~28Bytes). 2. We share same functions between pools, so code size may shrink under some scenarios. Signed-off-by: Zhe Weng <[email protected]>
1 parent badb5c5 commit 1fe07d0

File tree

15 files changed

+437
-724
lines changed

15 files changed

+437
-724
lines changed

net/bluetooth/bluetooth_conn.c

Lines changed: 17 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,19 @@
4242
#include <nuttx/net/bluetooth.h>
4343

4444
#include "devif/devif.h"
45+
#include "utils/utils.h"
4546
#include "bluetooth/bluetooth.h"
4647

4748
#ifdef CONFIG_NET_BLUETOOTH
4849

50+
/****************************************************************************
51+
* Pre-processor Definitions
52+
****************************************************************************/
53+
54+
#ifndef CONFIG_NET_BLUETOOTH_MAX_CONNS
55+
# define CONFIG_NET_BLUETOOTH_MAX_CONNS 0
56+
#endif
57+
4958
/****************************************************************************
5059
* Private Data
5160
****************************************************************************/
@@ -54,14 +63,10 @@
5463
* network lock.
5564
*/
5665

57-
#if CONFIG_NET_BLUETOOTH_PREALLOC_CONNS > 0
58-
static struct bluetooth_conn_s
59-
g_bluetooth_connections[CONFIG_NET_BLUETOOTH_PREALLOC_CONNS];
60-
#endif
61-
62-
/* A list of all free packet socket connections */
63-
64-
static dq_queue_t g_free_bluetooth_connections;
66+
NET_BUFPOOL_DECLARE(g_bluetooth_connections, sizeof(struct bluetooth_conn_s),
67+
CONFIG_NET_BLUETOOTH_PREALLOC_CONNS,
68+
CONFIG_NET_BLUETOOTH_ALLOC_CONNS,
69+
CONFIG_NET_BLUETOOTH_MAX_CONNS);
6570

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

@@ -90,17 +95,7 @@ static const bt_addr_t g_any_addr =
9095

9196
void bluetooth_conn_initialize(void)
9297
{
93-
#if CONFIG_NET_BLUETOOTH_PREALLOC_CONNS > 0
94-
int i;
95-
96-
for (i = 0; i < CONFIG_NET_BLUETOOTH_PREALLOC_CONNS; i++)
97-
{
98-
/* Link each pre-allocated connection structure into the free list. */
99-
100-
dq_addlast(&g_bluetooth_connections[i].bc_conn.node,
101-
&g_free_bluetooth_connections);
102-
}
103-
#endif
98+
NET_BUFPOOL_INIT(g_bluetooth_connections);
10499
}
105100

106101
/****************************************************************************
@@ -115,39 +110,12 @@ void bluetooth_conn_initialize(void)
115110
FAR struct bluetooth_conn_s *bluetooth_conn_alloc(void)
116111
{
117112
FAR struct bluetooth_conn_s *conn;
118-
#if CONFIG_NET_BLUETOOTH_ALLOC_CONNS > 0
119-
int i;
120-
#endif
121113

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

124116
net_lock();
125-
#if CONFIG_NET_BLUETOOTH_ALLOC_CONNS > 0
126-
if (dq_peek(&g_active_bluetooth_connections) == NULL)
127-
{
128-
#if CONFIG_NET_BLUETOOTH_MAX_CONNS > 0
129-
if (dq_count(&g_active_bluetooth_connections) +
130-
CONFIG_NET_BLUETOOTH_ALLOC_CONNS > CONFIG_NET_BLUETOOTH_MAX_CONNS)
131-
{
132-
net_unlock();
133-
return NULL;
134-
}
135-
#endif
136-
137-
conn = kmm_zalloc(sizeof(*conn) * CONFIG_NET_BLUETOOTH_ALLOC_CONNS);
138-
if (conn != NULL)
139-
{
140-
for (i = 0; i < CONFIG_NET_BLUETOOTH_ALLOC_CONNS; i++)
141-
{
142-
dq_addlast(&conn[i].bc_conn.node,
143-
&g_active_bluetooth_connections);
144-
}
145-
}
146-
}
147-
#endif
148117

149-
conn = (FAR struct bluetooth_conn_s *)
150-
dq_remfirst(&g_free_bluetooth_connections);
118+
conn = NET_BUFPOOL_TRYALLOC(g_bluetooth_connections);
151119
if (conn)
152120
{
153121
/* Mark as unbound */
@@ -207,22 +175,9 @@ void bluetooth_conn_free(FAR struct bluetooth_conn_s *conn)
207175
bluetooth_container_free(container);
208176
}
209177

210-
/* If this is a preallocated or a batch allocated connection store it in
211-
* the free connections list. Else free it.
212-
*/
178+
/* Free the connection structure */
213179

214-
#if CONFIG_NET_BLUETOOTH_ALLOC_CONNS == 1
215-
if (conn < g_bluetooth_connections || conn >= (g_bluetooth_connections +
216-
CONFIG_NET_BLUETOOTH_PREALLOC_CONNS))
217-
{
218-
kmm_free(conn);
219-
}
220-
else
221-
#endif
222-
{
223-
memset(conn, 0, sizeof(*conn));
224-
dq_addlast(&conn->bc_conn.node, &g_free_bluetooth_connections);
225-
}
180+
NET_BUFPOOL_FREE(g_bluetooth_connections, conn);
226181

227182
net_unlock();
228183
}

net/can/can_conn.c

Lines changed: 15 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -46,18 +46,22 @@
4646
#ifdef CONFIG_NET_CAN
4747

4848
/****************************************************************************
49-
* Private Data
49+
* Pre-processor Definitions
5050
****************************************************************************/
5151

52-
/* The array containing all NetLink connections. */
53-
54-
#if CONFIG_CAN_PREALLOC_CONNS > 0
55-
static struct can_conn_s g_can_connections[CONFIG_CAN_PREALLOC_CONNS];
52+
#ifndef CONFIG_CAN_MAX_CONNS
53+
# define CONFIG_CAN_MAX_CONNS 0
5654
#endif
5755

58-
/* A list of all free NetLink connections */
56+
/****************************************************************************
57+
* Private Data
58+
****************************************************************************/
59+
60+
/* The array containing all NetLink connections. */
5961

60-
static dq_queue_t g_free_can_connections;
62+
NET_BUFPOOL_DECLARE(g_can_connections, sizeof(struct can_conn_s),
63+
CONFIG_CAN_PREALLOC_CONNS, CONFIG_CAN_ALLOC_CONNS,
64+
CONFIG_CAN_MAX_CONNS);
6165
static mutex_t g_free_lock = NXMUTEX_INITIALIZER;
6266

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

8084
void can_initialize(void)
8185
{
82-
#if CONFIG_CAN_PREALLOC_CONNS > 0
83-
int i;
84-
85-
for (i = 0; i < CONFIG_CAN_PREALLOC_CONNS; i++)
86-
{
87-
/* Mark the connection closed and move it to the free list */
88-
89-
dq_addlast(&g_can_connections[i].sconn.node, &g_free_can_connections);
90-
}
91-
#endif
86+
NET_BUFPOOL_INIT(g_can_connections);
9287
}
9388

9489
/****************************************************************************
@@ -103,37 +98,12 @@ void can_initialize(void)
10398
FAR struct can_conn_s *can_alloc(void)
10499
{
105100
FAR struct can_conn_s *conn;
106-
#if CONFIG_CAN_ALLOC_CONNS > 0
107-
int i;
108-
#endif
109101

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

112104
nxmutex_lock(&g_free_lock);
113-
#if CONFIG_CAN_ALLOC_CONNS > 0
114-
if (dq_peek(&g_free_can_connections) == NULL)
115-
{
116-
#if CONFIG_CAN_MAX_CONNS > 0
117-
if (dq_count(&g_active_can_connections) +
118-
CONFIG_CAN_ALLOC_CONNS > CONFIG_CAN_MAX_CONNS)
119-
{
120-
nxmutex_unlock(&g_free_lock);
121-
return NULL;
122-
}
123-
#endif
124-
125-
conn = kmm_zalloc(sizeof(*conn) * CONFIG_CAN_ALLOC_CONNS);
126-
if (conn != NULL)
127-
{
128-
for (i = 0; i < CONFIG_CAN_ALLOC_CONNS; i++)
129-
{
130-
dq_addlast(&conn[i].sconn.node, &g_free_can_connections);
131-
}
132-
}
133-
}
134-
#endif
135105

136-
conn = (FAR struct can_conn_s *)dq_remfirst(&g_free_can_connections);
106+
conn = NET_BUFPOOL_TRYALLOC(g_can_connections);
137107
if (conn != NULL)
138108
{
139109
/* FIXME SocketCAN default behavior enables loopback */
@@ -184,22 +154,9 @@ void can_free(FAR struct can_conn_s *conn)
184154

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

187-
/* If this is a preallocated or a batch allocated connection store it in
188-
* the free connections list. Else free it.
189-
*/
157+
/* Free the connection. */
190158

191-
#if CONFIG_CAN_ALLOC_CONNS == 1
192-
if (conn < g_can_connections || conn >= (g_can_connections +
193-
CONFIG_CAN_PREALLOC_CONNS))
194-
{
195-
kmm_free(conn);
196-
}
197-
else
198-
#endif
199-
{
200-
memset(conn, 0, sizeof(*conn));
201-
dq_addlast(&conn->sconn.node, &g_free_can_connections);
202-
}
159+
NET_BUFPOOL_FREE(g_can_connections, conn);
203160

204161
nxmutex_unlock(&g_free_lock);
205162
}

net/devif/devif_callback.c

Lines changed: 10 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
#include <nuttx/net/netdev.h>
4040

4141
#include "netdev/netdev.h"
42+
#include "utils/utils.h"
4243
#include "devif/devif.h"
4344

4445
/****************************************************************************
@@ -52,11 +53,9 @@
5253
* Private Data
5354
****************************************************************************/
5455

55-
#if CONFIG_NET_PREALLOC_DEVIF_CALLBACKS > 0
56-
static struct devif_callback_s
57-
g_cbprealloc[CONFIG_NET_PREALLOC_DEVIF_CALLBACKS];
58-
#endif
59-
static FAR struct devif_callback_s *g_cbfreelist = NULL;
56+
NET_BUFPOOL_DECLARE(g_cbprealloc, sizeof(struct devif_callback_s),
57+
CONFIG_NET_PREALLOC_DEVIF_CALLBACKS,
58+
CONFIG_NET_ALLOC_DEVIF_CALLBACKS, 0);
6059

6160
/****************************************************************************
6261
* Private Functions
@@ -88,7 +87,7 @@ static void devif_callback_free(FAR struct net_driver_s *dev,
8887
#ifdef CONFIG_DEBUG_FEATURES
8988
/* Check for double freed callbacks */
9089

91-
curr = g_cbfreelist;
90+
curr = (FAR struct devif_callback_s *)g_cbprealloc.freebuffers.head;
9291

9392
while (curr != NULL)
9493
{
@@ -187,23 +186,9 @@ static void devif_callback_free(FAR struct net_driver_s *dev,
187186
}
188187
}
189188

190-
/* If this is a preallocated or a batch allocated callback store it in
191-
* the free callbacks list. Else free it.
192-
*/
189+
/* Free the callback structure */
193190

194-
#if CONFIG_NET_ALLOC_DEVIF_CALLBACKS == 1
195-
if (cb < g_cbprealloc || cb >= (g_cbprealloc +
196-
CONFIG_NET_PREALLOC_DEVIF_CALLBACKS))
197-
{
198-
kmm_free(cb);
199-
}
200-
else
201-
#endif
202-
{
203-
cb->nxtconn = g_cbfreelist;
204-
cb->nxtdev = NULL;
205-
g_cbfreelist = cb;
206-
}
191+
NET_BUFPOOL_FREE(g_cbprealloc, cb);
207192

208193
net_unlock();
209194
}
@@ -266,15 +251,7 @@ static bool devif_event_trigger(uint16_t events, uint16_t triggers)
266251

267252
void devif_callback_init(void)
268253
{
269-
#if CONFIG_NET_PREALLOC_DEVIF_CALLBACKS > 0
270-
int i;
271-
272-
for (i = 0; i < CONFIG_NET_PREALLOC_DEVIF_CALLBACKS; i++)
273-
{
274-
g_cbprealloc[i].nxtconn = g_cbfreelist;
275-
g_cbfreelist = &g_cbprealloc[i];
276-
}
277-
#endif
254+
NET_BUFPOOL_INIT(g_cbprealloc);
278255
}
279256

280257
/****************************************************************************
@@ -299,9 +276,6 @@ FAR struct devif_callback_s *
299276
FAR struct devif_callback_s **list_tail)
300277
{
301278
FAR struct devif_callback_s *ret;
302-
#if CONFIG_NET_ALLOC_DEVIF_CALLBACKS > 0
303-
int i;
304-
#endif
305279

306280
net_lock();
307281

@@ -324,34 +298,11 @@ FAR struct devif_callback_s *
324298
return NULL;
325299
}
326300

327-
/* Allocate the callback entry from heap */
301+
/* Get a callback structure */
328302

329-
#if CONFIG_NET_ALLOC_DEVIF_CALLBACKS > 0
330-
if (g_cbfreelist == NULL)
331-
{
332-
ret = kmm_zalloc(sizeof(struct devif_callback_s) *
333-
CONFIG_NET_ALLOC_DEVIF_CALLBACKS);
334-
if (ret != NULL)
335-
{
336-
for (i = 0; i < CONFIG_NET_ALLOC_DEVIF_CALLBACKS; i++)
337-
{
338-
ret[i].nxtconn = g_cbfreelist;
339-
g_cbfreelist = &ret[i];
340-
}
341-
}
342-
}
343-
#endif
344-
345-
/* Check the head of the free list */
346-
347-
ret = g_cbfreelist;
303+
ret = NET_BUFPOOL_TRYALLOC(g_cbprealloc);
348304
if (ret)
349305
{
350-
/* Remove the next instance from the head of the free list */
351-
352-
g_cbfreelist = ret->nxtconn;
353-
memset(ret, 0, sizeof(struct devif_callback_s));
354-
355306
/* Add the newly allocated instance to the head of the device event
356307
* list.
357308
*/

0 commit comments

Comments
 (0)