Re: [OpenWrt-Devel] [PATCH] b53 switch driver memory leak and reset gpio pin initialization fix

2015-06-13 Thread blmink

Hi, Jonas
I inserted trace points (pr_info) at functions in b53_common and figured 
out that driver behave wrong.

Please have a look at this:

~~~cut~~~
root@(none):/# uname -a
Linux (none) 4.0.4 #1 SMP Sat Jun 13 02:59:36 MSK 2015 mips64 GNU/Linux
root@(none):/#
root@(none):/# ifconfig eth0 up
[   15.561304] b53_common: b53_switch_alloc
[   15.565265] b53_common: b53_switch_register
[   15.569960] b53_common: b53_switch_init
[   15.650583] b53_common: found switch: BCM53115, rev 8
[   15.659538] eth0: 1000 Mbps Full duplex, port 0
[   15.664439] eth1: 1000 Mbps Full duplex, port  1, queue  1
root@(none):/#
root@(none):/# root@(none):/# ifconfig eth0 down
[   42.697656] eth0: Link down
[   42.700742] eth0: 1000 Mbps Full duplex, port  0, queue  0
root@(none):/#
root@(none):/# ifconfig eth0 down
root@(none):/# ifconfig eth0 up
[   49.145311] b53_common: b53_switch_alloc
[   49.149267] b53_common: b53_switch_register
[   49.153972] b53_common: b53_switch_init
[   49.160932] Broadcom B53 (1) 800118001800:1e: failed to register 
switch: -16

ifconfig: SIOCSIFFLAGS: No such device
root@(none):/# reboot
~~~cut~~~

We can see that "ifconfig up" calls b53_switch_alloc which calls 
devm_kzalloc in sequence.

b53_switch_alloc is called by following sequence:
"ifconfig up" --> b53_mdio driver probe/register --> b53_phy_config_init 
--> b53_switch_alloc
Driver removes never (in case of "ifconfig down" either) and it do not 
free memory.

So,  in our example we have b53_switch_alloc called twice in a row.

As for switch gpio reset.. "failed to register switch: -16" is from 
devm_gpio_request_one().

-16 is EBUSY (Device or resource busy).

My system is D-Link DSR-1000 (Cavium Octeon MIPS64), I have added 
support for it.

But things described above affect any platform.

Please also see comments below.


13.06.2015 01:57, Jonas Gorski пишет:

Hi,

On Fri, Jun 12, 2015 at 8:16 PM, Fedor Konstantinov  wrote:

Memory and switch reset gpio pin must be allocated on switch/module init and 
freed on removal. At least they should not be allocated 2 or more times in a 
row.

Signed-off-by: Fedor Konstantinov 
---
Comments:

Following cmd sequence calls b53_switch_init() twice, so causes leak of memory.
Last ifconfig will fail also on targets which support switch reset gpio pin, 
because devm_gpio_request_one() will be called twice in a row.
ifconfig eth0 up
ifconfig eth0 down
ifconfig eth0 up

On what platform? This also requires a better explanation why this is
the correct fix.

These affect any platform.

mmap/spi/srab drivers were not tested yet because I don't have such hardware.
---
  .../generic/files/drivers/net/phy/b53/b53_common.c | 19 +++
  .../generic/files/drivers/net/phy/b53/b53_mdio.c   |  6 +
  .../generic/files/drivers/net/phy/b53/b53_mmap.c   | 28 +-
  .../generic/files/drivers/net/phy/b53/b53_priv.h   |  7 +++---
  .../generic/files/drivers/net/phy/b53/b53_spi.c| 20 
  .../generic/files/drivers/net/phy/b53/b53_srab.c   | 28 +-
  6 files changed, 88 insertions(+), 20 deletions(-)

diff --git a/target/linux/generic/files/drivers/net/phy/b53/b53_common.c 
b/target/linux/generic/files/drivers/net/phy/b53/b53_common.c
index 47b5a8b..2e2f6aa 100644
--- a/target/linux/generic/files/drivers/net/phy/b53/b53_common.c
+++ b/target/linux/generic/files/drivers/net/phy/b53/b53_common.c
@@ -1362,6 +1362,12 @@ struct b53_device *b53_switch_alloc(struct device *base, 
struct b53_io_ops *ops,
  }
  EXPORT_SYMBOL(b53_switch_alloc);

+void b53_switch_free(struct device *dev, struct b53_device *priv)
+{
+   devm_kfree(dev, priv);
+}
+EXPORT_SYMBOL(b53_switch_free);
+
  int b53_switch_detect(struct b53_device *dev)
  {
 u32 id32;
@@ -1452,6 +1458,19 @@ int b53_switch_register(struct b53_device *dev)
  }
  EXPORT_SYMBOL(b53_switch_register);

+void b53_switch_remove(struct b53_device *dev)
+{
+   unregister_switch(&dev->sw_dev);
+
+   if (dev->reset_gpio >= 0)
+   devm_gpio_free(dev->dev, dev->reset_gpio);
+
+   devm_kfree(dev->dev, dev->buf);
+   devm_kfree(dev->dev, dev->vlans);
+   devm_kfree(dev->dev, dev->ports);
+}
+EXPORT_SYMBOL(b53_switch_remove);

These look wrong, the whole point of using devm_* is that you do *not*
need to free the resources manually and it will be automatically done
on removal or probe failure.
Removal occurs never, unfortunately. But memory may be allocated several 
times. :(
In our case "ifconfig down" doesn't remove driver. But "ifconfig up" 
allocates memory.

+
  MODULE_AUTHOR("Jonas Gorski ");
  MODULE_DESCRIPTION("B53 switch library");
  MODULE_LICENSE("Dual BSD/GPL");
diff --git a/target/linux/generic/files/drivers/net/phy/b53/b53_mdio.c 
b/target/linux/generic/files/drivers/net/phy/b53/b53_mdio.c
index 3c25f0e..9a5f058 100644
--- a/target/linux/generic/files/drivers/net/phy/b53/b53_mdio.c
+++ b/target/linux/generic/files/drivers/net/phy/b53/b53_mdio.c
@@ -285,6 +285,10 @@ 

[OpenWrt-Devel] [PATCH] b53 kernel memory corruption fix

2015-06-09 Thread blmink

Hi,

this patch fixes kernel memory corruption in b53 driver during device 
global reset, which causes kernel panic especially on 64bit platforms.


Signed-off-by: Fedor Konstantinov 
---
Index: target/linux/generic/files/drivers/net/phy/b53/b53_common.c
===
--- target/linux/generic/files/drivers/net/phy/b53/b53_common.c 
(revision 45932)
+++ target/linux/generic/files/drivers/net/phy/b53/b53_common.c	(working 
copy)

@@ -803,8 +803,8 @@
priv->enable_jumbo = 0;
priv->allow_vid_4095 = 0;

-   memset(priv->vlans, 0, sizeof(priv->vlans) * dev->vlans);
-   memset(priv->ports, 0, sizeof(priv->ports) * dev->ports);
+   memset(priv->vlans, 0, sizeof(struct b53_vlan) * dev->vlans);
+   memset(priv->ports, 0, sizeof(struct b53_port) * dev->ports);

return b53_switch_reset(priv);
 }
___
openwrt-devel mailing list
openwrt-devel@lists.openwrt.org
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel