Note this also occurs in MQX 4.2.0.1
I would be grateful if a freescale member could validate the fixes I’ve applied to the rtcs files below.
Issue
Our product uses a GPRS modem to send UDP data. When the modem sends us a disconnect we close the connection to the modem and then attempt to re-connect again. Every time the IP connection to the modem was established the software grabbed another 944B. The spare RAM we had could quickly disappear it eventually lost GPRS connectivity.
I turned on kernel logging and found 2 memory free calls that failed due to MQX_NOT_RESOURCE_OWNER in the task that makes the PPP connection.
Using break points I tracked the memory leak down to the PPP_init() PPP_release() functions.
The following list is the difference in the memory blocks between having never called PPP_init() and calling PPP_init() & PPP_release() twice:
0x20008d50 0x260 608 0x10013
0x20008fd0 0x10 16 0x10013
0x20009000 0x20 32 0x10013
0x20009040 0xd0 208 0x10013
0x20009130 0x260 608 0x10013
0x200093f0 0xd0 208 0x10013
Stepping through the PPP_release() function I tracked the MQX_NOT_RESOURCE_OWNER errors down to the following calls (note that the call stack shows a different build to the Memory Block Summary shown above):
The above two blocks that couldn’t be freed (twice) are the 208B and 608B blocks. The _mem_free() reckons that the ModemDialupTask (0x10013) doesn’t own the blocks, but the Memory Block Summary clearly states they are owned by 0x10013 and it is currently in that same task!
The 16B and 30B blocks left are simply due to the fact the PPP_release didn’t free up a pointer that was allocated memory in PPP_init().
Solution
I could not work out why the _mem_free() kept failing with MQX_NOT_RESOURCE_OWNER as the current task did own the memory block, so I simply forced the memory allocation functions to use system memory instead and added the missing memory free in function PPP_release().
Code changes:
In “Freescale_MQX_4_1\rtcs\source\include\ppphdlc.h” I changed:
#define PPPHDLC_memalloc _mem_alloc_zero
to be
#define PPPHDLC_memalloc _mem_alloc_system_zero
In “\Freescale_MQX_4_1\rtcs\source\ppp\ppp.c” function PPP_init() I changed:
ppp_ptr = _mem_alloc_zero(sizeof(PPP_CFG));
to be
ppp_ptr = _mem_alloc_system_zero(sizeof(PPP_CFG));
and
ppp_ptr->DEVICE_NAME = _mem_alloc_zero(strlen(params->device)+1);
to be
ppp_ptr->DEVICE_NAME = _mem_alloc_system_zero(strlen(params->device)+1);
In “\Freescale_MQX_4_1\rtcs\source\ppp\ppp.c” function PPP_release() I added the following line just before “PPP_memfree(handle);”:
PPP_memfree(ppp_ptr->DEVICE_NAME);
These changes cured the memory leaks, but is changing private memory to system memory ok?
Hi Graeme,
I have looked through the code. I think the problem occurs only when PPP_init() and PPP_release() are called by different tasks since private memory can only be freed by its owner. I would suggest to control PPP by one specific task. However, it's also fine if they are done by different tasks and using system memory allocation.
Regarding the memory leak of ppp_ptr->DEVICE_NAME, it should be freed before freeing the PPP handle. The code below should be added:
if (ppp_ptr->DEVICE_NAME) {
_mem_free(ppp_ptr->DEVICE_NAME);
}
Hi, Joseph
Thanks for looking at this, however, as I stated, PPP_init() and PPP_release() are being called by the same task. I do not know why _mem_free() thinks it isn't.
Also I do call PPP_memfree(ppp_ptr->DEVICE_NAME) before calling PPP_memfree(handle). I will add the "if (ppp_ptr->DEVICE_NAME)" check though, thanks :smileyhappy:
Hi Graeme,
FYI - I reported this to the MQX Development team to look into as well.
Regards,
David