Netdev List
 help / color / mirror / Atom feed
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>, <maciej.machnikowski@intel.com>,
	<przemyslaw.korba@intel.com>, <grzegorz.nitka@intel.com>,
	<sergey.temerkhanov@intel.com>, <arkadiusz.kubalewski@intel.com>,
	<poros@redhat.com>, <richardcochran@gmail.com>,
	<horms@kernel.org>, <pmenzel@molgen.mpg.de>,
	<aleksandr.loktionov@intel.com>, <alexander.nowlin@intel.com>
Subject: Re: [PATCH net v2 14/15] ice: don't clear in_use until HW clears ready bitmap
Date: Tue, 13 Oct 2026 15:59:53 -0700	[thread overview]
Message-ID: <68f6d0ce-4ae2-4861-bd66-ba46ece90c1c@intel.com> (raw)
In-Reply-To: <179184693319.434549.15963891869718203802@kernel.org>

On 10/12/2026 4:15 PM, netdev-bot+sashiko@kernel.org wrote:
> Thank you for your contribution! Sashiko AI review found 6 potential
> issue(s) to consider.
> 
> Critical: 0 · High: 2 · 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).
> 
> - [High] ice: Tx timestamp SKB leak when PHY ready bit is stuck
> - [High] net/ice: IRQ storm due to PHY read failure bypassing stale
>   cleanup
> - [Medium] ice_ptp_maybe_trigger_tx_interrupt()
>   (drivers/net/ethernet/intel/ice/ice_ptp.c:2994-3002) now calls…
> - [Medium] This patch removes the hardware ready-bitmap fallback from the
>   IRQ-thread re-arm decision.
> - [Medium] The patch now deliberately leaves a PHY Tx ready bit set while
>   it keeps the index in_use and stale (ice_ptp.c:622-634), and it also…
> - [Low] In ice_ptp_process_tx_tstamp() (ice_ptp.c:622-634), suppose
>   ice_read_phy_tstamp() succeeds and the hardware clears the ready bit,…
> 
> --
> 
> ice: don't clear in_use until HW clears ready bitmap
> 
> After each PHY timestamp read, this patch re-reads the Tx timestamp ready
> bitmap. If hardware did not clear the ready bit, the index stays locked and
> is marked stale. The patch also removes the hardware ready bitmap check from
> ice_ptp_tx_tstamps_pending(), stops the IRQ re-arm for trackers that are not
> up, and moves the hardware check into the periodic watchdog.
> 
>> diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c
>> index 9dc0b5fa33198..8d302b500a399 100644
>> --- a/drivers/net/ethernet/intel/ice/ice_ptp.c
>> +++ b/drivers/net/ethernet/intel/ice/ice_ptp.c
> 
> [ ... ]
> 
>> @@ -626,6 +619,20 @@ 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);
>> +				spin_unlock_irqrestore(&tx->lock, flags);
>> +				continue;
>> +			}
>> +		}
> 
> [Severity: High]
> The commit message says a failed ice_get_phy_tx_tstamp_ready() is
> treated the same as a ready bit that didn't clear. That holds for
> this re-read, but not for the first read at the top of
> ice_ptp_process_tx_tstamp():
> 
> 	if (tx->has_ready_bitmap) {
> 		err = ice_get_phy_tx_tstamp_ready(hw, tx->block, &tstamp_ready);
> 		if (err)
> 			return;
> 	}
> 
> On that error the function returns before the loop. Nothing is
> marked stale and the 2 second timeout is never checked.
> 
> With the link up, the tracker passes ice_ptp_is_tx_tracker_up(), and
> bitmap_andnot(in_use, stale) is still non-empty. So
> ice_misc_intr_thread_fn() sees ice_ptp_tx_tstamps_pending(pf, true)
> return true and writes PFINT_OICR_TSYN_TX_M again right away.
> 
> If the sideband read keeps failing, doesn't this turn into the same
> tight IRQ loop the patch is trying to remove? The pending skbs would
> also never time out.
> 
> The early return was there before this patch. The new tracker-up
> check only covers link down and calibrating, so it doesn't help in
> this case.
> 
> Should the initial failure be handled like the re-read failure? For
> example, the in_use entries could be marked stale while timed out
> entries are still released. Note that tstamp_ready is uninitialized
> on that path, so the loop can't simply fall through. Or is a
> persistent read failure with the link up not expected to happen?
> 

Well, a persistent read failure really is never exepected to happen, but
I think it would make sense to treat these as the same.

> [Severity: High]
> When the re-read still shows the ready bit set, this continue leaves
> both the in_use bit and tx->tstamps[idx].skb in place. Is holding on
> to the skb here intended?
> 

