Skip to content

Commit f9e6253

Browse files
EMAC memory manager improvements & fixes
1 parent b68997b commit f9e6253

File tree

25 files changed

+341
-469
lines changed

25 files changed

+341
-469
lines changed

connectivity/drivers/wifi/TARGET_STM/COMPONENT_EMW3080B/mx_wifi_mbed_os.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ void mx_buf_set_size(mx_buf_t *p, int32_t n)
6060

6161
mx_buf_t *mx_buf_alloc(uint32_t len)
6262
{
63-
emac_mem_buf_t *p = emac3080b_global_memory_manager->alloc_pool(len, 0);
63+
emac_mem_buf_t *p = emac3080b_global_memory_manager->alloc_heap(len, 0);
6464
return (mx_buf_t *) p;
6565
}
6666

connectivity/libraries/nanostack-libservice/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ target_sources(mbed-nanostack-libservice
2222
source/nvmHelper/ns_nvm_helper.c
2323
)
2424

25+
target_link_libraries(mbed-nanostack-libservice
26+
PUBLIC
27+
mbed-core-flags)
28+
2529
# The definition, source files and include directories below
2630
# are needed by mbed-trace which is part of the mbed-core CMake target
2731
target_compile_definitions(mbed-core-flags

connectivity/libraries/nanostack-libservice/source/nsdynmemLIB/nsdynmemLIB.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "platform/arm_hal_interrupt.h"
2222
#include <stdlib.h>
2323
#include "ns_list.h"
24+
#include "mbed_toolchain.h"
2425

2526
#ifndef STANDARD_MALLOC
2627
typedef enum mem_stat_update_t {
@@ -598,6 +599,10 @@ static bool pointer_address_validate(ns_mem_book_t *book, ns_mem_word_size_t *pt
598599
return false;
599600
}
600601

602+
// Hook from nanostack to the Mbed EMAC memory manager when memory becomes free.
603+
MBED_WEAK void mbed_ns_heap_free_hook(void)
604+
{}
605+
601606
void ns_mem_free(ns_mem_book_t *book, void *block)
602607
{
603608
#ifndef STANDARD_MALLOC
@@ -633,6 +638,8 @@ void ns_mem_free(ns_mem_book_t *book, void *block)
633638
free(block);
634639
platform_exit_critical();
635640
#endif
641+
642+
mbed_ns_heap_free_hook();
636643
}
637644

638645
void ns_dyn_mem_free(void *block)

connectivity/lwipstack/include/lwipstack/LWIPMemoryManager.h

Lines changed: 10 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -19,151 +19,47 @@
1919

2020
#include "EMACMemoryManager.h"
2121

22+
// Hook called from LwIP whenever a pbuf chain containing at least one pool pbuf has been freed
23+
extern "C" void mbed_lwip_on_pbuf_pool_free_hook();
2224

2325
class LWIPMemoryManager final : public EMACMemoryManager {
2426
public:
2527

26-
/**
27-
* Allocates memory buffer from the heap
28-
*
29-
* Memory buffer allocated from heap is always contiguous and can be arbitrary size.
30-
*
31-
* @param size Size of the memory to allocate in bytes
32-
* @param align Memory alignment requirement in bytes
33-
* @return Allocated memory buffer, or NULL in case of error
34-
*/
3528
net_stack_mem_buf_t *alloc_heap(uint32_t size, uint32_t align) override;
3629

37-
/**
38-
* Allocates memory buffer chain from a pool
39-
*
40-
* Memory allocated from pool is contiguous if size is equal or less than
41-
* (aligned) allocation unit, otherwise may be chained. Will typically come from
42-
* fixed-size packet pool memory.
43-
*
44-
* @param size Total size of the memory to allocate in bytes
45-
* @param align Memory alignment requirement for each buffer in bytes
46-
* @return Allocated memory buffer chain, or NULL in case of error
47-
*/
4830
net_stack_mem_buf_t *alloc_pool(uint32_t size, uint32_t align) override;
4931

50-
/**
51-
* Get memory buffer pool allocation unit
52-
*
53-
* Returns the maximum size of contiguous memory that can be allocated from a pool.
54-
*
55-
* @param align Memory alignment requirement in bytes
56-
* @return Contiguous memory size
57-
*/
5832
uint32_t get_pool_alloc_unit(uint32_t align) const override;
5933

60-
/**
61-
* Free memory buffer chain
62-
*
63-
* If memory buffer is chained must point to the start of the chain. Frees all buffers
64-
* from the chained list.
65-
*
66-
* @param buf Memory buffer chain to be freed.
67-
*/
34+
uint32_t get_pool_size() const override;
35+
6836
void free(net_stack_mem_buf_t *buf) override;
6937

70-
/**
71-
* Return total length of a memory buffer chain
72-
*
73-
* Returns a total length of this buffer and any following buffers in the chain.
74-
*
75-
* @param buf Memory buffer chain
76-
* @return Total length in bytes
77-
*/
7838
uint32_t get_total_len(const net_stack_mem_buf_t *buf) const override;
7939

80-
/**
81-
* Copy a memory buffer chain
82-
*
83-
* Copies data from one buffer chain to another. Copy operation does not adjust the lengths
84-
* of the copied-to memory buffer chain, so chain total lengths must be the same.
85-
*
86-
* @param to_buf Memory buffer chain to copy to
87-
* @param from_buf Memory buffer chain to copy from
88-
*/
8940
void copy(net_stack_mem_buf_t *to_buf, const net_stack_mem_buf_t *from_buf) override;
9041

91-
/**
92-
* Copy to a memory buffer chain
93-
*
94-
* Copies data to a buffer chain. Copy operation does not adjust the lengths
95-
* of the copied-to memory buffer chain, so chain total length must match the
96-
* copied length.
97-
*
98-
* @param to_buf Memory buffer chain to copy to
99-
* @param ptr Pointer to data
100-
* @param len Data length
101-
*/
10242
void copy_to_buf(net_stack_mem_buf_t *to_buf, const void *ptr, uint32_t len) override;
10343

104-
/**
105-
* Copy from a memory buffer chain
106-
*
107-
* Copies data from a memory buffer chain.
108-
*
109-
* @param len Data length
110-
* @param ptr Pointer to data
111-
* @param from_buf Memory buffer chain to copy from
112-
* @return Length of the data that was copied
113-
*/
11444
uint32_t copy_from_buf(void *ptr, uint32_t len, const net_stack_mem_buf_t *from_buf) const override;
11545

116-
/**
117-
* Concatenate two memory buffer chains
118-
*
119-
* Concatenates buffer chain to end of the other buffer chain. Concatenated-to buffer total length
120-
* is adjusted accordingly. cat_buf must point to the start of a the chain. After concatenation
121-
* to_buf's chain now owns those buffers, and they will be freed when the to_buf chain is freed.
122-
*
123-
* @param to_buf Memory buffer chain to concatenate to
124-
* @param cat_buf Memory buffer chain to concatenate
125-
*/
12646
void cat(net_stack_mem_buf_t *to_buf, net_stack_mem_buf_t *cat_buf) override;
12747

128-
/**
129-
* Returns the next buffer
130-
*
131-
* Returns the next buffer from the memory buffer chain.
132-
*
133-
* @param buf Memory buffer
134-
* @return The next memory buffer, or NULL if last
135-
*/
13648
net_stack_mem_buf_t *get_next(const net_stack_mem_buf_t *buf) const override;
13749

138-
/**
139-
* Return pointer to the payload of the buffer
140-
*
141-
* @param buf Memory buffer
142-
* @return Pointer to the payload
143-
*/
14450
void *get_ptr(const net_stack_mem_buf_t *buf) const override;
14551

146-
/**
147-
* Return payload size of the buffer
148-
*
149-
* @param buf Memory buffer
150-
* @return Size in bytes
151-
*/
15252
uint32_t get_len(const net_stack_mem_buf_t *buf) const override;
15353

154-
/**
155-
* Sets the payload size of the buffer
156-
*
157-
* The allocated payload size will not change. It is not permitted
158-
* to change the length of a buffer that is not the first (or only) in a chain.
159-
*
160-
* @param buf Memory buffer
161-
* @param len Payload size, must be less or equal allocated size
162-
*/
16354
void set_len(net_stack_mem_buf_t *buf, uint32_t len) override;
16455

56+
Lifetime get_lifetime(const net_stack_mem_buf_t *buf) const override;
57+
16558
private:
16659

60+
// Allow callback to access private vars
61+
friend void mbed_lwip_on_pbuf_pool_free_hook();
62+
16763
/**
16864
* Returns a total memory alignment size
16965
*
@@ -192,7 +88,7 @@ class LWIPMemoryManager final : public EMACMemoryManager {
19288
* Sets total lengths of a memory buffer chain
19389
*
19490
* Sets total length fields for a memory buffer chain based on buffer
195-
* length fields. All total lengths are calculated again.
91+
* \c len fields. All total lengths are calculated again.
19692
*
19793
* @param pbuf Memory buffer
19894
*/

connectivity/lwipstack/include/lwipstack/LWIPStack.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,12 @@ class LWIP : public OnboardNetworkStack, private mbed::NonCopyable<LWIP> {
344344
*/
345345
void set_default_interface(OnboardNetworkStack::Interface *interface) override;
346346

347+
/// Get the memory manager for the LwIP stack
348+
LWIPMemoryManager &get_memory_manager()
349+
{
350+
return memory_manager;
351+
}
352+
347353
protected:
348354
LWIP();
349355

connectivity/lwipstack/include/lwipstack/lwipopts.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -136,11 +136,11 @@
136136

137137
// Number of pool pbufs.
138138
// Each requires 684 bytes of RAM (if MSS=536 and PBUF_POOL_BUFSIZE defaulting to be based on MSS)
139-
#define PBUF_POOL_SIZE MBED_CONF_LWIP_PBUF_POOL_SIZE
139+
#define PBUF_POOL_SIZE MBED_CONF_NSAPI_EMAC_RX_POOL_NUM_BUFS
140140

141-
#ifdef MBED_CONF_LWIP_PBUF_POOL_BUFSIZE
141+
#ifdef MBED_CONF_NSAPI_EMAC_RX_POOL_BUF_SIZE
142142
#undef PBUF_POOL_BUFSIZE
143-
#define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(MBED_CONF_LWIP_PBUF_POOL_BUFSIZE)
143+
#define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(MBED_CONF_NSAPI_EMAC_RX_POOL_BUF_SIZE)
144144
#else
145145
#ifndef PBUF_POOL_BUFSIZE
146146
#if LWIP_IPV6

connectivity/lwipstack/lwip/src/core/lwip_pbuf.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -739,6 +739,9 @@ pbuf_free(struct pbuf *p)
739739
PERF_START;
740740

741741
count = 0;
742+
743+
bool pbuf_pool_freed = false;
744+
742745
/* de-allocate all consecutive pbufs from the head of the chain that
743746
* obtain a zero reference count after decrementing*/
744747
while (p != NULL) {
@@ -771,6 +774,9 @@ pbuf_free(struct pbuf *p)
771774
/* is this a pbuf from the pool? */
772775
if (alloc_src == PBUF_TYPE_ALLOC_SRC_MASK_STD_MEMP_PBUF_POOL) {
773776
memp_free(MEMP_PBUF_POOL, p);
777+
778+
// Mbed OS Patch: set flag that buffer was from the pool
779+
pbuf_pool_freed = true;
774780
/* is this a ROM or RAM referencing pbuf? */
775781
} else if (alloc_src == PBUF_TYPE_ALLOC_SRC_MASK_STD_MEMP_PBUF) {
776782
memp_free(MEMP_PBUF, p);
@@ -793,6 +799,13 @@ pbuf_free(struct pbuf *p)
793799
p = NULL;
794800
}
795801
}
802+
803+
// Mbed OS Patch: Hook into the memory manager when a POOL buffer is freed.
804+
if(pbuf_pool_freed) {
805+
extern void mbed_lwip_on_pbuf_pool_free_hook(void);
806+
mbed_lwip_on_pbuf_pool_free_hook();
807+
}
808+
796809
PERF_STOP("pbuf_free");
797810
/* return number of de-allocated pbufs */
798811
return count;
Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -118,14 +118,6 @@
118118
"help": "Priority of lwip TCPIP thread",
119119
"value": "osPriorityNormal"
120120
},
121-
"pbuf-pool-size": {
122-
"help": "Number of pbufs in pool - usually used for received packets, so this determines how much data can be buffered between reception and the application reading, see LWIP's opt.h for more information. If a driver uses PBUF_RAM for reception, less pool may be needed. Current default is 5.",
123-
"value": 5
124-
},
125-
"pbuf-pool-bufsize": {
126-
"help": "Size of pbufs in pool, see LWIP's opt.h for more information.",
127-
"value": null
128-
},
129121
"mem-size": {
130122
"help": "Size of heap (bytes) - used for outgoing packets, and also used by some drivers for reception, see LWIP's opt.h for more information. Current default is 1600.",
131123
"value": 1600
@@ -193,7 +185,6 @@
193185
"tcp-mss": 1440,
194186
"tcp-snd-buf": "(8 * TCP_MSS)",
195187
"tcp-wnd": "(TCP_MSS * 8)",
196-
"pbuf-pool-size": 16,
197188
"mem-size": 51200
198189
},
199190
"RZ_A2XX": {
@@ -203,7 +194,6 @@
203194
"tcp-mss": 1440,
204195
"tcp-snd-buf": "(8 * TCP_MSS)",
205196
"tcp-wnd": "(TCP_MSS * 8)",
206-
"pbuf-pool-size": 16,
207197
"mem-size": 51200
208198
},
209199
"MCU_PSOC6": {
@@ -216,7 +206,6 @@
216206
"tcp-mss": 1540,
217207
"tcp-snd-buf": "(6 * TCP_MSS)",
218208
"tcp-wnd": "(TCP_MSS * 6)",
219-
"pbuf-pool-size": 14,
220209
"mem-size": 65536
221210
},
222211
"MIMXRT105X": {

connectivity/lwipstack/source/LWIPMemoryManager.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
#include "pbuf.h"
1818
#include "LWIPMemoryManager.h"
1919

20+
#include <LWIPStack.h>
21+
2022
net_stack_mem_buf_t *LWIPMemoryManager::alloc_heap(uint32_t size, uint32_t align)
2123
{
2224
struct pbuf *pbuf = pbuf_alloc(PBUF_RAW, size + align, PBUF_RAM);
@@ -49,6 +51,11 @@ uint32_t LWIPMemoryManager::get_pool_alloc_unit(uint32_t align) const
4951
return alloc_unit;
5052
}
5153

54+
uint32_t LWIPMemoryManager::get_pool_size() const
55+
{
56+
return PBUF_POOL_SIZE;
57+
}
58+
5259
void LWIPMemoryManager::free(net_stack_mem_buf_t *buf)
5360
{
5461
pbuf_free(static_cast<struct pbuf *>(buf));
@@ -105,6 +112,23 @@ void LWIPMemoryManager::set_len(net_stack_mem_buf_t *buf, uint32_t len)
105112
set_total_len(pbuf);
106113
}
107114

115+
NetStackMemoryManager::Lifetime LWIPMemoryManager::get_lifetime(const net_stack_mem_buf_t *buf) const
116+
{
117+
auto const *p = static_cast<const struct pbuf *>(buf);
118+
119+
uint8_t allocSrc = pbuf_get_allocsrc(p);
120+
121+
if (allocSrc == PBUF_TYPE_ALLOC_SRC_MASK_STD_MEMP_PBUF && PBUF_NEEDS_COPY(p)) {
122+
return Lifetime::VOLATILE;
123+
} else if (allocSrc == PBUF_TYPE_ALLOC_SRC_MASK_STD_MEMP_PBUF) {
124+
return Lifetime::CONSTANT;
125+
} else if (allocSrc == PBUF_TYPE_ALLOC_SRC_MASK_STD_MEMP_PBUF_POOL) {
126+
return Lifetime::POOL_ALLOCATED;
127+
} else {
128+
return Lifetime::HEAP_ALLOCATED;
129+
}
130+
}
131+
108132
uint32_t LWIPMemoryManager::count_total_align(uint32_t size, uint32_t align)
109133
{
110134
uint32_t buffers = size / get_pool_alloc_unit(align);
@@ -162,3 +186,8 @@ void LWIPMemoryManager::set_total_len(struct pbuf *pbuf)
162186
pbuf = pbuf->next;
163187
}
164188
}
189+
190+
void mbed_lwip_on_pbuf_pool_free_hook()
191+
{
192+
LWIP::get_instance().get_memory_manager().onPoolSpaceAvailCallback();
193+
}

connectivity/lwipstack/source/LWIPStack.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -550,6 +550,9 @@ nsapi_size_or_error_t LWIP::socket_sendto_control(nsapi_socket_t handle, const S
550550

551551
struct netbuf *buf = netbuf_new();
552552

553+
// Note: netbuf_ref() tells LwIP that it can reference the application-supplied buffer,
554+
// but only until sendto() returns. If it has to hold onto the buffer until later
555+
// (e.g. due to an ARP packet that needs to be sent first), it must copy it.
553556
err_t err = netbuf_ref(buf, data, (u16_t)size);
554557
if (err != ERR_OK) {
555558
netbuf_free(buf);

0 commit comments

Comments
 (0)