diff mbox series

[v2,net] net: fec: avoid lock evasion when reading pps_enable

Message ID 20240521023800.17102-1-wei.fang@nxp.com (mailing list archive)
State Accepted
Commit 3b1c92f8e5371700fada307cc8fd2c51fa7bc8c1
Delegated to: Netdev Maintainers
Headers show
Series [v2,net] net: fec: avoid lock evasion when reading pps_enable | expand

Checks

Context Check Description
netdev/series_format success Single patches do not need cover letters
netdev/tree_selection success Clearly marked for net
netdev/ynl success Generated files up to date; no warnings/errors; no diff in generated;
netdev/fixes_present success Fixes tag present in non-next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 905 this patch: 905
netdev/build_tools success No tools touched, skip
netdev/cc_maintainers success CCed 9 of 10 maintainers
netdev/build_clang success Errors and warnings before: 909 this patch: 909
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success Fixes tag looks correct
netdev/build_allmodconfig_warn success Errors and warnings before: 909 this patch: 909
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 28 lines checked
netdev/build_clang_rust success No Rust files in patch. Skipping build
netdev/kdoc success Errors and warnings before: 19 this patch: 19
netdev/source_inline success Was 0 now: 0
netdev/contest success net-next-2024-05-21--21-00 (tests: 1039)

Commit Message

Wei Fang May 21, 2024, 2:38 a.m. UTC
The assignment of pps_enable is protected by tmreg_lock, but the read
operation of pps_enable is not. So the Coverity tool reports a lock
evasion warning which may cause data race to occur when running in a
multithread environment. Although this issue is almost impossible to
occur, we'd better fix it, at least it seems more logically reasonable,
and it also prevents Coverity from continuing to issue warnings.

Fixes: 278d24047891 ("net: fec: ptp: Enable PPS output based on ptp clock")
Signed-off-by: Wei Fang <wei.fang@nxp.com>
---
V2 changes:
Moved the assignment positions of pps_channel and reload_period.
---
 drivers/net/ethernet/freescale/fec_ptp.c | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

Comments

Paolo Abeni May 23, 2024, 9:14 a.m. UTC | #1
On Tue, 2024-05-21 at 10:38 +0800, Wei Fang wrote:
> The assignment of pps_enable is protected by tmreg_lock, but the read
> operation of pps_enable is not. So the Coverity tool reports a lock
> evasion warning which may cause data race to occur when running in a
> multithread environment. Although this issue is almost impossible to
> occur, we'd better fix it, at least it seems more logically reasonable,
> and it also prevents Coverity from continuing to issue warnings.
> 
> Fixes: 278d24047891 ("net: fec: ptp: Enable PPS output based on ptp clock")
> Signed-off-by: Wei Fang <wei.fang@nxp.com>
> ---
> V2 changes:
> Moved the assignment positions of pps_channel and reload_period.
> ---
>  drivers/net/ethernet/freescale/fec_ptp.c | 14 ++++++++------
>  1 file changed, 8 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/net/ethernet/freescale/fec_ptp.c b/drivers/net/ethernet/freescale/fec_ptp.c
> index 181d9bfbee22..e32f6724f568 100644
> --- a/drivers/net/ethernet/freescale/fec_ptp.c
> +++ b/drivers/net/ethernet/freescale/fec_ptp.c
> @@ -104,14 +104,13 @@ static int fec_ptp_enable_pps(struct fec_enet_private *fep, uint enable)
>  	struct timespec64 ts;
>  	u64 ns;
>  
> -	if (fep->pps_enable == enable)
> -		return 0;
> -
> -	fep->pps_channel = DEFAULT_PPS_CHANNEL;
> -	fep->reload_period = PPS_OUPUT_RELOAD_PERIOD;
> -
>  	spin_lock_irqsave(&fep->tmreg_lock, flags);
>  
> +	if (fep->pps_enable == enable) {
> +		spin_unlock_irqrestore(&fep->tmreg_lock, flags);
> +		return 0;
> +	}
> +
>  	if (enable) {
>  		/* clear capture or output compare interrupt status if have.
>  		 */
> @@ -532,6 +531,9 @@ static int fec_ptp_enable(struct ptp_clock_info *ptp,
>  	int ret = 0;
>  
>  	if (rq->type == PTP_CLK_REQ_PPS) {
> +		fep->pps_channel = DEFAULT_PPS_CHANNEL;
> +		fep->reload_period = PPS_OUPUT_RELOAD_PERIOD;
> +

I think this does not address Eric's concern on V1, the initialization
still basically happens in the same scope.

On the flip side, quickly skimming over the ptp core code, it looks
like that the ptp core will always call this function under ptp-
>pincfg_mux mutex protection or at device unregistration time.

AFAICS that makes pps_channel and reload_period update safe, so overall
patch LGTM and I'll apply it soon.

Thanks,

Paolo
patchwork-bot+netdevbpf@kernel.org May 23, 2024, 9:40 a.m. UTC | #2
Hello:

This patch was applied to netdev/net.git (main)
by Paolo Abeni <pabeni@redhat.com>:

On Tue, 21 May 2024 10:38:00 +0800 you wrote:
> The assignment of pps_enable is protected by tmreg_lock, but the read
> operation of pps_enable is not. So the Coverity tool reports a lock
> evasion warning which may cause data race to occur when running in a
> multithread environment. Although this issue is almost impossible to
> occur, we'd better fix it, at least it seems more logically reasonable,
> and it also prevents Coverity from continuing to issue warnings.
> 
> [...]

Here is the summary with links:
  - [v2,net] net: fec: avoid lock evasion when reading pps_enable
    https://git.kernel.org/netdev/net/c/3b1c92f8e537

You are awesome, thank you!
diff mbox series

Patch

diff --git a/drivers/net/ethernet/freescale/fec_ptp.c b/drivers/net/ethernet/freescale/fec_ptp.c
index 181d9bfbee22..e32f6724f568 100644
--- a/drivers/net/ethernet/freescale/fec_ptp.c
+++ b/drivers/net/ethernet/freescale/fec_ptp.c
@@ -104,14 +104,13 @@  static int fec_ptp_enable_pps(struct fec_enet_private *fep, uint enable)
 	struct timespec64 ts;
 	u64 ns;
 
-	if (fep->pps_enable == enable)
-		return 0;
-
-	fep->pps_channel = DEFAULT_PPS_CHANNEL;
-	fep->reload_period = PPS_OUPUT_RELOAD_PERIOD;
-
 	spin_lock_irqsave(&fep->tmreg_lock, flags);
 
+	if (fep->pps_enable == enable) {
+		spin_unlock_irqrestore(&fep->tmreg_lock, flags);
+		return 0;
+	}
+
 	if (enable) {
 		/* clear capture or output compare interrupt status if have.
 		 */
@@ -532,6 +531,9 @@  static int fec_ptp_enable(struct ptp_clock_info *ptp,
 	int ret = 0;
 
 	if (rq->type == PTP_CLK_REQ_PPS) {
+		fep->pps_channel = DEFAULT_PPS_CHANNEL;
+		fep->reload_period = PPS_OUPUT_RELOAD_PERIOD;
+
 		ret = fec_ptp_enable_pps(fep, on);
 
 		return ret;