From: Jacob Keller <jacob.e.keller@intel.com>
To: <netdev-bot+sashiko@kernel.org>, <anthony.l.nguyen@intel.com>
Cc: <davem@davemloft.net>, <kuba@kernel.org>, <pabeni@redhat.com>,
<edumazet@kernel.org>, <andrew+netdev@lunn.ch>,
<netdev@vger.kernel.org>, <poros@redhat.com>,
<maciej.machnikowski@intel.com>, <przemyslaw.korba@intel.com>,
<grzegorz.nitka@intel.com>, <sergey.temerkhanov@intel.com>,
<arkadiusz.kubalewski@intel.com>, <richardcochran@gmail.com>,
<horms@kernel.org>
Subject: Re: [PATCH net v3 14/14] ice: don't clear in_use until HW clears ready bitmap
Date: Mon, 19 Oct 2026 17:18:02 -0700 [thread overview]
Message-ID: <388b2dd4-13ee-4377-8d99-39f56a77762c@intel.com> (raw)
In-Reply-To: <179244085807.3135.9409141978116916415@kernel.org>
On 10/19/2026 1:14 PM, netdev-bot+sashiko@kernel.org wrote:
> Thank you for your contribution! Sashiko AI review found 4 potential
> issue(s) to consider.
>
> Critical: 0 · High: 0 · Medium: 3 · Low: 1
>
> 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] In ice_ptp_maybe_trigger_tx_interrupt()
> (drivers/net/ethernet/intel/ice/ice_ptp.c), the patch now reads the…
> - [Medium] ice_ptp_flush_tx_tracker() now increments
> pf->ptp.tx_hwtstamp_flushed on every flushed request, and also…
> - [Medium] The new 'ready bit not cleared' branch in
> ice_ptp_process_tx_tstamp() decides based on PHY reads done without…
> - [Low] pf->ptp.tx_hwtstamp_timeouts now has two writers that are not
> serialized against each other.
>
> --
>
> ice: don't clear in_use until HW clears ready bitmap
>
> This commit re-reads the PHY Tx timestamp ready bitmap after each read in
> ice_ptp_process_tx_tstamp(). If the hardware did not clear the bit, the
> index stays locked and is marked stale. It also moves the timeout count to
> the point where the index is released, counts timeouts on flush, and moves
> the hardware ready bitmap check out of ice_ptp_tx_tstamps_pending() and
> into ice_ptp_maybe_trigger_tx_interrupt().
>
>> diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c
>> index a9658f859c2e8..74e0c0138c501 100644
>> --- a/drivers/net/ethernet/intel/ice/ice_ptp.c
>> +++ b/drivers/net/ethernet/intel/ice/ice_ptp.c
>
> [ ... ]
>
>> @@ -627,6 +622,27 @@ static void ice_ptp_process_tx_tstamp(struct ice_ptp_tx *tx)
>> if (err && !drop_ts)
>> continue;
>>
>> + /* verify ready bit cleared */
>> + if (tx->has_ready_bitmap) {
>> + err = ice_get_phy_tx_tstamp_ready(hw, tx->block, &tstamp_ready);
>> + if (err || tstamp_ready & BIT_ULL(phy_idx)) {
>> + spin_lock_irqsave(&tx->lock, flags);
>> + if (test_bit(idx, tx->in_use) &&
>> + !test_and_set_bit(idx, tx->stale))
>> + dev_dbg(ice_pf_to_dev(pf), "PHY port %u failed to clear ready bit for idx %u\n",
>> + ptp_port->port_num, phy_idx);
>> + skb = tx->tstamps[idx].skb;
>> + tx->tstamps[idx].skb = NULL;
>> + spin_unlock_irqrestore(&tx->lock, flags);
>> + /* Free the SKB immediately since we're never
>> + * going to report a timestamp for the stale
>> + * packet.
>> + */
>> + dev_kfree_skb_any(skb);
>> + continue;
>> + }
>> + }
>
> [Severity: Medium]
> Can this branch mark a newer request in the same slot as stale and free
> its skb?
>
> The decision here comes from ice_read_phy_tstamp() and the ready bitmap
> re-read. Neither is done under tx->lock. After the lock is taken, the only
> check is test_bit(idx, tx->in_use), and that check can't tell the original
> request from a new one that reused idx.
>
> On E825, a link-up event can run this sequence while the IRQ thread sits
> between the re-read and spin_lock_irqsave():
>
> ice_ptp_link_change()
> ice_ptp_port_phy_restart()
> ptp_port->tx.calibrating = true;
> ice_ptp_flush_tx_tracker() /* clears in_use[idx], frees skb */
> ice_start_phy_timer_eth56g()
> ptp_port->tx.calibrating = false;
>
> ice_ptp_request_ts()
> tx->tstamps[idx].start = jiffies;
> tx->tstamps[idx].skb = skb_get(skb);
> ...
> clear_bit(idx, tx->stale);
> smp_mb__before_atomic();
> set_bit(idx, tx->in_use);
>
> Nothing in that sequence waits for an IRQ thread that is already inside the
> loop. When the IRQ thread resumes, test_bit(idx, tx->in_use) returns true.
> It then sets stale[idx] and frees the new request's skb because of the old
> request's hardware state. The new packet's Tx timestamp is lost and
> skb_tstamp_tx() is never called for it.
>
> The timing window is narrow, and the freed reference came from skb_get(),
> so this is a lost timestamp, not a memory safety issue. The existing
> skip_ts_read path has a similar check-then-act gap.
>
Of course. The change to flush tracker was problematic afterall.
Reverting back to marking stale should fix it.
>> ice_trace(tx_tstamp_fw_done, tx->tstamps[idx].skb, idx);
>>
>> /* For PHYs which don't implement a proper timestamp ready
>> @@ -643,6 +659,9 @@ static void ice_ptp_process_tx_tstamp(struct ice_ptp_tx *tx)
>> drop_ts = true;
>>
>> skip_ts_read:
>> + if (timeout)
>> + pf->ptp.tx_hwtstamp_timeouts++;
>> +
>> spin_lock_irqsave(&tx->lock, flags);
>> if (!tx->has_ready_bitmap && raw_tstamp)
>> tx->tstamps[idx].cached_tstamp = raw_tstamp;
>
> [Severity: Low]
> Is the timeout counted here only when this path is the one that actually
> releases the index?
>
> The increment happens before tx->lock is taken, and it doesn't check that
> in_use[idx] is still set. This patch also adds an increment of
> tx_hwtstamp_timeouts in ice_ptp_flush_tx_tracker(), under tx->lock.
>
> On E82x/E825, ice_ptp_process_tx_tstamp() runs in the clock owner's misc
> IRQ thread without ps_lock. The flush can run at the same time from
> ice_ptp_port_phy_restart() (E825 link up), from
> ice_ptp_flush_all_tx_tracker() during reset, or from tracker release.
>
> Here is one way it can happen:
>
> 1. The IRQ thread sees a request that is older than 2 seconds with its
> ready bit clear, sets timeout = true and jumps to skip_ts_read.
> 2. The flush takes tx->lock, increments tx_hwtstamp_timeouts and clears
> in_use.
> 3. The IRQ thread increments tx_hwtstamp_timeouts again, and its
> clear_bit() does nothing.
>
> One request ends up counted twice. Also, a plain u32 increment from two
> CPUs can lose updates.
>
> The commit message says:
>
> "This ensures that we don't double count timeouts or count them
> prematurely."
>
> Is that still true now that the flush path also increments this counter?
>
I'm going to revert that flush change back which should address this.
> [ ... ]
>
>> @@ -849,14 +869,20 @@ ice_ptp_flush_tx_tracker(struct ice_pf *pf, struct ice_ptp_tx *tx)
>> ice_clear_phy_tstamp(hw, tx->block, phy_idx);
>>
>> spin_lock_irqsave(&tx->lock, flags);
>> +
>> + /* Count the number of Tx timestamps flushed */
>> + pf->ptp.tx_hwtstamp_flushed++;
>> +
>> + /* Also count timeouts if we flush a request that timed out */
>> + if (time_is_before_jiffies(tx->tstamps[idx].start + 2 * HZ))
>> + pf->ptp.tx_hwtstamp_timeouts++;
>> +
>
> [Severity: Medium]
> Doesn't this count one flushed request as both err and lost in the ethtool
> timestamping stats?
>
> Both counters are incremented here for the same idx. ice_get_ts_stats()
> reports them as:
>
> drivers/net/ethernet/intel/ice/ice_ethtool.c:ice_get_ts_stats() {
> ...
> ts_stats->err = ptp->tx_hwtstamp_skipped +
> ptp->tx_hwtstamp_flushed +
> ptp->tx_hwtstamp_discarded;
> ts_stats->lost = ptp->tx_hwtstamp_timeouts;
> }
>
> The kernel-doc for struct ethtool_ts_stats in include/linux/ethtool.h says:
>
> * @err: Number of arbitrary timestamp generation error events that the
> * hardware encountered, exclusive of @lost statistics.
>
> This patch lets stuck slots stay locked for well over 2 seconds, so the
> E825 link-up flush from ice_ptp_port_phy_restart() is likely to hit this
> case. Should tx_hwtstamp_flushed be skipped when the request is counted as
> a timeout?
>
> A related detail: an index whose skb was already freed by the new
> stuck-ready-bit path still counts towards tx_hwtstamp_flushed, even though
> tx->tstamps[idx].skb is NULL. Is that intended?
>
> [ ... ]
>
>> @@ -3001,7 +3009,15 @@ static void ice_ptp_maybe_trigger_tx_interrupt(struct ice_pf *pf)
>> !ice_pf_src_tmr_owned(pf))
>> return;
>>
>> - if (ice_ptp_tx_tstamps_pending(pf, false)) {
>> + ret = ice_check_phy_tx_tstamp_ready(hw);
>> + if (ret < 0) {
>> + dev_dbg(dev, "Unable to read PHY Tx timestamp ready bitmap, err %pe\n",
>> + ERR_PTR(ret));
>> + /* Don't trigger an IRQ if we are unable to access the PHY */
>> + return;
>> + }
>> +
>> + if (ret > 0 || ice_ptp_tx_tstamps_pending(pf, false)) {
>
> [Severity: Medium]
> Can this early return stop the watchdog from re-triggering the interrupt
> for ports that still have outstanding requests?
>
> Before this patch, ice_ptp_tx_tstamps_pending(pf, false) checked the
> software in_use bitmaps first, and returned true whenever any request was
> outstanding. The hardware check only ran when software had nothing
> pending, and an error from it only turned off that hardware-only trigger.
>
> Now the hardware read happens first. On E82x and E825
> (ICE_PTP_TX_INTERRUPT_ALL on the clock owner), ice_check_phy_tx_tstamp_ready()
> walks every quad or port and returns the first error it hits:
>
> drivers/net/ethernet/intel/ice/ice_ptp_hw.c:ice_check_phy_tx_tstamp_ready_eth56g() {
> for (port = 0; port < hw->ptp.num_lports; port++) {
> ...
> err = ice_get_phy_tx_tstamp_ready(hw, port, &tstamp_ready);
> if (err)
> return err;
> ...
> }
>
> ice_check_phy_tx_tstamp_ready_e82x() does the same across quads.
>
> As long as one PHY can't be read, the watchdog triggers no IRQ for any
> port. ice_ptp_process_tx_tstamp() is not re-run, so timed-out or stale
> slots on healthy ports are not reaped and a stalled hardware interrupt is
> not recovered.
>
> This patch also stops the IRQ path from re-arming for stale entries and
> for link-down or calibrating trackers, which leaves the watchdog as the
> only fallback. The commit message also says PHY access errors can happen
> during the link transition window this patch targets. The commit message
> doesn't mention this ordering change.
>
> The kernel-doc for ice_ptp_maybe_trigger_tx_interrupt() still says:
>
> * To avoid getting permanently stuck, periodically check if there is any
> * outstanding timestamps or if the PHY has marked any index as ready.
>
> Would it work to check ice_ptp_tx_tstamps_pending() first, and treat a
> hardware read error the same as no hardware-ready timestamps?
>
>> dev_dbg(dev, "PTP periodic task detected waiting timestamps. Triggering Tx timestamp interrupt now.\n");
>>
>> wr32(hw, PFINT_OICR, PFINT_OICR_TSYN_TX_M);
>
I can try to order this better. In practice the thought I had was that
if we can't access the PHY anyways we shouldn't really be triggering an
IRQ since the only known paths for a failure to acecss PHY are because
the sideband queue is blocked which we don't really expect to be a
transient failure. However in principle there is nothing that guarantees
that... Fine.
prev parent reply other threads:[~2026-10-20 0:18 UTC|newest]
Thread overview: 40+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-15 19:10 [PATCH net v3 00/14][pull request] ice: E82x: timestamp processing logic fixes Tony Nguyen
2026-10-15 19:10 ` [PATCH net v3 01/14] ice: fix removal of PTP timestamp tracker during reset Tony Nguyen
2026-10-19 20:14 ` netdev-bot+sashiko
2026-10-19 23:14 ` Jacob Keller
2026-10-15 19:10 ` [PATCH net v3 02/14] ice: use reference counting and SRCU for PTP port access Tony Nguyen
2026-10-19 20:14 ` netdev-bot+sashiko
2026-10-19 23:16 ` Jacob Keller
2026-10-15 19:10 ` [PATCH net v3 03/14] ice: fix PHY port restart serialization Tony Nguyen
2026-10-19 20:14 ` netdev-bot+sashiko
2026-10-19 23:21 ` Jacob Keller
2026-10-15 19:10 ` [PATCH net v3 04/14] ice: set in_use only after preparing Tx timestamp index Tony Nguyen
2026-10-15 19:10 ` [PATCH net v3 05/14] ice: call PTP link change only from link events Tony Nguyen
2026-10-19 20:14 ` netdev-bot+sashiko
2026-10-19 23:35 ` Jacob Keller
2026-10-15 19:10 ` [PATCH net v3 06/14] ice: E822: keep Tx timestamps disabled during offset calibration Tony Nguyen
2026-10-19 20:14 ` netdev-bot+sashiko
2026-10-19 23:37 ` Jacob Keller
2026-10-15 19:10 ` [PATCH net v3 07/14] ice: E822: cancel offset verification work during reset preparation Tony Nguyen
2026-10-19 20:14 ` netdev-bot+sashiko
2026-10-19 23:40 ` Jacob Keller
2026-10-15 19:10 ` [PATCH net v3 08/14] ice: E825: stop clearing PHY_REG_TX_OFFSET_READY Tony Nguyen
2026-10-19 20:14 ` netdev-bot+sashiko
2026-10-19 23:42 ` Jacob Keller
2026-10-20 1:53 ` Jacob Keller
2026-10-15 19:10 ` [PATCH net v3 09/14] ice: E825: clear PHY_TSTAMP memory prior to soft reset Tony Nguyen
2026-10-19 20:14 ` netdev-bot+sashiko
2026-10-19 23:49 ` Jacob Keller
2026-10-15 19:10 ` [PATCH net v3 10/14] ice: E825: perform a soft reset when starting the PHY timer Tony Nguyen
2026-10-19 20:14 ` netdev-bot+sashiko
2026-10-19 23:57 ` Jacob Keller
2026-10-15 19:10 ` [PATCH net v3 11/14] ice: wait for in-flight Tx timestamps before removing the tracker Tony Nguyen
2026-10-19 20:14 ` netdev-bot+sashiko
2026-10-20 0:05 ` Jacob Keller
2026-10-15 19:10 ` [PATCH net v3 12/14] ice: keep Tx timestamp slots tracked until completion or timeout Tony Nguyen
2026-10-19 20:14 ` netdev-bot+sashiko
2026-10-20 0:11 ` Jacob Keller
2026-10-15 19:10 ` [PATCH net v3 13/14] ice: skip reading Tx ready bitmap on ports with no timestamps Tony Nguyen
2026-10-15 19:11 ` [PATCH net v3 14/14] ice: don't clear in_use until HW clears ready bitmap Tony Nguyen
2026-10-19 20:14 ` netdev-bot+sashiko
2026-10-20 0:18 ` Jacob Keller [this message]
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=388b2dd4-13ee-4377-8d99-39f56a77762c@intel.com \
--to=jacob.e.keller@intel.com \
--cc=andrew+netdev@lunn.ch \
--cc=anthony.l.nguyen@intel.com \
--cc=arkadiusz.kubalewski@intel.com \
--cc=davem@davemloft.net \
--cc=edumazet@kernel.org \
--cc=grzegorz.nitka@intel.com \
--cc=horms@kernel.org \
--cc=kuba@kernel.org \
--cc=maciej.machnikowski@intel.com \
--cc=netdev-bot+sashiko@kernel.org \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=poros@redhat.com \
--cc=przemyslaw.korba@intel.com \
--cc=richardcochran@gmail.com \
--cc=sergey.temerkhanov@intel.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.