[PATCH v2] watchdog: starfive: fix runtime PM usage counter leak in pm_start
"Manush Prajwal" <[email protected]>
| Newsgroups | org.kernel.vger.linux-watchdog,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
starfive_wdt_pm_start() calls pm_runtime_get_sync() and returns its error code directly on failure. Per Documentation/power/runtime_pm.rst, pm_runtime_get_sync() does not drop the usage counter on error, so the caller is expected to release the reference itself. The early return here skips that, leaking a runtime PM usage count on wdd->parent on every failed resume, which prevents the device from being suspended correctly afterwards. Fix it by calling pm_runtime_put_noidle() before returning, mirroring the same balance the counterpart starfive_wdt_pm_stop() already maintains with pm_runtime_put_sync(). v1 only balanced the pm_runtime_get_sync() failure path. As Guenter Roeck and the Sashiko AI review both pointed out, the same leak remains if the subsequent starfive_wdt_start() call fails: the runtime PM reference acquired by pm_runtime_get_sync() would still be held while returning an error, again leaving the device unable to suspend. Drop the reference on that failure path too. Signed-off-by: manushprajwal <[email protected]> --- v2: Also drop the pm_runtime reference when starfive_wdt_start() fails, not just when pm_runtime_get_sync() fails, per Guenter Roeck and the Sashiko AI review on v1. drivers/watchdog/starfive-wdt.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/watchdog/starfive-wdt.c b/drivers/watchdog/starfive-wdt.c index af55adc4a..b1c2d3e4f 100644 --- a/drivers/watchdog/starfive-wdt.c +++ b/drivers/watchdog/starfive-wdt.c @@ -373,8 +373,15 @@ static int starfive_wdt_pm_start(struct watchdog_device *wdd) struct starfive_wdt *wdt = watchdog_get_drvdata(wdd); int ret = pm_runtime_get_sync(wdd->parent); - if (ret < 0) + if (ret < 0) { + pm_runtime_put_noidle(wdd->parent); return ret; + } - return starfive_wdt_start(wdt); + ret = starfive_wdt_start(wdt); + if (ret) + pm_runtime_put_noidle(wdd->parent); + + return ret; } -- 2.46.2.windows.1