[PATCH net v5 4/5] net: dsa: microchip: Free previously initialized ports on init failures

Bastien Curutchet (Schneider Electric) posted 5 patches 1 week, 6 days ago
There is a newer version of this series
[PATCH net v5 4/5] net: dsa: microchip: Free previously initialized ports on init failures
Posted by Bastien Curutchet (Schneider Electric) 1 week, 6 days ago
If a port interrupt setup fails after at least one port has already been
successfully initialized, the gotos miss some resource releasing:
- the already initialized PTP IRQs aren't released
- the already initialized port IRQs aren't released if the failure
occurs in ksz_pirq_setup().

Merge out_ptpirq, out_pirq and out_girq into a single label that
releases all IRQ resources for all initialized ports.
Free the port IRQ inside the initialization loop when
ksz_ptp_irq_setup() fails, since the error path only iterates over the
'fully' initialized ports.

Cc: stable@vger.kernel.org
Fixes: c9cd961c0d43 ("net: dsa: microchip: lan937x: add interrupt support for port phy link")
Signed-off-by: Bastien Curutchet (Schneider Electric) <bastien.curutchet@bootlin.com>
---
 drivers/net/dsa/microchip/ksz_common.c | 26 +++++++++++++-------------
 1 file changed, 13 insertions(+), 13 deletions(-)

diff --git a/drivers/net/dsa/microchip/ksz_common.c b/drivers/net/dsa/microchip/ksz_common.c
index 49827ac770e6fcc9e4a1a11e8814cdd90b17473e..1cb4f35edb49ba4f35ec3ae80fe1699d31540d96 100644
--- a/drivers/net/dsa/microchip/ksz_common.c
+++ b/drivers/net/dsa/microchip/ksz_common.c
@@ -3036,12 +3036,14 @@ static int ksz_setup(struct dsa_switch *ds)
 		dsa_switch_for_each_user_port(dp, dev->ds) {
 			ret = ksz_pirq_setup(dev, dp->index);
 			if (ret)
-				goto out_girq;
+				goto port_release;
 
 			if (dev->info->ptp_capable) {
 				ret = ksz_ptp_irq_setup(ds, dp->index);
-				if (ret)
-					goto out_pirq;
+				if (ret) {
+					ksz_irq_free(&dev->ports[dp->index].pirq);
+					goto port_release;
+				}
 			}
 		}
 	}
@@ -3051,7 +3053,7 @@ static int ksz_setup(struct dsa_switch *ds)
 		if (ret) {
 			dev_err(dev->dev, "Failed to register PTP clock: %d\n",
 				ret);
-			goto out_ptpirq;
+			goto port_release;
 		}
 	}
 
@@ -3074,17 +3076,15 @@ static int ksz_setup(struct dsa_switch *ds)
 out_ptp_clock_unregister:
 	if (dev->info->ptp_capable)
 		ksz_ptp_clock_unregister(ds);
-out_ptpirq:
-	if (dev->irq > 0 && dev->info->ptp_capable)
-		dsa_switch_for_each_user_port(dp, dev->ds)
-			ksz_ptp_irq_free(ds, dp->index);
-out_pirq:
-	if (dev->irq > 0)
-		dsa_switch_for_each_user_port_continue_reverse(dp, dev->ds)
+port_release:
+	if (dev->irq > 0) {
+		dsa_switch_for_each_user_port_continue_reverse(dp, dev->ds) {
+			if (dev->info->ptp_capable)
+				ksz_ptp_irq_free(ds, dp->index);
 			ksz_irq_free(&dev->ports[dp->index].pirq);
-out_girq:
-	if (dev->irq > 0)
+		}
 		ksz_irq_free(&dev->girq);
+	}
 
 	return ret;
 }

-- 
2.51.1
Re: [PATCH net v5 4/5] net: dsa: microchip: Free previously initialized ports on init failures
Posted by Jakub Kicinski 1 week, 4 days ago
On Tue, 18 Nov 2025 17:13:25 +0100 Bastien Curutchet (Schneider
Electric) wrote:
>  			if (dev->info->ptp_capable) {
>  				ret = ksz_ptp_irq_setup(ds, dp->index);
> -				if (ret)
> -					goto out_pirq;
> +				if (ret) {
> +					ksz_irq_free(&dev->ports[dp->index].pirq);
> +					goto port_release;

please jump to the correct location in the unwind loop
it's perfectly normal for kernel code

> +				}
>  			}