Netdev List
 help / color / mirror / Atom feed
From: netdev-bot+sashiko@kernel.org
To: alex.austin@amd.com
Cc: ecree.xilinx@gmail.com, andrew+netdev@lunn.ch,
	davem@davemloft.net, edumazet@kernel.org, kuba@kernel.org,
	pabeni@redhat.com, richardcochran@gmail.com, alucerop@amd.com,
	pieter.jansen-van-vuuren@amd.com, netdev@vger.kernel.org,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH net v2 1/2] sfc: ptp: serialize host and MC synchronization transactions
Date: Mon, 19 Oct 2026 11:58:39 +0000	[thread overview]
Message-ID: <179241111900.3135.15377803717583250573@kernel.org> (raw)
In-Reply-To: <20261015114104.2531624-2-alex.austin@amd.com>

Thank you for your contribution! Sashiko AI review found 4 potential
issue(s) to consider.

Critical: 0 · High: 0 · Medium: 2 · Low: 2

If you believe none of the issues are legitimate, please reply to each
issue of Medium severity or higher and explain why the AI is wrong.
If any of them are legitimate and you plan to respin, please let patchwork
know by including "pw-bot: cr" as a separate line at the end of your reply
(one such reply per series is enough).

- [Medium] Incomplete fix: the Siena sibling driver is left with the same
  bugs.
- [Medium] efx_ptp_start() sends MC_CMD_PTP_OP_ENABLE through
  efx_ptp_enable() (line 1460) with no lock held.
- [Low] Resolved later in the series (baseline decision: false).
- [Low] The new kernel-doc for @phc_lock in struct efx_ptp_data (lines
  276-277) says the lock 'Serializes PHC commands and synchronization,…

--

sfc: ptp: serialize host and MC synchronization transactions

This patch adds a phc_lock mutex to struct efx_ptp_data. The lock is held
across efx_ptp_synchronize(), the PHC adjfine/adjtime/settime callbacks,
and the current_adjfreq reset in efx_ptp_start(). efx_ptp_synchronize()
also now bails out when efx_mcdi_rpc_start() fails, instead of finishing
an RPC that was never acquired.

> diff --git a/drivers/net/ethernet/sfc/ptp.c b/drivers/net/ethernet/sfc/ptp.c
> index 6ca9a75af01d8..c2f8b94592718 100644
> --- a/drivers/net/ethernet/sfc/ptp.c
> +++ b/drivers/net/ethernet/sfc/ptp.c

[ ... ]

> @@ -272,6 +273,8 @@ struct efx_ptp_rxfilter {
>   * frequency adjustment into a fixed point fractional nanosecond format.
>   * @current_adjfreq: Current ppb adjustment.
>   * @phc_clock: Pointer to registered phc device (if primary function)
> + * @phc_lock: Serializes PHC commands and synchronization, and protects
> + *	      @current_adjfreq

[Severity: Low]
Does this description cover more than the code does?

efx_phc_adjfine(), efx_phc_adjtime() and efx_phc_settime() take
phc_lock. efx_phc_gettime(), which is the gettime64 callback, still sends
MC_CMD_PTP_OP_READ_NIC_TIME without it when the PTP core calls it
directly:

drivers/net/ethernet/sfc/ptp.c:efx_phc_gettime() {
    ...
	rc = efx_mcdi_rpc(efx, MC_CMD_PTP, inbuf, sizeof(inbuf),
			  outbuf, sizeof(outbuf), NULL);
    ...
}

efx_phc_enable() also updates its state without the lock:

	ptp_data->nic_ts_enabled = !!enable;

Could the comment be limited to the operations that actually take
phc_lock?

[ ... ]

> @@ -1027,11 +1038,14 @@ static int efx_ptp_synchronize(struct efx_nic *efx, unsigned int num_readings)
>  	MCDI_SET_QWORD(synch_buf, PTP_IN_SYNCHRONIZE_START_ADDR,
>  		       ptp->start.dma_addr);
>  
> +	mutex_lock(&ptp->phc_lock);
> +
>  	/* Clear flag that signals MC ready */
>  	WRITE_ONCE(*start, 0);
>  	rc = efx_mcdi_rpc_start(efx, MC_CMD_PTP, synch_buf,
>  				MC_CMD_PTP_IN_SYNCHRONIZE_LEN);
> -	EFX_WARN_ON_ONCE_PARANOID(rc);
> +	if (rc)
> +		goto out;

[Severity: Medium]
Does drivers/net/ethernet/sfc/siena/ptp.c need the same fix? It has the
same code, and every problem fixed here is still present there.

In siena, efx_ptp_synchronize() clears the start flag without a lock. If
the start fails, it still goes on to efx_siena_mcdi_rpc_finish():

drivers/net/ethernet/sfc/siena/ptp.c:efx_ptp_synchronize() {
    ...
	/* Clear flag that signals MC ready */
	WRITE_ONCE(*start, 0);
	rc = efx_siena_mcdi_rpc_start(efx, MC_CMD_PTP, synch_buf,
				      MC_CMD_PTP_IN_SYNCHRONIZE_LEN);
	EFX_WARN_ON_ONCE_PARANOID(rc);
    ...
}

efx_siena_mcdi_rpc_start() can return before efx_mcdi_acquire_sync()
through efx_mcdi_check_supported(), mc_bist_for_other_fn or
MCDI_MODE_FAIL.

The siena driver also has the same two concurrent callers,
efx_ptp_pps_worker() and efx_ptp_change_mode(). Its efx_phc_adjfine() and
efx_ptp_start() write current_adjfreq without a lock. Its
efx_phc_settime() still does gettime and adjtime as two separate steps.

The Fixes: tag points at 7c236c43b838 ("sfc: Add support for IEEE-1588
PTP"), the original code that siena/ptp.c was forked from. The commit
message does not mention Siena. Should there be a companion patch for
sfc-siena, or a note on why Siena is not affected?

> @@ -1062,11 +1076,13 @@ static int efx_ptp_synchronize(struct efx_nic *efx, unsigned int num_readings)
>  			++ptp->no_time_syncs;
>  	}
>  
> +out:
>  	/* Increment the bad syncs counter if the synchronize fails, whatever
>  	 * the reason.
>  	 */
>  	if (rc != 0)
>  		++ptp->bad_syncs;
> +	mutex_unlock(&ptp->phc_lock);
>  
>  	return rc;
>  }

[Severity: Low]
After this unlock, efx_ptp_pps_worker() reads the shared synchronization
result without holding phc_lock:

drivers/net/ethernet/sfc/ptp.c:efx_ptp_pps_worker() {
    ...
	ptp_evt.type = PTP_CLOCK_PPSUSR;
	ptp_evt.pps_times = ptp->host_time_pps;
	ptp_clock_event(ptp->phc_clock, &ptp_evt);
}

Can a concurrent efx_ptp_change_mode()->efx_ptp_synchronize() rewrite
ptp->host_time_pps in efx_ptp_process_times() during that read?

	ptp->host_time_pps = *last_time;
	pps_sub_ts(&ptp->host_time_pps, delta);

If so, ptp_clock_event() would get a torn or foreign timestamp.

The next patch in the series, "sfc: ptp: avoid racing PPS timestamp
updates", removes host_time_pps. It copies the result into a stack-local
pps_event_time under phc_lock, so the unlocked read is gone by the end of
the series.

[ ... ]

> @@ -1446,7 +1462,9 @@ static int efx_ptp_start(struct efx_nic *efx)
>  		goto fail;
>  
>  	ptp->evt_frag_idx = 0;
> +	mutex_lock(&ptp->phc_lock);
>  	ptp->current_adjfreq = 0;
> +	mutex_unlock(&ptp->phc_lock);

[Severity: Medium]
Can a frequency adjustment still be lost here?

Just above this, efx_ptp_start() sends MC_CMD_PTP_OP_ENABLE without
holding any lock:

	rc = efx_ptp_enable(efx);
	if (rc != 0)
		goto fail;

The firmware enable and the cache reset are therefore not one critical
section, and efx_phc_adjfine() can run completely between them:

CPU0 (efx_ptp_start)            CPU1 (clock_adjtime ADJ_FREQUENCY)
efx_ptp_enable() completes
                                efx_phc_adjfine()
                                  mutex_lock(&ptp_data->phc_lock)
                                  MCDI ADJUST with FREQ=X
                                  current_adjfreq = X
                                  mutex_unlock(&ptp_data->phc_lock)
mutex_lock(&ptp->phc_lock)
current_adjfreq = 0
mutex_unlock(&ptp->phc_lock)

The next adjtime or settime goes through _efx_phc_adjtime(), which
programs the frequency from the cached value:

	MCDI_SET_QWORD(inbuf, PTP_IN_ADJUST_FREQ, ptp_data->current_adjfreq);

That would put the MC back at frequency 0 and drop a correction that
adjfine already reported as applied.

The commit message says current_adjfreq "cannot be torn by the reset in
efx_ptp_start()". The patch prevents tearing, but the cached value can
still get out of sync with the hardware. Would phc_lock need to be held
across both efx_ptp_enable() and the reset?

Also, efx_ptp_enable() treats -EALREADY as success. In that case the
firmware probably did not reset its frequency, but the driver still sets
current_adjfreq to 0. Is that intended?

-- 
Sashiko AI review · https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20261015114104.2531624-1-alex.austin%40amd.com

  reply	other threads:[~2026-10-19 11:58 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-15 11:41 [PATCH net v2 0/2] sfc: fix PTP synchronization races Alex Austin
2026-10-15 11:41 ` [PATCH net v2 1/2] sfc: ptp: serialize host and MC synchronization transactions Alex Austin
2026-10-19 11:58   ` netdev-bot+sashiko [this message]
2026-10-19 17:21     ` Austin, Alex (DCCG)
2026-10-15 11:41 ` [PATCH net v2 2/2] sfc: ptp: avoid racing PPS timestamp updates Alex Austin
2026-10-19 11:58   ` netdev-bot+sashiko

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=179241111900.3135.15377803717583250573@kernel.org \
    --to=netdev-bot+sashiko@kernel.org \
    --cc=alex.austin@amd.com \
    --cc=alucerop@amd.com \
    --cc=andrew+netdev@lunn.ch \
    --cc=davem@davemloft.net \
    --cc=ecree.xilinx@gmail.com \
    --cc=edumazet@kernel.org \
    --cc=kuba@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=pieter.jansen-van-vuuren@amd.com \
    --cc=richardcochran@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox