mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: netdev-bot+sashiko@kernel.org
To: arouhi@sitime.com
Cc: jiri@resnulli.us, vadim.fedorenko@linux.dev,
	arkadiusz.kubalewski@intel.com, ivecera@redhat.com,
	kuba@kernel.org, pabeni@redhat.com, robh@kernel.org,
	krzk+dt@kernel.org, conor+dt@kernel.org, cjubran@nvidia.com,
	Oleg.Zadorozhnyi@devoxsoftware.com, devicetree@vger.kernel.org,
	netdev@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH net-next v11 08/13] dpll: sit9531x: add support to get and set priority on input pins
Date: Mon, 05 Oct 2026 01:10:02 +0000	[thread overview]
Message-ID: <179116260241.434549.7401028968217040174@kernel.org> (raw)
In-Reply-To: <20260930233714.87679-9-arouhi@sitime.com>

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] sit9531x_input_prio_set() (core.c:1175-1181) stores the
  requested priority with `chan->cfg_prio[input_idx] = prio;…
- [Medium] The first monitoring pass can silently absorb a real
  operational-state or priority change on an input pin.
- [Medium] sit9531x_prio_src_live() (core.c:614-622) checks only
  `!sitdev->ref[index].los`.
- [Low] The kernel-doc of sit9531x_dpll_input_pin_prio_set()
  (dpll.c:542-546) says "The other pins keep their priorities, so only…

--

dpll: sit9531x: add support to get and set priority on input pins

This patch adds prio_get and prio_set callbacks for the sit9531x input
pins. Each input keeps a priority per PLL, and the Page 1 priority table
is rebuilt from those priorities. The poll now watches priority and
operational state as well as state, and sends pin notifications after
multiop_lock is dropped.

> diff --git a/drivers/dpll/sit9531x/dpll.c b/drivers/dpll/sit9531x/dpll.c
> index f961b7af28fed..ebbf7f5a3394e 100644
> --- a/drivers/dpll/sit9531x/dpll.c
> +++ b/drivers/dpll/sit9531x/dpll.c

[ ... ]

> +/*
> + * sit9531x_dpll_input_pin_prio_set - set input pin priority
> + *
> + * Records the priority and, for a pin in this PLL's table, rewrites the
> + * Page 1 table in priority order (sit9531x_input_prio_set()).  The other
> + * pins keep their priorities, so only the named pin changes and the core
> + * notifies it.  A pin that is not in the table keeps the priority for when
> + * it is connected.
> + */

[Severity: Low]
Is the claim that "only the named pin changes" accurate when the reorder
moves the active reference? The commit message says the same thing:

  Setting one input's priority leaves every other input's
  as it was, so only the named pin changes and the core's own notification
  covers it.

sit9531x_prio_table_commit() calls sit9531x_prio_activesel_pick(). When
the new order puts another live source first, that function writes the
other source into the selection nibble:

	if (top != SIT9531X_PRIO_SRC_NONE &&
	    top != sit9531x_prio_top_live(sitdev, old))
		return top;

When that happens, the previously active pin's operstate goes from ACTIVE
to STANDBY, and the new top pin's goes the other way.

chan->selected_ref is only refreshed by sit9531x_chan_state_fetch() in the
poll. As a result, the notification that dpll_pin_prio_set() sends right
away for the named pin carries the old operstate. The sibling pins, and
the corrected operstate, are only notified by the next poll, up to
SIT9531X_STATUS_POLL_MS later.

> +static int
> +sit9531x_dpll_input_pin_prio_set(const struct dpll_pin *pin, void *pin_priv,
> +				 const struct dpll_device *dpll,
> +				 void *dpll_priv, u32 prio,
> +				 struct netlink_ext_ack *extack)
> +{

[ ... ]

> +	mutex_lock(&sitdev->multiop_lock);
> +	rc = sit9531x_input_prio_set(sitdev, sitdpll->id,
> +				     sit9531x_input_hw_src(dpin->id),
> +				     (u8)prio);
> +	if (!rc)
> +		dpin->prio = prio;
> +	mutex_unlock(&sitdev->multiop_lock);

[Severity: Medium]
If the table write fails, does the driver keep the rejected priority
anyway? sit9531x_input_prio_set() commits the new value before calling
the step that can fail:

drivers/dpll/sit9531x/core.c:sit9531x_input_prio_set() {
    ...
	chan->cfg_prio[input_idx] = prio;
	chan->cfg_known |= BIT(input_idx);

	if (!(chan->prio_mask & BIT(input_idx)))
		return 0;

	return sit9531x_prio_table_apply(sitdev, pll_idx, chan->prio_mask);
}

Nothing restores cfg_prio if sit9531x_prio_table_commit() fails. It can
fail on the HO_FORCE update, a slot write, the latch, or the holdover
release.

On the failure path, sit9531x_prio_table_commit() reads the table back
and refreshes seen_srcs from it:

	} else if (!sit9531x_prio_table_read(sitdev, pll_idx, now)) {
		sit9531x_prio_mask_build(sitdev, pll_idx, now);
		memcpy(chan->seen_srcs, now, sizeof(chan->seen_srcs));
		chan->seen_valid = true;
	}

This means the check in sit9531x_chan_state_fetch() never re-seeds from
the hardware:

	if (!chan->seen_valid ||
	    memcmp(srcs, chan->seen_srcs, sizeof(chan->seen_srcs)))
		sit9531x_prio_cfg_seed(sitdev, pll_idx, srcs);

Meanwhile dpin->prio keeps the old value, and netlink gets an error. Can
this lead to the following?

  - prio_get reports a priority that the device rejected.
  - The next poll sees cfg_prio != pin->prio and sends
    dpll_pin_change_ntf() for a priority the device never took.
  - The next rebuild for any other reason, for example a state change on
    a sibling input of the same PLL, sorts by the stale cfg_prio in
    sit9531x_prio_table_build() and writes the rejected order.
    sit9531x_prio_activesel_pick() could then move the PLL to a different
    reference long after the failed request.

This code is unchanged at the end of the series.

[Severity: Medium]
With prio_set now available to userspace, can a reorder steer the PLL
onto an input whose monitor has disqualified it? sit9531x_prio_src_live()
only looks at LOS:

drivers/dpll/sit9531x/core.c:sit9531x_prio_src_live() {
    ...
	return !sitdev->ref[index].los;
}

It ignores ref->qual_fail. sit9531x_input_mon_fetch() sets qual_fail on
fine or coarse frequency drift, and
sit9531x_dpll_selection_operstate_get() reports that same condition as
DPLL_PIN_OPERSTATE_QUAL_FAILED.

Suppose prio_set moves a qualification-failed input ahead of a healthy
one. sit9531x_prio_table_commit() then does this:

		sel = sit9531x_prio_activesel_pick(sitdev, chan->prio_srcs,
						   srcs, sel);
		val = sit9531x_prio_slot_set(val, slot + 1, sel);

The drifting input counts as the top live source, so it is written into
the active-selection nibble. The comment on activesel_pick says the PLL
leaves the named source only when that source loses its signal. That
seems to contradict the commit message, which says "it takes the first
slot of its priority table whose signal is qualified".

The helper comes from the previous patch in the series, but this patch
exposes the reorder that triggers it. It is unchanged at the end of the
series.

[ ... ]

> @@ -625,39 +707,67 @@ void sit9531x_dpll_changes_check(struct sit9531x_dpll *sitdpll)

[ ... ]

> +		if (sit9531x_input_prio_get(sitdev, sitdpll->id,
> +					    sit9531x_input_hw_src(id), &prio))
> +			prio = pin->prio;
> +
> +		changed = pin->seen &&
> +			  (state != pin->pin_state ||
> +			   operstate != pin->operstate || prio != pin->prio);

[Severity: Medium]
Can the first poll pass silently absorb a real operstate or priority
change? The probe ordering looks like this:

sit9531x_dev_start()
    sit9531x_dev_state_fetch()        <- fills ref[]/chan[] caches
    register DPLLs and pins           <- create ntfs and GETs use the caches
    kthread_queue_delayed_work(sitdev->kworker, &sitdev->work, 0);

sit9531x_dev_periodic_work()
    fetch state again
    sit9531x_dpll_changes_check()     <- every pin still has seen == false

The pins come from kzalloc_obj() in sit9531x_dpll_pin_alloc(), so
pin->seen is false on this first pass. Whatever differs, changed is false,
and the new values become the baseline.

An input might lose signal between the initial fetch and the first tick,
or the table might be rewritten and re-seeded in that window. Userspace
would then keep the snapshot from registration, with no notification
until some other change happens.

This patch adds operstate and prio to the comparison, so those attributes
now share the gap. The cache is already valid at registration, so could
the baseline be taken there instead?

> +		if (changed)
> +			dev_dbg(sitdev->dev,
> +				"%s: state %u->%u operstate %u->%u prio %u->%u\n",
> +				pin->label, pin->pin_state, state,
> +				pin->operstate, operstate, pin->prio, prio);
>  
> -		/*
> -		 * The first pass only takes the baseline: the pin was
> -		 * registered with this state, so nothing has changed yet.
> -		 */
> -		changed = pin->seen && state != pin->pin_state;
>  		pin->pin_state = state;
> +		pin->operstate = operstate;
> +		pin->prio = prio;
>  		pin->seen = true;

[ ... ]

-- 
Sashiko AI review · https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260930233714.87679-1-arouhi%40sitime.com

  reply	other threads:[~2026-10-05  1:10 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-30 23:37 [PATCH net-next v11 00/13] dpll: add SiTime SiT9531x DPLL clock driver Ali Rouhi
2026-09-30 23:37 ` [PATCH net-next v11 01/13] dt-bindings: dpll: allow hex unit addresses on output pins Ali Rouhi
2026-10-02  8:32   ` Krzysztof Kozlowski
2026-09-30 23:37 ` [PATCH net-next v11 02/13] dt-bindings: vendor-prefixes: add SiTime Corporation Ali Rouhi
2026-09-30 23:37 ` [PATCH net-next v11 03/13] dt-bindings: dpll: add SiTime SiT95316 clock generator Ali Rouhi
2026-10-05  1:09   ` netdev-bot+sashiko
2026-09-30 23:37 ` [PATCH net-next v11 04/13] dpll: add basic SiTime SiT9531x support Ali Rouhi
2026-10-05  1:09   ` netdev-bot+sashiko
2026-09-30 23:37 ` [PATCH net-next v11 05/13] dpll: sit9531x: read DPLL types and pin properties from system firmware Ali Rouhi
2026-10-05  1:09   ` netdev-bot+sashiko
2026-09-30 23:37 ` [PATCH net-next v11 06/13] dpll: sit9531x: register DPLL devices and pins Ali Rouhi
2026-10-05  1:09   ` netdev-bot+sashiko
2026-09-30 23:37 ` [PATCH net-next v11 07/13] dpll: sit9531x: implement input pin state on a DPLL Ali Rouhi
2026-10-05  1:10   ` netdev-bot+sashiko
2026-09-30 23:37 ` [PATCH net-next v11 08/13] dpll: sit9531x: add support to get and set priority on input pins Ali Rouhi
2026-10-05  1:10   ` netdev-bot+sashiko [this message]
2026-09-30 23:37 ` [PATCH net-next v11 09/13] dpll: sit9531x: add support to get and set frequency on pins Ali Rouhi
2026-10-05  1:10   ` netdev-bot+sashiko
2026-09-30 23:37 ` [PATCH net-next v11 10/13] dpll: sit9531x: implement output pin state on a DPLL Ali Rouhi
2026-10-05  1:10   ` netdev-bot+sashiko
2026-09-30 23:37 ` [PATCH net-next v11 12/13] dpll: sit9531x: add support to get phase offset on the connected input pin Ali Rouhi
2026-10-05  1:10   ` netdev-bot+sashiko
2026-09-30 23:37 ` [PATCH net-next v11 11/13] dpll: sit9531x: add support to adjust output phase Ali Rouhi
2026-10-05  1:10   ` netdev-bot+sashiko
2026-09-30 23:37 ` [PATCH net-next v11 13/13] dpll: sit9531x: model the inter-PLL sync net as a pair of pins Ali Rouhi
2026-10-05  1:10   ` 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=179116260241.434549.7401028968217040174@kernel.org \
    --to=netdev-bot+sashiko@kernel.org \
    --cc=Oleg.Zadorozhnyi@devoxsoftware.com \
    --cc=arkadiusz.kubalewski@intel.com \
    --cc=arouhi@sitime.com \
    --cc=cjubran@nvidia.com \
    --cc=conor+dt@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=ivecera@redhat.com \
    --cc=jiri@resnulli.us \
    --cc=krzk+dt@kernel.org \
    --cc=kuba@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=robh@kernel.org \
    --cc=vadim.fedorenko@linux.dev \
    /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

all inboxes | Powered by JetHome®