Commit ee0475a5 authored by David S. Miller's avatar David S. Miller

Merge branch 'phy-ref-leaks'

Johan Hovold says:

====================
net: fix device reference leaks

This series fixes a number of device reference leaks (and one of_node
leak) due to failure to drop the references taken by bus_find_device()
and friends.

Note that the final two patches have been compile tested only.

v2
 - hold reference to cpsw-phy-sel device while accessing private data as
   requested by David. Also update the commit message. (patch 1/4)
 - add linux-omap on CC where appropriate
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 6a0c9f68 2271150b
...@@ -332,8 +332,10 @@ struct hnae_handle *hnae_get_handle(struct device *owner_dev, ...@@ -332,8 +332,10 @@ struct hnae_handle *hnae_get_handle(struct device *owner_dev,
return ERR_PTR(-ENODEV); return ERR_PTR(-ENODEV);
handle = dev->ops->get_handle(dev, port_id); handle = dev->ops->get_handle(dev, port_id);
if (IS_ERR(handle)) if (IS_ERR(handle)) {
put_device(&dev->cls_dev);
return handle; return handle;
}
handle->dev = dev; handle->dev = dev;
handle->owner_dev = owner_dev; handle->owner_dev = owner_dev;
...@@ -356,6 +358,8 @@ struct hnae_handle *hnae_get_handle(struct device *owner_dev, ...@@ -356,6 +358,8 @@ struct hnae_handle *hnae_get_handle(struct device *owner_dev,
for (j = i - 1; j >= 0; j--) for (j = i - 1; j >= 0; j--)
hnae_fini_queue(handle->qs[j]); hnae_fini_queue(handle->qs[j]);
put_device(&dev->cls_dev);
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
} }
EXPORT_SYMBOL(hnae_get_handle); EXPORT_SYMBOL(hnae_get_handle);
...@@ -377,6 +381,8 @@ void hnae_put_handle(struct hnae_handle *h) ...@@ -377,6 +381,8 @@ void hnae_put_handle(struct hnae_handle *h)
dev->ops->put_handle(h); dev->ops->put_handle(h);
module_put(dev->owner); module_put(dev->owner);
put_device(&dev->cls_dev);
} }
EXPORT_SYMBOL(hnae_put_handle); EXPORT_SYMBOL(hnae_put_handle);
......
...@@ -176,9 +176,12 @@ void cpsw_phy_sel(struct device *dev, phy_interface_t phy_mode, int slave) ...@@ -176,9 +176,12 @@ void cpsw_phy_sel(struct device *dev, phy_interface_t phy_mode, int slave)
} }
dev = bus_find_device(&platform_bus_type, NULL, node, match); dev = bus_find_device(&platform_bus_type, NULL, node, match);
of_node_put(node);
priv = dev_get_drvdata(dev); priv = dev_get_drvdata(dev);
priv->cpsw_phy_sel(priv, phy_mode, slave); priv->cpsw_phy_sel(priv, phy_mode, slave);
put_device(dev);
} }
EXPORT_SYMBOL_GPL(cpsw_phy_sel); EXPORT_SYMBOL_GPL(cpsw_phy_sel);
......
...@@ -1410,6 +1410,7 @@ static int emac_dev_open(struct net_device *ndev) ...@@ -1410,6 +1410,7 @@ static int emac_dev_open(struct net_device *ndev)
int i = 0; int i = 0;
struct emac_priv *priv = netdev_priv(ndev); struct emac_priv *priv = netdev_priv(ndev);
struct phy_device *phydev = NULL; struct phy_device *phydev = NULL;
struct device *phy = NULL;
ret = pm_runtime_get_sync(&priv->pdev->dev); ret = pm_runtime_get_sync(&priv->pdev->dev);
if (ret < 0) { if (ret < 0) {
...@@ -1488,19 +1489,20 @@ static int emac_dev_open(struct net_device *ndev) ...@@ -1488,19 +1489,20 @@ static int emac_dev_open(struct net_device *ndev)
/* use the first phy on the bus if pdata did not give us a phy id */ /* use the first phy on the bus if pdata did not give us a phy id */
if (!phydev && !priv->phy_id) { if (!phydev && !priv->phy_id) {
struct device *phy;
phy = bus_find_device(&mdio_bus_type, NULL, NULL, phy = bus_find_device(&mdio_bus_type, NULL, NULL,
match_first_device); match_first_device);
if (phy) if (phy) {
priv->phy_id = dev_name(phy); priv->phy_id = dev_name(phy);
if (!priv->phy_id || !*priv->phy_id)
put_device(phy);
}
} }
if (!phydev && priv->phy_id && *priv->phy_id) { if (!phydev && priv->phy_id && *priv->phy_id) {
phydev = phy_connect(ndev, priv->phy_id, phydev = phy_connect(ndev, priv->phy_id,
&emac_adjust_link, &emac_adjust_link,
PHY_INTERFACE_MODE_MII); PHY_INTERFACE_MODE_MII);
put_device(phy); /* reference taken by bus_find_device */
if (IS_ERR(phydev)) { if (IS_ERR(phydev)) {
dev_err(emac_dev, "could not connect to phy %s\n", dev_err(emac_dev, "could not connect to phy %s\n",
priv->phy_id); priv->phy_id);
......
...@@ -723,6 +723,7 @@ struct phy_device *phy_connect(struct net_device *dev, const char *bus_id, ...@@ -723,6 +723,7 @@ struct phy_device *phy_connect(struct net_device *dev, const char *bus_id,
phydev = to_phy_device(d); phydev = to_phy_device(d);
rc = phy_connect_direct(dev, phydev, handler, interface); rc = phy_connect_direct(dev, phydev, handler, interface);
put_device(d);
if (rc) if (rc)
return ERR_PTR(rc); return ERR_PTR(rc);
...@@ -953,6 +954,7 @@ struct phy_device *phy_attach(struct net_device *dev, const char *bus_id, ...@@ -953,6 +954,7 @@ struct phy_device *phy_attach(struct net_device *dev, const char *bus_id,
phydev = to_phy_device(d); phydev = to_phy_device(d);
rc = phy_attach_direct(dev, phydev, phydev->dev_flags, interface); rc = phy_attach_direct(dev, phydev, phydev->dev_flags, interface);
put_device(d);
if (rc) if (rc)
return ERR_PTR(rc); return ERR_PTR(rc);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment