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: David Daney <david.daney@cavium.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
							parent
							
								
									9277a4f875
								
							
						
					
					
						commit
						b7d3e3d3d2
					
				| @ -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 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user