mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-11 21:14:07 +08:00
phy: fix of_mdio_find_bus() device refcount leak
of_mdio_find_bus() leaks a struct device refcount, caused by using class_find_device() and not realising that the device reference has its refcount incremented: * Note, you will need to drop the reference with put_device() after use. ... while ((dev = class_dev_iter_next(&iter))) { if (match(dev, data)) { get_device(dev); break; } Update the comment, and arrange for the phy code to drop this refcount when disposing of a reference to it. Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
17a10c9215
commit
a136442131
@ -113,18 +113,18 @@ int mdio_mux_init(struct device *dev,
|
|||||||
if (!parent_bus_node)
|
if (!parent_bus_node)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
parent_bus = of_mdio_find_bus(parent_bus_node);
|
|
||||||
if (parent_bus == NULL) {
|
|
||||||
ret_val = -EPROBE_DEFER;
|
|
||||||
goto err_parent_bus;
|
|
||||||
}
|
|
||||||
|
|
||||||
pb = devm_kzalloc(dev, sizeof(*pb), GFP_KERNEL);
|
pb = devm_kzalloc(dev, sizeof(*pb), GFP_KERNEL);
|
||||||
if (pb == NULL) {
|
if (pb == NULL) {
|
||||||
ret_val = -ENOMEM;
|
ret_val = -ENOMEM;
|
||||||
goto err_parent_bus;
|
goto err_parent_bus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
parent_bus = of_mdio_find_bus(parent_bus_node);
|
||||||
|
if (parent_bus == NULL) {
|
||||||
|
ret_val = -EPROBE_DEFER;
|
||||||
|
goto err_parent_bus;
|
||||||
|
}
|
||||||
|
|
||||||
pb->switch_data = data;
|
pb->switch_data = data;
|
||||||
pb->switch_fn = switch_fn;
|
pb->switch_fn = switch_fn;
|
||||||
pb->current_child = -1;
|
pb->current_child = -1;
|
||||||
@ -173,6 +173,10 @@ int mdio_mux_init(struct device *dev,
|
|||||||
dev_info(dev, "Version " DRV_VERSION "\n");
|
dev_info(dev, "Version " DRV_VERSION "\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* balance the reference of_mdio_find_bus() took */
|
||||||
|
put_device(&pb->mii_bus->dev);
|
||||||
|
|
||||||
err_parent_bus:
|
err_parent_bus:
|
||||||
of_node_put(parent_bus_node);
|
of_node_put(parent_bus_node);
|
||||||
return ret_val;
|
return ret_val;
|
||||||
@ -189,6 +193,9 @@ void mdio_mux_uninit(void *mux_handle)
|
|||||||
mdiobus_free(cb->mii_bus);
|
mdiobus_free(cb->mii_bus);
|
||||||
cb = cb->next;
|
cb = cb->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* balance the reference of_mdio_find_bus() in mdio_mux_init() took */
|
||||||
|
put_device(&pb->mii_bus->dev);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(mdio_mux_uninit);
|
EXPORT_SYMBOL_GPL(mdio_mux_uninit);
|
||||||
|
|
||||||
|
@ -167,7 +167,9 @@ static int of_mdio_bus_match(struct device *dev, const void *mdio_bus_np)
|
|||||||
* of_mdio_find_bus - Given an mii_bus node, find the mii_bus.
|
* of_mdio_find_bus - Given an mii_bus node, find the mii_bus.
|
||||||
* @mdio_bus_np: Pointer to the mii_bus.
|
* @mdio_bus_np: Pointer to the mii_bus.
|
||||||
*
|
*
|
||||||
* Returns a pointer to the mii_bus, or NULL if none found.
|
* Returns a reference to the mii_bus, or NULL if none found. The
|
||||||
|
* embedded struct device will have its reference count incremented,
|
||||||
|
* and this must be put once the bus is finished with.
|
||||||
*
|
*
|
||||||
* Because the association of a device_node and mii_bus is made via
|
* Because the association of a device_node and mii_bus is made via
|
||||||
* of_mdiobus_register(), the mii_bus cannot be found before it is
|
* of_mdiobus_register(), the mii_bus cannot be found before it is
|
||||||
|
Loading…
Reference in New Issue
Block a user