[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20220405070413.250573972@linuxfoundation.org>
Date: Tue, 5 Apr 2022 09:25:52 +0200
From: Greg Kroah-Hartman <gregkh@...uxfoundation.org>
To: linux-kernel@...r.kernel.org
Cc: Greg Kroah-Hartman <gregkh@...uxfoundation.org>,
stable@...r.kernel.org, Jan Sondhauss <jan.sondhauss@...o.com>,
Vignesh Raghavendra <vigneshr@...com>,
Jakub Kicinski <kuba@...nel.org>,
Sasha Levin <sashal@...nel.org>
Subject: [PATCH 5.16 0639/1017] drivers: ethernet: cpsw: fix panic when interrupt coaleceing is set via ethtool
From: Sondhauß, Jan <Jan.Sondhauss@...o.com>
[ Upstream commit 2844e2434385819f674d1fb4130c308c50ba681e ]
cpsw_ethtool_begin directly returns the result of pm_runtime_get_sync
when successful.
pm_runtime_get_sync returns -error code on failure and 0 on successful
resume but also 1 when the device is already active. So the common case
for cpsw_ethtool_begin is to return 1. That leads to inconsistent calls
to pm_runtime_put in the call-chain so that pm_runtime_put is called
one too many times and as result leaving the cpsw dev behind suspended.
The suspended cpsw dev leads to an access violation later on by
different parts of the cpsw driver.
Fix this by calling the return-friendly pm_runtime_resume_and_get
function.
Fixes: d43c65b05b84 ("ethtool: runtime-resume netdev parent in ethnl_ops_begin")
Signed-off-by: Jan Sondhauss <jan.sondhauss@...o.com>
Reviewed-by: Vignesh Raghavendra <vigneshr@...com>
Link: https://lore.kernel.org/r/20220323084725.65864-1-jan.sondhauss@wago.com
Signed-off-by: Jakub Kicinski <kuba@...nel.org>
Signed-off-by: Sasha Levin <sashal@...nel.org>
---
drivers/net/ethernet/ti/cpsw_ethtool.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/ti/cpsw_ethtool.c b/drivers/net/ethernet/ti/cpsw_ethtool.c
index 158c8d3793f4..b5bae6324970 100644
--- a/drivers/net/ethernet/ti/cpsw_ethtool.c
+++ b/drivers/net/ethernet/ti/cpsw_ethtool.c
@@ -364,11 +364,9 @@ int cpsw_ethtool_op_begin(struct net_device *ndev)
struct cpsw_common *cpsw = priv->cpsw;
int ret;
- ret = pm_runtime_get_sync(cpsw->dev);
- if (ret < 0) {
+ ret = pm_runtime_resume_and_get(cpsw->dev);
+ if (ret < 0)
cpsw_err(priv, drv, "ethtool begin failed %d\n", ret);
- pm_runtime_put_noidle(cpsw->dev);
- }
return ret;
}
--
2.34.1
Powered by blists - more mailing lists