All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jacob Keller <jacob.e.keller@intel.com>
To: Jakub Kicinski <kuba@kernel.org>, <anthony.l.nguyen@intel.com>
Cc: <davem@davemloft.net>, <pabeni@redhat.com>, <edumazet@google.com>,
	<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 02/15] ice: fix removal of PTP timestamp tracker during reset
Date: Thu, 17 Sep 2026 09:19:15 -0700	[thread overview]
Message-ID: <c12c607e-63fe-4967-bcde-a97bdd3fe4ba@intel.com> (raw)
In-Reply-To: <20260916011213.1632286-1-kuba@kernel.org>

On 9/15/2026 6:12 PM, Jakub Kicinski wrote:
> This is an AI-generated review of your patch. The human sending this
> email has considered the AI review valid, or at least plausible.
> ---
> ice: fix removal of PTP timestamp tracker during reset
> 
> This drops the ice_ptp_release_tx_tracker() call from
> ice_ptp_prepare_for_reset(), completing the intent of 7a25fe5cd5fb so the
> Tx timestamp tracker is no longer destroyed (and never re-created) across a
> CORE or GLOBAL reset.
> 
> Closes: https://sashiko.dev/#/patchset/20260821-jk-e825c-minimized-fixes-v1-0-9d0731eb4858%40intel.com?part=8
> 
>>     Unfortunately, the commit only removed the calls to ice_ptp_init_tx_*().
>>     This fixed a memory leak in PF reset. However, now a CORE or GLOBAL reset
>>     will leave the device unable to initiate Tx timestamp requests
>>     indefinitely.
> 
> [Severity: Low]
> Is the list of affected reset types complete here?  ice_ptp_prepare_for_reset()
> returns early only for PFR:
> 
> 	if (reset_type == ICE_RESET_PFR)
> 		return;
> 
> 	...
> 	ice_ptp_release_tx_tracker(pf, &pf->ptp.port.tx);
> 
> so the deleted call also ran for ICE_RESET_EMPR.  ice_reset_subtask() maps
> ICE_EMPR_RECV to ICE_RESET_EMPR and then calls ice_prepare_for_reset(), and
> the matching ice_rebuild() -> ice_ptp_rebuild() has no ice_ptp_init_tx_*()
> call either.  Should the commit message mention EMP resets as well, since
> that affects stable triage?
> 

Sure we can update the message.

>> diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c
>> index b12181b8c8434..142d39ee5cc52 100644
>> --- a/drivers/net/ethernet/intel/ice/ice_ptp.c
>> +++ b/drivers/net/ethernet/intel/ice/ice_ptp.c
>> @@ -2979,8 +2979,6 @@ void ice_ptp_prepare_for_reset(struct ice_pf *pf, enum ice_reset_req reset_type)
>>  	if (ice_pf_src_tmr_owned(pf) && hw->mac_type == ICE_MAC_GENERIC_3K_E825)
>>  		ice_ptp_prepare_rebuild_sec(pf, false, reset_type);
>>  
>> -	ice_ptp_release_tx_tracker(pf, &pf->ptp.port.tx);
>> -
> 
> [Severity: High]
> This call was also the only thing that cleared tx->init under tx->lock and
> ran synchronize_irq() for the low latency Tx timestamp path.  With the
> tracker left armed, can ice_ll_ts_intr() still run against live tracker
> state in the middle of a CORE or GLOBAL reset?
> 
> The handler is gated only on tx->init:
> 
> drivers/net/ethernet/intel/ice/ice_main.c:ice_ll_ts_intr() {
> 	spin_lock_irqsave(&tx->lock, flags);
> 	if (tx->init) {
> 		ice_ptp_complete_tx_single_tstamp(tx);
> 
> 		idx = find_next_bit_wrap(tx->in_use, tx->len,
> 					 tx->last_ll_ts_idx_read + 1);
> 		if (idx != tx->len)
> 			ice_ptp_req_tx_single_tstamp(tx, idx);
> 	}
> 	...
> }
> 
> The LL cause lives in PFINT_SB_CTL, so ice_ptp_disable_timestamp_mode() does
> not mask it (it only clears PFINT_OICR_ENA TSYN_TX), and
> ice_prepare_for_reset() only does synchronize_irq(pf->oicr_irq.virq), not
> pf->ll_ts_irq.
> 
> Two consequences worth checking:
> 
> ice_ptp_complete_tx_single_tstamp() reads REG_LL_PROXY_L/H of a resetting
> device, so can a garbage timestamp be reported through skb_tstamp_tx() for a
> still-set in_use slot?
> 
> The handler sees the pre-reset in_use bits and issues a new firmware request
> via ice_ptp_req_tx_single_tstamp(), which sets:
> 
> 	params->atqbal_flags |= ATQBAL_FLAGS_INTR_IN_PROGRESS;
> 
> That flag is cleared only by ice_ptp_complete_tx_single_tstamp(), i.e. by a
> later LL interrupt, and nothing re-initializes it on rebuild.  If the reset
> swallows the request, does every subsequent user of the LL interface block
> forever in the untimed wait in ice_ptp_prep_phy_incval_ll_e810() /
> ice_ptp_prep_phy_adj_ll_e810():
> 
> 	err = wait_event_interruptible_locked_irq(params->atqbal_wq,
> 						  !(params->atqbal_flags &
> 						    ATQBAL_FLAGS_INTR_IN_PROGRESS));
> 
> These are reached from ice_ptp_rebuild_owner() through
> ice_ptp_write_incval()/ice_ptp_write_init(), which run in the PF service task
> workqueue where no signal can break the wait.
> 
> Note ice_ptp_ts_irq() checks ice_pf_state_is_nominal() and
> ice_misc_intr_thread_fn() checks ice_is_reset_in_progress(), while
> ice_ll_ts_intr() has no reset-state check.  Would keeping the tracker across
> reset need an explicit disarm here (a state check honored by
> ice_ll_ts_intr() plus synchronize_irq(pf->ll_ts_irq.virq)) rather than just
> dropping the release?
> 

