IB/ipoib: Fix memory leaks for child interfaces priv
authorAlex Vesker <valex@mellanox.com>
Wed, 14 Jun 2017 06:59:05 +0000 (09:59 +0300)
committerDoug Ledford <dledford@redhat.com>
Wed, 14 Jun 2017 19:16:23 +0000 (15:16 -0400)
There is a need to free priv explicitly and not just to release
the device, child priv is freed explicitly on remove flow and this
patch also includes priv free on error flow in P_key creation
and also in add_port.

Fixes: cd565b4b51e5 ('IB/IPoIB: Support acceleration options callbacks')
Signed-off-by: Alex Vesker <valex@mellanox.com>
Signed-off-by: Leon Romanovsky <leon@kernel.org>
Signed-off-by: Doug Ledford <dledford@redhat.com>
drivers/infiniband/ulp/ipoib/ipoib_main.c
drivers/infiniband/ulp/ipoib/ipoib_vlan.c

index a115c0b7a310ed630c1c32ffd9e2c17574358f7c..0ddd9709e1df9e44f84bd5c648804a7437f8945d 100644 (file)
@@ -2237,6 +2237,7 @@ event_failed:
 
 device_init_failed:
        free_netdev(priv->dev);
+       kfree(priv);
 
 alloc_mem_failed:
        return ERR_PTR(result);
@@ -2277,7 +2278,7 @@ static void ipoib_add_one(struct ib_device *device)
 
 static void ipoib_remove_one(struct ib_device *device, void *client_data)
 {
-       struct ipoib_dev_priv *priv, *tmp;
+       struct ipoib_dev_priv *priv, *tmp, *cpriv, *tcpriv;
        struct list_head *dev_list = client_data;
 
        if (!dev_list)
@@ -2301,6 +2302,10 @@ static void ipoib_remove_one(struct ib_device *device, void *client_data)
 
                unregister_netdev(priv->dev);
                free_netdev(priv->dev);
+
+               list_for_each_entry_safe(cpriv, tcpriv, &priv->child_intfs, list)
+                       kfree(cpriv);
+
                kfree(priv);
        }
 
index 36dc4fcaa3cdbcd2516d44fb9360c5dcccce1404..1ee46194bbf586c56819a2d138e2d627049c72d6 100644 (file)
@@ -167,8 +167,10 @@ out:
 
        rtnl_unlock();
 
-       if (result)
+       if (result) {
                free_netdev(priv->dev);
+               kfree(priv);
+       }
 
        return result;
 }
@@ -209,6 +211,7 @@ int ipoib_vlan_delete(struct net_device *pdev, unsigned short pkey)
 
        if (dev) {
                free_netdev(dev);
+               kfree(priv);
                return 0;
        }