Sebastien Baron

LPC17xx-40xx emac driver memory leak on TX (found and fixed)

Discussion created by Sebastien Baron on Mar 8, 2020
Latest reply on Jul 20, 2020 by Craig McQueen

Hello,

 

I have found and fixed a memory leak in the EMAC driver, in file lpc17xx_40xx_emac.c.
Note: I have NO_SYS=1 and LPC_NUM_BUFF_TXDESCS=4

 

The memory leak happens when 4 calls of the lpc_low_level_output() functions are performed from the LWIP stack before returning to the user code (for example the ARP protocol adds some packets each ARP_AGE_REREQUEST_USED_UNICAST seconds).
Then if the user code spends some time doing other things, the CONSUME register can make a 'full loop' and go back to its original value.
When this happens, the lpc_tx_reclaim() function does not detect it and returns immediately leaving 4 pbuf which pointers will be overwritten at the next lpc_low_level_output() calls. These pbuf will never be freed.

 

To fix this, I have added the following code inside the lpc_low_level_output() function:

 

        if (dn == 0) {
              /* Save size of packet and signal it's ready */
              lpc_enetif->ptxd[idx].Control = ENET_TCTRL_SIZE(q->len) | ENET_TCTRL_INT |
                                              ENET_TCTRL_LAST;
// NEW CODE
            if (lpc_enetif->txb[idx] != NULL) {
              pbuf_free(lpc_enetif->txb[idx]);
            }
// END NEW CODE

 

            lpc_enetif->txb[idx] = p;
          }

 

Note that calling the lpc_tx_reclaim() function is not needed any more, although it can be a good idea to free the pbuf on idle time, rather than at the time we need to send a packet.

 

Thank you,
Sébastien

Outcomes