Hm. Will investigate.

> [Severity: Medium]
> Can the tracker allocations now leak at unload when the PTP state is not
> ICE_PTP_READY?
> 
> tx->tstamps, tx->in_use and tx->stale are allocated in
> ice_ptp_alloc_tx_tracker(), and after this change the only remaining free is
> in the READY branch of ice_ptp_release():
> 
> 	if (pf->ptp.state != ICE_PTP_READY) {
> 		mutex_destroy(&pf->ptp.port.ps_lock);
> 		ice_ptp_cleanup_pf(pf);
> 		if (pf->ptp.clock) {
> 			ptp_clock_unregister(pf->ptp.clock);
> 			pf->ptp.clock = NULL;
> 		}
> 		return;
> 	}
> 	...
> 	ice_ptp_release_tx_tracker(pf, &pf->ptp.port.tx);
> 
> ice_ptp_cleanup_pf() only unlinks the port from the adapter list and drops
> the kref, so it does not touch the tracker.
> 
> If ice_ptp_rebuild_owner() fails, ice_ptp_rebuild() leaves the state at
> ICE_PTP_ERROR:
> 
> err:
> 	ptp->state = ICE_PTP_ERROR;
> 	dev_err(ice_pf_to_dev(pf), "PTP reset failed %d\n", err);
> 
> and a failed ice_check_reset() leaves it at ICE_PTP_RESETTING.  A later
> rmmod or unbind then takes the early-return branch above.  Does that leak the
> timestamp array, both bitmaps, and any SKBs still pinned in tx->tstamps[]
> along with their socket references?
> 
> [Severity: Medium]
> With this call gone, the only reset-time flush left is
> ice_ptp_flush_all_tx_tracker() inside ice_ptp_rebuild_owner().  What reclaims
> the tracker if the reset never reaches ice_rebuild()?
> 
> drivers/net/ethernet/intel/ice/ice_main.c:ice_reset_subtask() {
> 		if (ice_check_reset(&pf->hw)) {
> 			set_bit(ICE_RESET_FAILED, pf->state);
> 		} else {
> 			...
> 			ice_rebuild(pf, reset_type);
> 	...
> }
> 
> In that path ice_ptp_prepare_for_reset() has already run, so the pre-reset
> tx->in_use bits stay set with skb_get() references pinned in tx->tstamps[]
> and SKBTX_IN_PROGRESS still set, while the PHY timestamps were destroyed by
> the reset.
> 
> The 2 second timeout drain cannot run either:
> 
> 	if (pf->ptp.state != ICE_PTP_READY)
> 		return;
> 
> in ice_ptp_periodic_work(), and the work was cancelled in
> ice_ptp_prepare_for_reset().  The OICR TSYN_TX cause was masked by
> ice_ptp_disable_timestamp_mode() and is only re-enabled by
> ice_ptp_restore_timestamp_mode() at the end of a completed ice_rebuild().
> Combined with the non-READY branch of ice_ptp_release() above, are those SKBs
> and their socket references then held for the remaining lifetime of the
> driver instance?
> 
> For contrast, the narrower case of a *PTP* rebuild failure does still drain:
> ice_ptp_rebuild() returns void, ice_rebuild() continues and calls
> ice_ptp_restore_timestamp_mode(), so the stale entries age out via the 2 s
> timeout.
> 
> [Severity: Medium]
> After a failed CORE or GLOBAL PTP rebuild, does the retained tracker keep
> accepting requests that can never complete?
> 
> tx->init now stays 1, and admission in ice_ptp_request_ts() consults only the
> tracker:
> 
> 	if (!ice_ptp_is_tx_tracker_up(tx)) {
> 		spin_unlock_irqrestore(&tx->lock, flags);
> 		return -1;
> 	}
> 
> ice_ptp_is_tx_tracker_up() tests tx->init && !tx->calibrating and never looks
> at pf->ptp.state.  Meanwhile ice_ptp_rebuild() has set ICE_PTP_ERROR and
> returned void, so ice_rebuild() reattaches the netdev and calls
> ice_ptp_restore_timestamp_mode(), re-enabling the Tx timestamp cause, while
> the PHY was never restarted (ice_ptp_restart_all_phy() sits after the failure
> point) and:
> 
> 	if (test_bit(ICE_FLAG_PTP_SUPPORTED, pf->flags) &&
> 	    pf->ptp.state == ICE_PTP_READY)
> 		kthread_queue_delayed_work(pf->ptp.kworker, &pf->ptp.work, 0);
> 
> in ice_ptp_queue_work() refuses to restart periodic processing.  Before this
> patch tx->init had been cleared, so this error path rejected requests.  Would
> each timestamp-requesting SKB now be held until the 2 second timeout drops it
> and bumps tx_hwtstamp_timeouts?
> 

We should probably check the state and reject requests when we're not ready.

> [Severity: Medium]
> Since peer PFs' trackers now survive CORER/GLOBR, can the clock owner's
> rebuild flush race the peers?
> 
> ice_ptp_rebuild_owner() -> ice_ptp_flush_all_tx_tracker() walks every port of
> the adapter:
> 
> 		ice_ptp_flush_tx_tracker(ptp_port_to_pf(port), &port->tx);
> 
> and ice_ptp_flush_tx_tracker() does its PHY register work outside tx->lock:
> 
> 	err = ice_get_phy_tx_tstamp_ready(hw, tx->block, &tstamp_ready);
> 	...
> 		if (!hw->reset_ongoing && (tstamp_ready & BIT_ULL(phy_idx)))
> 			ice_clear_phy_tstamp(hw, tx->block, phy_idx);
> 
> On E810/E830 each PF uses ICE_PTP_TX_INTERRUPT_SELF, so a peer PF that has
> already finished its own ice_rebuild() (and therefore
> ice_ptp_restore_timestamp_mode()) can be inside ice_ptp_process_tx_tstamp()
> reading the same block:
> 
> 	if (tx->has_ready_bitmap) {
> 		err = ice_get_phy_tx_tstamp_ready(hw, tx->block, &tstamp_ready);
> 	...
> 		err = ice_read_phy_tstamp(hw, tx->block, phy_idx, &raw_tstamp);
> 
> Before this patch the peers' trackers had been released (tx->len = 0, in_use
> NULL, tx->init = 0), so the owner's flush iterated nothing and the peers could
> not process.  Can a timestamp be cleared between the peer's ready-bitmap read
> and its register read here, which the comment in ice_ptp_process_tx_tstamp()
> warns can wedge the interrupt generation logic?  Note the teardown path
> (ice_ptp_release_tx_tracker()) clears tx->init and calls synchronize_irq()
> before flushing, but the rebuild flush has no equivalent quiesce for peer
> PFs.

Similar comment from above, we should probably do this same quie

  reply	other threads:[~2026-09-17 16:19 UTC|newest]

Thread overview: 45+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-11  0:34 [PATCH net 00/15][pull request] ice: E82x: timestamp processing logic fixes Tony Nguyen
2026-09-11  0:34 ` [PATCH net 01/15] ice: use reference counting and RCU for PTP port access Tony Nguyen
2026-09-16  1:12   ` Jakub Kicinski
2026-09-17 16:13     ` Jacob Keller
2026-09-11  0:34 ` [PATCH net 02/15] ice: fix removal of PTP timestamp tracker during reset Tony Nguyen
2026-09-16  1:12   ` Jakub Kicinski
2026-09-17 16:19     ` Jacob Keller [this message]
2026-09-18  0:22     ` Jacob Keller
2026-09-11  0:34 ` [PATCH net 03/15] ice: set in_use only after preparing Tx timestamp index Tony Nguyen
2026-09-11  0:34 ` [PATCH net 04/15] ice: E822: keep Tx timestamps disabled during offset calibration Tony Nguyen
2026-09-16  1:12   ` Jakub Kicinski
2026-09-17 16:25     ` Jacob Keller
2026-09-11  0:34 ` [PATCH net 05/15] ice: E822: cancel offset verification work during reset preparation Tony Nguyen
2026-09-16  1:12   ` Jakub Kicinski
2026-09-17 16:31     ` Jacob Keller
2026-09-11  0:34 ` [PATCH net 06/15] ice: call PTP link change only from link events Tony Nguyen
2026-09-16  1:12   ` Jakub Kicinski
2026-09-17 16:37     ` Jacob Keller
2026-09-18  1:31     ` Jacob Keller
2026-09-11  0:34 ` [PATCH net 07/15] ice: E825: stop clearing PHY_REG_TX_OFFSET_READY Tony Nguyen
2026-09-16  1:12   ` Jakub Kicinski
2026-09-17 16:41     ` Jacob Keller
2026-09-11  0:34 ` [PATCH net 08/15] ice: E825: clear PHY_REG_TX_MEMORY_STATUS prior to soft reset Tony Nguyen
2026-09-16  1:12   ` Jakub Kicinski
2026-09-17 16:46     ` Jacob Keller
2026-09-11  0:34 ` [PATCH net 09/15] ice: E825: perform a soft reset when starting the PHY timer Tony Nguyen
2026-09-16  1:12   ` Jakub Kicinski
2026-09-17 16:58     ` Jacob Keller
2026-09-11  0:34 ` [PATCH net 10/15] ice: wait for in-flight Tx timestamps before flushing the tracker Tony Nguyen
2026-09-16  1:12   ` Jakub Kicinski
2026-09-17 17:00     ` Jacob Keller
2026-09-11  0:34 ` [PATCH net 11/15] ice: keep Tx timestamp slots tracked until completion or timeout Tony Nguyen
2026-09-16  1:12   ` Jakub Kicinski
2026-09-17 17:47     ` Jacob Keller
2026-09-11  0:34 ` [PATCH net 12/15] ice: remove unnecessary discarding of timestamps after clock adjust Tony Nguyen
2026-09-16  1:12   ` Jakub Kicinski
2026-09-17 17:53     ` Jacob Keller
2026-09-11  0:34 ` [PATCH net 13/15] ice: skip reading Tx ready bitmap on ports with no timestamps Tony Nguyen
2026-09-11  0:34 ` [PATCH net 14/15] ice: don't clear in_use until HW clears ready bitmap Tony Nguyen
2026-09-16  1:12   ` Jakub Kicinski
2026-09-17 17:56     ` Jacob Keller
2026-09-11  0:34 ` [PATCH net 15/15] ice: Recalibrate PHY after settime64 on E825-C Tony Nguyen
2026-09-16  1:12   ` Jakub Kicinski
2026-09-17 18:02     ` Jacob Keller
2026-09-16 21:46 ` [PATCH net 00/15][pull request] ice: E82x: timestamp processing logic fixes 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=c12c607e-63fe-4967-bcde-a97bdd3fe4ba@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@google.com \
    --cc=grzegorz.nitka@intel.com \
    --cc=horms@kernel.org \
    --cc=kuba@kernel.org \
    --cc=maciej.machnikowski@intel.com \
    --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 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.