Netdev List
 help / color / mirror / Atom feed
From: Jakub Kicinski <kuba@kernel.org>
To: anthony.l.nguyen@intel.com
Cc: Jakub Kicinski <kuba@kernel.org>,
	davem@davemloft.net, pabeni@redhat.com, edumazet@google.com,
	andrew+netdev@lunn.ch, netdev@vger.kernel.org,
	maciej.machnikowski@intel.com, jacob.e.keller@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: Tue, 15 Sep 2026 18:12:12 -0700	[thread overview]
Message-ID: <20260916011213.1632286-1-kuba@kernel.org> (raw)
In-Reply-To: <20260911003430.3386340-3-anthony.l.nguyen@intel.com>

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?

> 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?

[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?

[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.

  reply	other threads:[~2026-09-16  1:12 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 [this message]
2026-09-17 16:19     ` Jacob Keller
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=20260916011213.1632286-1-kuba@kernel.org \
    --to=kuba@kernel.org \
    --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=jacob.e.keller@intel.com \
    --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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox