Skip to content

Commit 84d261e

Browse files
wengzheAlan C. Assis
authored andcommitted
net: Optimize ipfwd and wrbuffer by buffer pool
To allow dynamic allocation of these structs, performance keeps the same as the previous implementation. Signed-off-by: Zhe Weng <[email protected]>
1 parent 1fe07d0 commit 84d261e

File tree

8 files changed

+113
-151
lines changed

8 files changed

+113
-151
lines changed

net/ipforward/Kconfig

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,21 @@ config NET_IPFORWARD_NSTRUCT
4040
WARNING: DO NOT set this setting to a value greater than or equal to
4141
CONFIG_IOB_NBUFFERS, otherwise it may consume all the IOB and let
4242
netdev fail to work.
43+
44+
config NET_IPFORWARD_ALLOC_STRUCT
45+
int "Dynamic forwarding structures allocation"
46+
default 0
47+
---help---
48+
When set to 0 all dynamic allocations are disabled
49+
50+
When set to 1 a new forwarding structure will be allocated every
51+
time, and it will be free'd when no longer needed.
52+
53+
Setting this to 2 or more will allocate the forwarding structures
54+
in batches (with batch size equal to this config). When a I/O buffer
55+
chain head is no longer needed, it will be returned to the free
56+
forwarding structures pool, and it will never be deallocated!
57+
58+
Note: maximum number of allocated forwarding structures is limited
59+
to CONFIG_IOB_NBUFFERS - CONFIG_IOB_THROTTLE to avoid consuming all
60+
the IOBs.

net/ipforward/ipfwd_alloc.c

Lines changed: 9 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
#include <nuttx/net/icmpv6.h>
3838

3939
#include "ipforward/ipforward.h"
40+
#include "utils/utils.h"
4041

4142
#ifdef CONFIG_NET_IPFORWARD
4243

@@ -66,13 +67,12 @@
6667
* Private Data
6768
****************************************************************************/
6869

69-
/* This is an array of pre-allocating forwarding structures */
70+
/* This is the state of the global forwarding structures */
7071

71-
static struct forward_s g_fwdpool[CONFIG_NET_IPFORWARD_NSTRUCT];
72-
73-
/* This is a list of free forwarding structures */
74-
75-
static FAR struct forward_s *g_fwdfree;
72+
NET_BUFPOOL_DECLARE(g_fwdpool, sizeof(struct forward_s),
73+
CONFIG_NET_IPFORWARD_NSTRUCT,
74+
CONFIG_NET_IPFORWARD_ALLOC_STRUCT,
75+
CONFIG_IOB_NBUFFERS - CONFIG_IOB_THROTTLE);
7676

7777
/****************************************************************************
7878
* Public Functions
@@ -91,25 +91,13 @@ static FAR struct forward_s *g_fwdfree;
9191

9292
void ipfwd_initialize(void)
9393
{
94-
FAR struct forward_s *fwd;
95-
int i;
96-
9794
/* The IOB size must be such that the maximum L2 and L3 headers fit into
9895
* the contiguous memory of the first IOB in the IOB chain.
9996
*/
10097

10198
DEBUGASSERT(MAX_HDRLEN <= CONFIG_IOB_BUFSIZE);
10299

103-
/* Add all pre-allocated forwarding structures to the free list */
104-
105-
g_fwdfree = NULL;
106-
107-
for (i = 0; i < CONFIG_NET_IPFORWARD_NSTRUCT; i++)
108-
{
109-
fwd = &g_fwdpool[i];
110-
fwd->f_flink = g_fwdfree;
111-
g_fwdfree = fwd;
112-
}
100+
NET_BUFPOOL_INIT(g_fwdpool);
113101
}
114102

115103
/****************************************************************************
@@ -127,16 +115,7 @@ void ipfwd_initialize(void)
127115

128116
FAR struct forward_s *ipfwd_alloc(void)
129117
{
130-
FAR struct forward_s *fwd;
131-
132-
fwd = g_fwdfree;
133-
if (fwd != NULL)
134-
{
135-
g_fwdfree = fwd->f_flink;
136-
memset (fwd, 0, sizeof(struct forward_s));
137-
}
138-
139-
return fwd;
118+
return NET_BUFPOOL_TRYALLOC(g_fwdpool);
140119
}
141120

142121
/****************************************************************************
@@ -153,8 +132,7 @@ FAR struct forward_s *ipfwd_alloc(void)
153132

154133
void ipfwd_free(FAR struct forward_s *fwd)
155134
{
156-
fwd->f_flink = g_fwdfree;
157-
g_fwdfree = fwd;
135+
NET_BUFPOOL_FREE(g_fwdpool, fwd);
158136
}
159137

160138
#endif /* CONFIG_NET_IPFORWARD */

net/tcp/Kconfig

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,20 @@ config NET_TCP_NWRBCHAINS
259259
choice for this value would be the same as the maximum number of
260260
TCP connections.
261261

262+
config NET_TCP_ALLOC_WRBCHAINS
263+
int "Dynamic I/O buffer chain heads allocation"
264+
default 0
265+
---help---
266+
When set to 0 all dynamic allocations are disabled
267+
268+
When set to 1 a new I/O buffer chain head will be allocated every
269+
time, and it will be free'd when no longer needed.
270+
271+
Setting this to 2 or more will allocate the I/O buffer chain heads
272+
in batches (with batch size equal to this config). When a I/O buffer
273+
chain head is no longer needed, it will be returned to the free
274+
I/O buffer chain heads pool, and it will never be deallocated!
275+
262276
config NET_TCP_WRBUFFER_DEBUG
263277
bool "Force write buffer debug"
264278
default n

net/tcp/tcp_wrbuffer.c