It was, but I can try to re-arrange things to avoid needing to keep it
locked for 2 seconds.

> Keeping the index locked makes sense. The problem is that the skb now
> has no way out of the tracker while the PHY stays stuck, and the 2
> second timeout no longer helps.
> 
> With the ready bit still set, a timed out entry doesn't take the goto
> skip_ts_read branch. It reads the PHY again, fails this same check,
> and hits this continue again. Before this patch the timeout path
> always reached skip_ts_read and freed the skb.

The idea is that the hardware will *eventually* release the index, and
we would eventually free the skb.

> 
> ice_ptp_request_ts() stores a reference to the original skb taken
> with skb_get(). The sending socket therefore stays charged in
> sk_wmem_alloc for as long as the entry sits here.
> 
> The commit message says stuck indexes stay locked until the PHY is
> reset on link up. As far as I can tell, if the link never comes back,
> the skb is only freed by a reset or a driver unload. Until then the
> owning socket can't be destroyed.
> 
> An unprivileged user in a container can request Tx timestamps. If
> that happens around a link drop, the netns teardown could be left
> hanging.
> 

Hm.

> Could the skb be pulled out of tx->tstamps[idx] and freed (or
> completed without a timestamp) under tx->lock once the timeout
> expires? The in_use bit could still stay set so the index isn't
> reused. Or is there another path that releases these skbs that I'm
> missing?

Since we're going to mark the packet as stale, we might as well free the
skb immediately the moment we do that. I'll investigate how to make that
safe.

> 
> [Severity: Low]
> Suppose ice_read_phy_tstamp() succeeds and hardware clears the ready bit,
> but this second ice_get_phy_tx_tstamp_ready() call hits a transient
> sideband error. What happens then?
> 
> The index gets marked stale and stays in_use. On the next pass the ready
> bit reads as clear, so ice_ptp_process_tx_tstamp() takes this earlier
> branch:
> 
> 		if (tx->has_ready_bitmap &&
> 		    !(tstamp_ready & BIT_ULL(phy_idx))) {
> 			if (drop_ts)
> 				goto skip_ts_read;
> 
> 			continue;
> 		}
> 
> That branch never checks the stale bit. The slot seems to stay locked until
> the 2 second timeout sets drop_ts. When it is finally released, timeout is
> true and pf->ptp.tx_hwtstamp_timeouts gets incremented.
> 
> Would this count a PHY access error as a Tx timestamp timeout, and hold the
> slot for up to 2 seconds?
> 

Hm. Likely yes. I am not sure what the best way to handle this would be
because we want to be careful about ensuring that we do not release an
index prematurely.

