Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b7d3e3d3 authored by David Daney's avatar David Daney Committed by David S. Miller
Browse files

net: thunderx: Don't leak phy device references on -EPROBE_DEFER condition.



It is possible, although unlikely, that probing will find the
phy_device for the first LMAC of a thunder BGX device, but then need
to fail with -EPROBE_DEFER on a subsequent LMAC.  In this case, we
need to call put_device() on each of the phy_devices that were
obtained, but will be unused due to returning -EPROBE_DEFER.

Also, since we can break out of the probing loop early, we need to
explicitly call of_node_put() outside of the loop.

Signed-off-by: default avatarDavid Daney <david.daney@cavium.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 9277a4f8
Loading
Loading
Loading
Loading
+20 −6
Original line number Diff line number Diff line
@@ -974,17 +974,18 @@ static int bgx_init_acpi_phy(struct bgx *bgx)
static int bgx_init_of_phy(struct bgx *bgx)
{
	struct fwnode_handle *fwn;
	struct device_node *node = NULL;
	u8 lmac = 0;
	const char *mac;

	device_for_each_child_node(&bgx->pdev->dev, fwn) {
		struct phy_device *pd;
		struct device_node *phy_np;
		struct device_node *node = to_of_node(fwn);
		const char *mac;

		/* Should always be an OF node.  But if it is not, we
		 * cannot handle it, so exit the loop.
		 */
		node = to_of_node(fwn);
		if (!node)
			break;

@@ -1005,17 +1006,30 @@ static int bgx_init_of_phy(struct bgx *bgx)
			/* Wait until the phy drivers are available */
			pd = of_phy_find_device(phy_np);
			if (!pd)
				return -EPROBE_DEFER;
				goto defer;
			bgx->lmac[lmac].phydev = pd;
		}

		lmac++;
		if (lmac == MAX_LMAC_PER_BGX) {
			of_node_put(node);
		if (lmac == MAX_LMAC_PER_BGX)
			break;
	}
	}
	of_node_put(node);
	return 0;

defer:
	/* We are bailing out, try not to leak device reference counts
	 * for phy devices we may have already found.
	 */
	while (lmac) {
		if (bgx->lmac[lmac].phydev) {
			put_device(&bgx->lmac[lmac].phydev->mdio.dev);
			bgx->lmac[lmac].phydev = NULL;
		}
		lmac--;
	}
	of_node_put(node);
	return -EPROBE_DEFER;
}

#else