Lines changed: 8 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -48,34 +48,15 @@
4848

4949
#if defined(CONFIG_NET_TCP) && defined(CONFIG_NET_TCP_WRITE_BUFFERS)
5050

51-
/****************************************************************************
52-
* Private Types
53-
****************************************************************************/
54-
55-
/* Package all globals used by this logic into a structure */
56-
57-
struct wrbuffer_s
58-
{
59-
/* The semaphore to protect the buffers */
60-
61-
sem_t sem;
62-
63-
/* This is the list of available write buffers */
64-
65-
sq_queue_t freebuffers;
66-
67-
/* These are the pre-allocated write buffers */
68-
69-
struct tcp_wrbuffer_s buffers[CONFIG_NET_TCP_NWRBCHAINS];
70-
};
71-
7251
/****************************************************************************
7352
* Private Data
7453
****************************************************************************/
7554

7655
/* This is the state of the global write buffer resource */
7756

78-
static struct wrbuffer_s g_wrbuffer;
57+
NET_BUFPOOL_DECLARE(g_wrbuffer, sizeof(struct tcp_wrbuffer_s),
58+
CONFIG_NET_TCP_NWRBCHAINS,
59+
CONFIG_NET_TCP_ALLOC_WRBCHAINS, 0);
7960

8061
/****************************************************************************
8162
* Public Functions
@@ -94,16 +75,7 @@ static struct wrbuffer_s g_wrbuffer;
9475

9576
void tcp_wrbuffer_initialize(void)
9677
{
97-
int i;
98-
99-
sq_init(&g_wrbuffer.freebuffers);
100-
101-
nxsem_init(&g_wrbuffer.sem, 0, CONFIG_NET_TCP_NWRBCHAINS);
102-
103-
for (i = 0; i < CONFIG_NET_TCP_NWRBCHAINS; i++)
104-
{
105-
sq_addfirst(&g_wrbuffer.buffers[i].wb_node, &g_wrbuffer.freebuffers);
106-
}
78+
NET_BUFPOOL_INIT(g_wrbuffer);
10779
}
10880

10981
/****************************************************************************
@@ -127,7 +99,6 @@ void tcp_wrbuffer_initialize(void)
12799
FAR struct tcp_wrbuffer_s *tcp_wrbuffer_timedalloc(unsigned int timeout)
128100
{
129101
FAR struct tcp_wrbuffer_s *wrb;
130-
int ret;
131102

132103
/* We need to allocate two things: (1) A write buffer structure and (2)
133104
* at least one I/O buffer to start the chain.
@@ -137,20 +108,12 @@ FAR struct tcp_wrbuffer_s *tcp_wrbuffer_timedalloc(unsigned int timeout)
137108
* buffer
138109
*/
139110

140-
ret = net_sem_timedwait_uninterruptible(&g_wrbuffer.sem, timeout);
141-
if (ret != OK)
111+
wrb = NET_BUFPOOL_TIMEDALLOC(g_wrbuffer, timeout);
112+
if (wrb == NULL)
142113
{
143114
return NULL;
144115
}
145116

146-
/* Now, we are guaranteed to have a write buffer structure reserved
147-
* for us in the free list.
148-
*/
149-
150-
wrb = (FAR struct tcp_wrbuffer_s *)sq_remfirst(&g_wrbuffer.freebuffers);
151-
DEBUGASSERT(wrb);
152-
memset(wrb, 0, sizeof(struct tcp_wrbuffer_s));
153-
154117
/* Now get the first I/O buffer for the write buffer structure */
155118

156119
wrb->wb_iob = net_iobtimedalloc(true, timeout);
@@ -247,8 +210,7 @@ void tcp_wrbuffer_release(FAR struct tcp_wrbuffer_s *wrb)
247210

248211
/* Then free the write buffer structure */
249212

250-
sq_addlast(&wrb->wb_node, &g_wrbuffer.freebuffers);
251-
nxsem_post(&g_wrbuffer.sem);
213+
NET_BUFPOOL_FREE(g_wrbuffer, wrb);
252214
}
253215

254216
/****************************************************************************
@@ -304,16 +266,7 @@ uint32_t tcp_wrbuffer_inqueue_size(FAR struct tcp_conn_s *conn)
304266

305267
int tcp_wrbuffer_test(void)
306268
{
307-
int val = 0;
308-
int ret;
309-
310-
ret = nxsem_get_value(&g_wrbuffer.sem, &val);
311-
if (ret >= 0)
312-
{
313-
ret = val > 0 ? OK : -ENOSPC;
314-
}
315-
316-
return ret;
269+
return NET_BUFPOOL_TEST(g_wrbuffer);
317270
}
318271

319272
#endif /* CONFIG_NET_TCP && CONFIG_NET_TCP_WRITE_BUFFERS */

net/udp/Kconfig

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,20 @@ config NET_UDP_NWRBCHAINS
103103
choice for this value would be the same as the maximum number of
104104
UDP connections.
105105

106+
config NET_UDP_ALLOC_WRBCHAINS
107+
int "Dynamic I/O buffer chain heads allocation"
108+
default 0
109+
---help---
110+
When set to 0 all dynamic allocations are disabled.
111+
112+
When set to 1 a new I/O buffer chain head will be allocated every
113+
time, and it will be free'd when no longer needed.
114+
115+
Setting this to 2 or more will allocate the I/O buffer chain heads
116+
in batches (with batch size equal to this config). When a I/O buffer
117+
chain head is no longer needed, it will be returned to the free
118+
I/O buffer chain heads pool, and it will never be deallocated!
119+
106120
config NET_UDP_WRBUFFER_DEBUG
107121
bool "Force write buffer debug"
108122
default n

0 commit comments

Comments
 (0)