Possible memory leak in cpu/ppc4xx/4xx_enet.c
Hi all,
I've seen an issue with my 1.3.1-based port of U-Boot where a relatively large number of pings issued from the command line will ultimately fail with the message:
Cannot allocate private hw data for eth_device...
I looked around this message and it seems that ppc_4xx_eth_initialize() malloc()?s a EMAC_4XX_HW_PST structure and assigns it to dev->priv. However, nothing ever frees this buffer so standing on a ping will ultimately pull down all the available memory.
One fix might be to free( dev->priv ) at the end of ppc_4xx_eth_halt().
I tried this today and noted no ill effects.
Thanks,
Dave
Dave,
Quoted 10 lines · Dave Littell
I've seen an issue with my 1.3.1-based port of U-Boot where a relatively large number of pings issued from the command line will ultimately fail with the message:
Cannot allocate private hw data for
eth_device...I looked around this message and it seems that
ppc_4xx_eth_initialize()malloc()?s aEMAC_4XX_HW_PSTstructure and assigns it todev->priv. However, nothing ever frees this buffer so standing on a ping will ultimately pull down all the available memory.
Hmmm. IIRC ppc_4xx_eth_initialize() is only called once upon bootup for ethernet driver initialization. The function called each time before network action is ppc_4xx_eth_init().
Quoted 2 lines
One fix might be to
free( dev->priv )at the end ofppc_4xx_eth_halt().
I tried this today and noted no ill effects.
So did it work for you?
Best regards,
Stefan
=====================================================================
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-0 Fax: +49-8142-66989-80 Email: office at denx.de
=====================================================================
Quoted 9 lines · Stefan Roese
Dave,
Quoted 6 lines · Dave Littell
I've seen an issue with my 1.3.1-based port of U-Boot where a relatively large number of pings issued from the command line will ultimately fail with the message:
Cannot allocate private hw data for
eth_device...
Quoted 9 lines
Quoted 4 lines
I looked around this message and it seems that
ppc_4xx_eth_initialize()malloc()?s aEMAC_4XX_HW_PSTstructure and assigns it todev->priv. However, nothing ever frees this buffer so standing on a ping will ultimately pull down all the available memory.Hmmm. IIRC
ppc_4xx_eth_initialize()is only called once upon bootup for ethernet driver initialization. The function called each time before network action isppc_4xx_eth_init().
It looks like ppc_4xx_eth_initialize() is called from eth_init() and ppc_4xx_eth_init() is only called if there's an emac0_dev.
Hm?
Quoted 5 lines
Quoted 2 lines
One fix might be to
free( dev->priv )at the end ofppc_4xx_eth_halt().
I tried this today and noted no ill effects.So did it work for you?
It seems to be working well.
Thanks,
Dave
Quoted 5 lines · Dave Littell
Quoted 5 lines
Quoted 4 lines
I looked around this message and it seems that
ppc_4xx_eth_initialize()malloc()?s aEMAC_4XX_HW_PSTstructure and assigns it todev->priv. However, nothing ever frees this buffer so standing on a ping will ultimately pull down all the available memory.
Quoted 8 lines
Quoted 3 lines
Hmmm. IIRC
ppc_4xx_eth_initialize()is only called once upon bootup for ethernet driver initialization. The function called each time before network action isppc_4xx_eth_init().It looks like
ppc_4xx_eth_initialize()is called frometh_init()andppc_4xx_eth_init()is only called if there's anemac0_dev.Hm?
I see. You don't have CONFIG_NET_MULTI defined. Which 4xx platform are we talking about btw?
Quoted 6 lines
Quoted 4 lines
Quoted 2 lines
One fix might be to
free( dev->priv )at the end ofppc_4xx_eth_halt().
I tried this today and noted no ill effects.So did it work for you?
It seems to be working well.
OK. But your patch will most likely break all platforms with CONFIG_NET_MULTI defined. Please give the attached patch a try and let me know if it works too. I'll push it online if it fixes the problem.
cpu/ppc4xx/4xx_enet.c +4 -1
@@ -1998,9 +1998,12 @@ int ppc_4xx_eth_initialize (bd_t * bis) }#if !defined(CONFIG_NET_MULTI ) -void eth_halt (void ) { +void eth_halt (void ) +{if (emac0_dev) {ppc_4xx_eth_halt (emac0_dev); +if (emac0_dev->priv) +free (emac0_dev->priv);free (emac0_dev); emac0_dev =NULL ; }
Best regards,
Stefan
=====================================================================
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-0 Fax: +49-8142-66989-80 Email: office at denx.de
=====================================================================
Quoted 8 lines · Stefan Roese
Quoted 7 lines · Dave Littell
Quoted 7 lines
Quoted 4 lines
I looked around this message and it seems that
ppc_4xx_eth_initialize()malloc()?s aEMAC_4XX_HW_PSTstructure and assigns it todev->priv. However, nothing ever frees this buffer so standing on a ping will ultimately pull down all the available memory.Hmmm. IIRC
ppc_4xx_eth_initialize()is only called once upon bootup for ethernet driver initialization. The function called each time before network action isppc_4xx_eth_init().
Quoted 8 lines
Quoted 4 lines
It looks like
ppc_4xx_eth_initialize()is called frometh_init()andppc_4xx_eth_init()is only called if there's anemac0_dev.Hm?
I see. You don't have
CONFIG_NET_MULTIdefined. Which 4xx platform are we talking about btw?
This is a platform similar to the AMCC sequoia, but CONFIG_NET_MULTI is not defined.
Quoted 9 lines
Quoted 4 lines
Quoted 3 lines
Quoted 2 lines
One fix might be to
free( dev->priv )at the end ofppc_4xx_eth_halt().
I tried this today and noted no ill effects.So did it work for you?
It seems to be working well.
OK. But your patch will most likely break all platforms with
CONFIG_NET_MULTIdefined. Please give the attached patch a try and let me know if it works too. I'll push it online if it fixes the problem.
It does indeed seem to work - thanks!
Quoted 10 lines
cpu/ppc4xx/4xx_enet.c +0
-0@@ -1998,9 +1998,12 @@ int ppc_4xx_eth_initialize (bd_t * bis) }#if !defined(CONFIG_NET_MULTI )
cpu/ppc4xx/4xx_enet.c int ppc_4xx_eth_initialize (bd_t * bis) · line 2009
Quoted 10 lines
cpu/ppc4xx/4xx_enet.c +4
-1-void eth_halt (void ) { +void eth_halt (void ) +{if (emac0_dev) {ppc_4xx_eth_halt (emac0_dev); +if (emac0_dev->priv) +free (emac0_dev->priv);free (emac0_dev); emac0_dev =NULL ; }
Thanks,
Dave