> The commit message says transient errors mark packets stale. It doesn't
> mention the 2 second hold or the timeout being counted.
> >> +
>>  		ice_trace(tx_tstamp_fw_done, tx->tstamps[idx].skb, idx);
> 
> [ ... ]
> 
>> @@ -2837,10 +2847,14 @@ static bool ice_port_has_timestamps(struct ice_ptp_tx *tx, bool in_irq)
>>  		if (!tx->init)
>>  			return false;
>>  
>> -		if (in_irq)
>> +		if (in_irq) {
>> +			if (!ice_ptp_is_tx_tracker_up(tx))
>> +				return false;
>> +
>>  			return bitmap_andnot(tstamps, tx->in_use, tx->stale, tx->len);
> 
> [Severity: Medium]
> The verify path in ice_ptp_process_tx_tstamp() now leaves a ready bit set
> while the index stays in_use and stale. Can a stuck index on one port delay
> Tx timestamps for healthy ports that share the same interrupt source?
> 

The ready bit was stuck regardless in this case, while the hardware was
unable to perform its automatic clearing.

> The comment above ice_ptp_maybe_trigger_tx_interrupt() says:
> 
>  * timestamp data from the PHY. It will not interrupt again until all
>  * current timestamp data is read.
> 
> An earlier commit in this series also says an unread ready bit means
> delivery for the whole quad degrades to the periodic work.
> 

Hm.

> On E82x, the timestamp interrupt enable and threshold are per quad. See the
> single Q_REG_TX_MEM_GBL_CFG in ice_phy_cfg_intr_e82x(). On E825, the TSYN_TX
> causes for all ports go to the clock owner in ICE_PTP_TX_INTERRUPT_ALL mode.
> 
> Before this patch, the hardware check in the IRQ re-arm path caused the
> storm, but it also kept serving the other ports in the quad within
> microseconds.
> 

True, but we potentially locked up CPU until the cleanup happens...
Which is worse? :\

> The in_irq branch now looks only at software state. Would new timestamps on
> healthy ports then be handled only when ice_ptp_periodic_work() writes
> PFINT_OICR every 500 ms?
I think as long as there is at least one outstanding timestamp before it
would re-arm in software since the shared interrupt checks all the
trackers. But I guess the moment there are no outstanding non-stale
timestamps then we'd degrade back to checking once every 500ms... until
the status clears.

> 
> On E825, ice_ptp_link_change() only restarts the PHY on link up, so this
> could last as long as the bad port's link stays down. The latency numbers in
> the commit message only cover healthy links.
> 

Nope. After the link goes down, evetually the stuck bit will clear and
then things should return to normal. I don't know how long that takes in
practice yet....

>> -		else
>> +		} else {
>>  			return !bitmap_empty(tx->in_use, tx->len);
>> +		}
>>  	}
>>  }
>>  
>> @@ -2872,41 +2886,18 @@ static bool ice_any_port_has_timestamps(struct ice_pf *pf, bool in_irq)
>>  
>>  bool ice_ptp_tx_tstamps_pending(struct ice_pf *pf, bool in_irq)
>>  {
> 
> [ ... ]
> 
>> -	/* Check hardware indicator */
>> -	ret = ice_check_phy_tx_tstamp_ready(hw);
>> -	if (ret < 0) {
>> -		dev_dbg(ice_pf_to_dev(pf), "Unable to read PHY Tx timestamp ready bitmap, err %d\n",
>> -			ret);
>> -		/* Stop triggering IRQs if we're unable to read PHY */
>>  		return false;
>>  	}
>> -
>> -	/* ice_check_phy_tx_tstamp_ready() returns 1 if there are timestamps
>> -	 * available, 0 if there are no waiting timestamps, and a negative
>> -	 * value if there was an error (which we checked for above).
>> -	 */
>> -	return ret > 0;
>>  }
> 
> [Severity: Medium]
> Removing this hardware fallback also affects the in_irq callers:
> ice_misc_intr_thread_fn() and the E830 top half in ice_ptp_ts_irq(). Can a
> stale index on a tracker that is up miss its re-arm?
> 
> Stale entries can exist while the tracker and link are both up, for example
> after a PHC settime/adjtime:
> 
> ice_ptp_reset_cached_phctime() {
>     ...
> 	ice_ptp_mark_tx_tracker_stale(&pf->ptp.port.tx);
> }
> 
> Such a stale index might become ready after ice_ptp_process_tx_tstamp() has
> already passed it in the loop, or after the last refresh of tstamp_ready.
> If so, it isn't read in that pass. Then ice_misc_intr_thread_fn() runs:
> 
> 	if (ice_ptp_tx_tstamps_pending(pf, true)) {
> 		...
> 		wr32(hw, PFINT_OICR, PFINT_OICR_TSYN_TX_M);
> 
> The software check is now bitmap_andnot(in_use, stale), which is empty, so
> no re-arm happens. Before this patch, ice_check_phy_tx_tstamp_ready() would
> have seen the ready bit and re-armed.
> 
> An earlier commit in this series says the PHY doesn't raise another Tx
> timestamp interrupt until every outstanding ready bit is read. If that
> holds, would new non-stale timestamps then wait for ice_ptp_periodic_work()
> (500 ms)? That is well past ptp4l's default 10 ms tx_timestamp_timeout.
> 
> The commit message justifies dropping the hardware check for trackers that
> are calibrating or link down. It doesn't cover trackers that are up and have
> stale entries whose ready bits are set.
> 

Hmm. Ugh :\

> [ ... ]
> 
>> @@ -2999,7 +2991,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]
> Does this early return change when the watchdog kicks the interrupt?
> 
> Before this patch, ice_ptp_tx_tstamps_pending(pf, false) checked the
> software in_use bitmap first. It only read the PHY when nothing was pending
> in software.
> 
> Now a PHY read error returns before the software check runs. In that case
> PFINT_OICR_TSYN_TX_M is not written, even if in_use has entries.
> 
> ice_check_phy_tx_tstamp_ready_eth56g() returns the first error from any
> port, and ice_check_phy_tx_tstamp_ready_e82x() does the same over quads:
> 
> 	for (port = 0; port < hw->ptp.num_lports; port++) {
> 		...
> 		err = ice_get_phy_tx_tstamp_ready(hw, port, &tstamp_ready);
> 		if (err)
> 			return err;
> 
> In ICE_PTP_TX_INTERRUPT_ALL mode, one port or quad with a failing status
> read would then stop the watchdog kick for every port.
> 
> After this patch, the in_irq path skips stale entries and trackers that are
> down. The 2 second timeout is only checked inside
> ice_ptp_process_tx_tstamp().
> 
> While the read keeps failing, would those in_use entries and their skbs stay
> unreleased until a real PHY interrupt arrives?
> 
> Would it make sense to check the software tracker first, or to ignore the
> PHY error when in_use is not empty? The commit message says the watchdog
> continues to check the hardware bitmap. It doesn't mention this change in
> ordering.
> 

Well the idea behind not re-triggering is that if we failed to read the
PHY then we probably shouldn't bother trying to read it in the IRQ. I
guess it didn't consider a transient failure.

>>  		dev_dbg(dev, "PTP periodic task detected waiting timestamps. Triggering Tx timestamp interrupt now.\n");
>>  
>>  		wr32(hw, PFINT_OICR, PFINT_OICR_TSYN_TX_M);
> 


  reply	other threads:[~2026-10-13 23:00 UTC|newest]

Thread overview: 41+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-08 21:55 [PATCH net v2 00/15][pull request] ice: E82x: timestamp processing logic fixes Tony Nguyen
2026-10-08 21:55 ` [PATCH net v2 01/15] ice: fix removal of PTP timestamp tracker during reset Tony Nguyen
2026-10-12 23:15   ` netdev-bot+sashiko
2026-10-13 21:31     ` Jacob Keller
2026-10-08 21:55 ` [PATCH net v2 02/15] ice: use reference counting and SRCU for PTP port access Tony Nguyen
2026-10-12 23:15   ` netdev-bot+sashiko
2026-10-13 21:41     ` Jacob Keller
2026-10-08 21:56 ` [PATCH net v2 03/15] ice: fix PHY port restart serialization Tony Nguyen
2026-10-12 23:15   ` netdev-bot+sashiko
2026-10-13 21:43     ` Jacob Keller
2026-10-08 21:56 ` [PATCH net v2 04/15] ice: set in_use only after preparing Tx timestamp index Tony Nguyen
2026-10-08 21:56 ` [PATCH net v2 05/15] ice: call PTP link change only from link events Tony Nguyen
2026-10-12 23:15   ` netdev-bot+sashiko
2026-10-13 21:58     ` Jacob Keller
2026-10-08 21:56 ` [PATCH net v2 06/15] ice: E822: keep Tx timestamps disabled during offset calibration Tony Nguyen
2026-10-08 21:56 ` [PATCH net v2 07/15] ice: E822: cancel offset verification work during reset preparation Tony Nguyen
2026-10-12 23:15   ` netdev-bot+sashiko
2026-10-13 22:07     ` Jacob Keller
2026-10-08 21:56 ` [PATCH net v2 08/15] ice: E825: stop clearing PHY_REG_TX_OFFSET_READY Tony Nguyen
2026-10-12 23:15   ` netdev-bot+sashiko
2026-10-13 22:08     ` Jacob Keller
2026-10-08 21:56 ` [PATCH net v2 09/15] ice: E825: clear PHY_REG_TX_MEMORY_STATUS prior to soft reset Tony Nguyen
2026-10-12 23:15   ` netdev-bot+sashiko
2026-10-13 22:11     ` Jacob Keller
2026-10-08 21:56 ` [PATCH net v2 10/15] ice: E825: perform a soft reset when starting the PHY timer Tony Nguyen
2026-10-12 23:15   ` netdev-bot+sashiko
2026-10-13 22:32     ` Jacob Keller
2026-10-08 21:56 ` [PATCH net v2 11/15] ice: wait for in-flight Tx timestamps before flushing the tracker Tony Nguyen
2026-10-12 23:15   ` netdev-bot+sashiko
2026-10-13 22:39     ` Jacob Keller
2026-10-08 21:56 ` [PATCH net v2 12/15] ice: keep Tx timestamp slots tracked until completion or timeout Tony Nguyen
2026-10-12 23:15   ` netdev-bot+sashiko
2026-10-13 22:44     ` Jacob Keller
2026-10-08 21:56 ` [PATCH net v2 13/15] ice: skip reading Tx ready bitmap on ports with no timestamps Tony Nguyen
2026-10-08 21:56 ` [PATCH net v2 14/15] ice: don't clear in_use until HW clears ready bitmap Tony Nguyen
2026-10-12 23:15   ` netdev-bot+sashiko
2026-10-13 22:59     ` Jacob Keller [this message]
2026-10-08 21:56 ` [PATCH net v2 15/15] ice: Recalibrate PHY after settime64 on E825-C Tony Nguyen
2026-10-12 23:15   ` netdev-bot+sashiko
2026-10-13 23:04     ` Jacob Keller
2026-10-14  0:59       ` Jacob Keller

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=68f6d0ce-4ae2-4861-bd66-ba46ece90c1c@intel.com \
    --to=jacob.e.keller@intel.com \
    --cc=aleksandr.loktionov@intel.com \
    --cc=alexander.nowlin@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=pmenzel@molgen.mpg.de \
    --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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox