[PATCH net-next v3 3/3] net: stmmac: hold runtime PM reference in setup_tc
Lorenzo Bianconi
lorenzo.bianconi at oss.qualcomm.com
Sat Aug 8 07:49:59 PDT 2026
The qdisc offload callbacks invoked by stmmac_setup_tc() program
MTL/MAC registers, but they can be reached while the interface is down,
when stmmac_release() has dropped the runtime PM usage counter and the
device may be suspended with its clocks gated. Accessing the registers
in that state can trigger a bus error.
Hold a runtime PM reference for the whole setup_tc() call so the device
is active, and its clocks enabled, whenever a qdisc offload is
configured or torn down. This covers all qdisc offloads, including the
pre-existing CBS/TAPRIO paths that had the same issue.
Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi at oss.qualcomm.com>
---
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 39 ++++++++++++++++-------
1 file changed, 28 insertions(+), 11 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index e19f75d8c393..5aee03ebe131 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -6443,28 +6443,45 @@ static int stmmac_setup_tc(struct net_device *ndev, enum tc_setup_type type,
void *type_data)
{
struct stmmac_priv *priv = netdev_priv(ndev);
+ int ret;
+
+ ret = pm_runtime_resume_and_get(priv->device);
+ if (ret < 0)
+ return ret;
switch (type) {
case TC_QUERY_CAPS:
- return stmmac_tc_query_caps(priv, priv, type_data);
+ ret = stmmac_tc_query_caps(priv, priv, type_data);
+ break;
case TC_SETUP_QDISC_MQPRIO:
- return stmmac_tc_setup_mqprio(priv, priv, type_data);
+ ret = stmmac_tc_setup_mqprio(priv, priv, type_data);
+ break;
case TC_SETUP_BLOCK:
- return flow_block_cb_setup_simple(type_data,
- &stmmac_block_cb_list,
- stmmac_setup_tc_block_cb,
- priv, priv, true);
+ ret = flow_block_cb_setup_simple(type_data,
+ &stmmac_block_cb_list,
+ stmmac_setup_tc_block_cb,
+ priv, priv, true);
+ break;
case TC_SETUP_QDISC_CBS:
- return stmmac_tc_setup_cbs(priv, priv, type_data);
+ ret = stmmac_tc_setup_cbs(priv, priv, type_data);
+ break;
case TC_SETUP_QDISC_TAPRIO:
- return stmmac_tc_setup_taprio(priv, priv, type_data);
+ ret = stmmac_tc_setup_taprio(priv, priv, type_data);
+ break;
case TC_SETUP_QDISC_ETF:
- return stmmac_tc_setup_etf(priv, priv, type_data);
+ ret = stmmac_tc_setup_etf(priv, priv, type_data);
+ break;
case TC_SETUP_QDISC_ETS:
- return stmmac_tc_setup_ets(priv, priv, type_data);
+ ret = stmmac_tc_setup_ets(priv, priv, type_data);
+ break;
default:
- return -EOPNOTSUPP;
+ ret = -EOPNOTSUPP;
+ break;
}
+
+ pm_runtime_put(priv->device);
+
+ return ret;
}
static u16 stmmac_select_queue(struct net_device *dev, struct sk_buff *skb,
--
2.55.0
More information about the linux-arm-kernel
mailing list