[PATCH net] net: stmmac: serialize PTP timestamping configuration with priv->lock
Lorenzo Bianconi
lorenzo.bianconi at oss.qualcomm.com
Fri Oct 2 03:37:26 PDT 2026
stmmac_dl_ts_coarse_set() runs under devl_lock only while
stmmac_hwtstamp_set() runs under RTNL. They read/write
systime_flags/tsfupdt_coarse and run stmmac_config_hw_tstamping().
stmmac_dl_ts_coarse_set() snapshots priv->systime_flags, programs
PTP_TCR, PTP_SSIR and PTP_TAR, and only then publishes tsfupdt_coarse
and systime_flags. A concurrent stmmac_hwtstamp_set() can read the
stale tsfupdt_coarse, build fine-mode flags, program PTP_TCR in fine
mode and set hwts_rx_en.
Take priv->lock in both stmmac_dl_ts_coarse_set() and
stmmac_hwtstamp_set() so the timestamping configuration is updated
under a single lock.
Fixes: 4347287b8627 ("net: stmmac: propagate PTP addend and system time programming errors")
Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi at oss.qualcomm.com>
---
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 43 ++++++++++++++---------
1 file changed, 27 insertions(+), 16 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 9741f97fa37a..a6793054a179 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -685,14 +685,7 @@ static int stmmac_hwtstamp_set(struct net_device *dev,
u32 snap_type_sel = 0;
u32 ts_master_en = 0;
u32 ts_event_en = 0;
-
- if (!(priv->dma_cap.time_stamp || priv->adv_ts)) {
- NL_SET_ERR_MSG_MOD(extack, "No support for HW time stamping");
- priv->hwts_tx_en = 0;
- priv->hwts_rx_en = 0;
-
- return -EOPNOTSUPP;
- }
+ int ret = 0;
if (!netif_running(dev)) {
NL_SET_ERR_MSG_MOD(extack,
@@ -700,13 +693,23 @@ static int stmmac_hwtstamp_set(struct net_device *dev,
return -ENODEV;
}
- netdev_dbg(priv->dev, "%s config flags:0x%x, tx_type:0x%x, rx_filter:0x%x\n",
- __func__, config->flags, config->tx_type, config->rx_filter);
-
if (config->tx_type != HWTSTAMP_TX_OFF &&
config->tx_type != HWTSTAMP_TX_ON)
return -ERANGE;
+ netdev_dbg(priv->dev, "%s config flags:0x%x, tx_type:0x%x, rx_filter:0x%x\n",
+ __func__, config->flags, config->tx_type, config->rx_filter);
+
+ mutex_lock(&priv->lock);
+
+ if (!(priv->dma_cap.time_stamp || priv->adv_ts)) {
+ NL_SET_ERR_MSG_MOD(extack, "No support for HW time stamping");
+ priv->hwts_tx_en = 0;
+ priv->hwts_rx_en = 0;
+ ret = -EOPNOTSUPP;
+ goto unlock;
+ }
+
if (priv->adv_ts) {
switch (config->rx_filter) {
case HWTSTAMP_FILTER_NONE:
@@ -829,7 +832,8 @@ static int stmmac_hwtstamp_set(struct net_device *dev,
break;
default:
- return -ERANGE;
+ ret = -ERANGE;
+ goto unlock;
}
} else {
switch (config->rx_filter) {
@@ -859,8 +863,10 @@ static int stmmac_hwtstamp_set(struct net_device *dev,
stmmac_config_hw_tstamping(priv, priv->ptpaddr, priv->systime_flags);
priv->tstamp_config = *config;
+unlock:
+ mutex_unlock(&priv->lock);
- return 0;
+ return ret;
}
/**
@@ -7753,9 +7759,12 @@ static int stmmac_dl_ts_coarse_set(struct devlink *dl, u32 id,
{
struct stmmac_devlink_priv *dl_priv = devlink_priv(dl);
struct stmmac_priv *priv = dl_priv->stmmac_priv;
- u32 systime_flags = priv->systime_flags;
+ u32 systime_flags;
int ret;
+ mutex_lock(&priv->lock);
+
+ systime_flags = priv->systime_flags;
if (ctx->val.vbool)
systime_flags &= ~PTP_TCR_TSCFUPDT;
else
@@ -7768,13 +7777,15 @@ static int stmmac_dl_ts_coarse_set(struct devlink *dl, u32 id,
if (ret) {
NL_SET_ERR_MSG_MOD(extack,
"failed to reconfigure PTP adjustment");
- return ret;
+ goto unlock;
}
priv->tsfupdt_coarse = ctx->val.vbool;
priv->systime_flags = systime_flags;
+unlock:
+ mutex_unlock(&priv->lock);
- return 0;
+ return ret;
}
static int stmmac_dl_ts_coarse_get(struct devlink *dl, u32 id,
---
base-commit: 232d49dd4b40a666283de9e722899f088ed581b2
change-id: 20261002-stmmac-hwtstamp-missing-lock-b6a7979c643c
Best regards,
--
Lorenzo Bianconi <lorenzo.bianconi at oss.qualcomm.com>
More information about the linux-arm-kernel
mailing list