spl2sw_probe() acquires three of_node references that are never properly released in all paths: - eth_ports_np from of_get_child_by_name() leaks on every probe. - port_np returned from spl2sw_get_eth_child_node() (which exits a for_each_child_of_node() loop mid-iteration) leaks per loop pass. - phy_np from of_parse_phandle() leaks on the -EPROBE_DEFER and spl2sw_init_netdev() failure goto paths, and the registered netdev's mac->phy_node is not released on the out_unregister_dev cleanup path. Convert eth_ports_np and port_np to scoped __free(device_node), add explicit of_node_put(phy_np) on the two early-error gotos where ownership has not yet been transferred to mac->phy_node, and release each registered ndev's mac->phy_node in the out_unregister_dev loop before unregister_netdev(). The mac->phy_node release in the normal driver-remove path is handled by patch 1/2. Compile-tested only; no SP7021 hardware available. Fixes: fd3040b9394c ("net: ethernet: Add driver for Sunplus SP7021") Signed-off-by: Shitalkumar Gandhi --- drivers/net/ethernet/sunplus/spl2sw_driver.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/drivers/net/ethernet/sunplus/spl2sw_driver.c b/drivers/net/ethernet/sunplus/spl2sw_driver.c index 5e0e4c9ecbb0..d78bda050ee4 100644 --- a/drivers/net/ethernet/sunplus/spl2sw_driver.c +++ b/drivers/net/ethernet/sunplus/spl2sw_driver.c @@ -319,10 +319,8 @@ static struct device_node *spl2sw_get_eth_child_node(struct device_node *ether_n static int spl2sw_probe(struct platform_device *pdev) { - struct device_node *eth_ports_np; - struct device_node *port_np; + struct device_node *eth_ports_np __free(device_node) = NULL; struct spl2sw_common *comm; - struct device_node *phy_np; phy_interface_t phy_mode; struct net_device *ndev; struct spl2sw_mac *mac; @@ -418,8 +416,10 @@ static int spl2sw_probe(struct platform_device *pdev) } for (i = 0; i < MAX_NETDEV_NUM; i++) { - /* Get port@i of node ethernet-ports. */ - port_np = spl2sw_get_eth_child_node(eth_ports_np, i); + struct device_node *port_np __free(device_node) = + spl2sw_get_eth_child_node(eth_ports_np, i); + struct device_node *phy_np; + if (!port_np) continue; @@ -441,6 +441,7 @@ static int spl2sw_probe(struct platform_device *pdev) /* Get mac-address from nvmem. */ ret = spl2sw_nvmem_get_mac_address(&pdev->dev, port_np, mac_addr); if (ret == -EPROBE_DEFER) { + of_node_put(phy_np); goto out_unregister_dev; } else if (ret) { dev_info(&pdev->dev, "Generate a random mac address!\n"); @@ -449,8 +450,10 @@ static int spl2sw_probe(struct platform_device *pdev) /* Initialize the net device. */ ret = spl2sw_init_netdev(pdev, mac_addr, &ndev); - if (ret) + if (ret) { + of_node_put(phy_np); goto out_unregister_dev; + } ndev->irq = irq; comm->ndev[i] = ndev; @@ -500,8 +503,11 @@ static int spl2sw_probe(struct platform_device *pdev) out_unregister_dev: for (i = 0; i < MAX_NETDEV_NUM; i++) - if (comm->ndev[i]) + if (comm->ndev[i]) { + mac = netdev_priv(comm->ndev[i]); + of_node_put(mac->phy_node); unregister_netdev(comm->ndev[i]); + } out_free_mdio: spl2sw_mdio_remove(comm); -- 2.25.1