From: Jakub Kicinski <kuba@kernel.org>
To: ivecera@redhat.com
Cc: Jakub Kicinski <kuba@kernel.org>,
netdev@vger.kernel.org, poros@redhat.com,
arkadiusz.kubalewski@intel.com, davem@davemloft.net,
donald.hunter@gmail.com, edumazet@google.com, jiri@resnulli.us,
mschmidt@redhat.com, pabeni@redhat.com, pvaanane@redhat.com,
Prathosh.Satish@microchip.com, horms@kernel.org,
vadim.fedorenko@linux.dev, linux-kernel@vger.kernel.org
Subject: Re: [PATCH net-next v5 3/4] dpll: zl3073x: add per-DPLL serialization lock
Date: Wed, 3 Jun 2026 18:51:27 -0700 [thread overview]
Message-ID: <20260604015127.2872457-1-kuba@kernel.org> (raw)
In-Reply-To: <20260531194423.383366-4-ivecera@redhat.com>
This is an AI-generated review of your patch. The human sending this
email says "While we wait for more acks - claude says.."
---
dpll: zl3073x: add per-DPLL serialization lock
This patch adds a per-DPLL mutex serializing netlink callbacks and the
periodic worker, moves zl3073x_chan_state_update() under the new lock,
defers change notifications outside the lock to avoid ABBA with
dpll_lock, and converts pin->freq_offset from atomic64_t to plain s64.
> diff --git a/drivers/dpll/zl3073x/core.c b/drivers/dpll/zl3073x/core.c
> index 0b2050aa2ed9..27c71807e4ef 100644
> --- a/drivers/dpll/zl3073x/core.c
> +++ b/drivers/dpll/zl3073x/core.c
> @@ -567,19 +567,7 @@ zl3073x_dev_ref_states_update(struct zl3073x_dev *zldev)
> }
> }
>
> -static void
> -zl3073x_dev_chan_states_update(struct zl3073x_dev *zldev)
> -{
> - int i, rc;
>
> - for (i = 0; i < zldev->info->num_channels; i++) {
> - rc = zl3073x_chan_state_update(zldev, i);
> - if (rc)
> - dev_warn(zldev->dev,
> - "Failed to get DPLL%u state: %pe\n", i,
> - ERR_PTR(rc));
> - }
> -}
[ ... ]
> diff --git a/drivers/dpll/zl3073x/dpll.c b/drivers/dpll/zl3073x/dpll.c
> index 5e58ded5734d..4bee3d0c4659 100644
> --- a/drivers/dpll/zl3073x/dpll.c
> +++ b/drivers/dpll/zl3073x/dpll.c
[ ... ]
> @@ -1817,27 +1906,37 @@ zl3073x_dpll_pin_measured_freq_check(struct zl3073x_dpll_pin *pin)
> void
> zl3073x_dpll_changes_check(struct zl3073x_dpll *zldpll)
> {
> + DECLARE_BITMAP(changed_pins, ZL3073X_NUM_INPUT_PINS);
> struct zl3073x_dev *zldev = zldpll->dev;
> enum dpll_lock_status lock_status;
> struct device *dev = zldev->dev;
> struct zl3073x_dpll_pin *pin;
> + bool dev_changed = false;
> int rc;
>
> + bitmap_zero(changed_pins, ZL3073X_NUM_INPUT_PINS);
> +
> + mutex_lock(&zldpll->lock);
> +
> zldpll->check_count++;
>
> - /* Get current lock status for the DPLL */
> - rc = zl3073x_dpll_lock_status_get(zldpll->dpll_dev, zldpll,
> - &lock_status, NULL, NULL);
> + rc = zl3073x_chan_state_update(zldev, zldpll->id);
> + if (rc) {
> + dev_err(dev, "Failed to get DPLL%u state: %pe\n",
> + zldpll->id, ERR_PTR(rc));
> + goto unlock;
> + }
[Low]
The previous code path, zl3073x_dev_chan_states_update() in core.c, used
dev_warn() and continued the periodic update for the device, allowing the
subsequent lock-status, phase-offset and per-pin checks to run for every
DPLL even when an individual chan_state_update() failed.
After this change, a single failure of zl3073x_chan_state_update() inside
zl3073x_dpll_changes_check() is logged at dev_err and triggers
goto unlock, skipping all remaining work for that DPLL in that cycle:
rc = zl3073x_chan_state_update(zldev, zldpll->id);
if (rc) {
dev_err(dev, "Failed to get DPLL%u state: %pe\n",
zldpll->id, ERR_PTR(rc));
goto unlock;
}
The commit message describes the move only as a serialization change so
that it "runs under zldpll->lock". Should the log-level promotion from warn
to err and the new short-circuit of the rest of the cycle on transient
register-read failures be mentioned in the commit message, or alternatively
preserved as warn-and-continue?
> +
> + rc = __zl3073x_dpll_lock_status_get(zldpll, &lock_status);
> if (rc) {
> dev_err(dev, "Failed to get DPLL%u lock status: %pe\n",
> zldpll->id, ERR_PTR(rc));
> - return;
> + goto unlock;
> }
[ ... ]
> }
The commit message states:
All DPLL pin and device callbacks that access mutable state take the
lock as the first operation.
[Low]
Does this hold for zl3073x_dpll_freq_monitor_get() and
zl3073x_dpll_freq_monitor_set()? Both are device callbacks that read or
write zldpll->dev->freq_monitor, but neither takes zldpll->lock:
static int
zl3073x_dpll_freq_monitor_get(const struct dpll_device *dpll, ...)
{
struct zl3073x_dpll *zldpll = dpll_priv;
if (zldpll->dev->freq_monitor)
*state = DPLL_FEATURE_STATE_ENABLE;
else
*state = DPLL_FEATURE_STATE_DISABLE;
return 0;
}
static int
zl3073x_dpll_freq_monitor_set(const struct dpll_device *dpll, ...)
{
struct zl3073x_dpll *item, *zldpll = dpll_priv;
zldpll->dev->freq_monitor = (state == DPLL_FEATURE_STATE_ENABLE);
...
}
The same field is read in zl3073x_dpll_pin_measured_freq_check() under
lockdep_assert_held(&zldpll->lock):
static bool
zl3073x_dpll_pin_measured_freq_check(struct zl3073x_dpll_pin *pin)
{
...
lockdep_assert_held(&zldpll->lock);
if (!zldpll->dev->freq_monitor)
return false;
...
}
freq_monitor is a per-device bool shared by all channels, so the per-DPLL
lock would not provide cross-DPLL serialization for it anyway. Should the
commit message carve out an exception for this per-device field, or should
some appropriate lock be taken in the freq_monitor get/set callbacks to
match the stated invariant?
next prev parent reply other threads:[~2026-06-04 1:51 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-31 19:44 [PATCH net-next v5 0/4] dpll: add NCO pin type and zl3073x support Ivan Vecera
2026-05-31 19:44 ` [PATCH net-next v5 1/4] dpll: add DPLL_PIN_TYPE_INT_NCO pin type Ivan Vecera
2026-06-04 1:50 ` Jakub Kicinski
2026-05-31 19:44 ` [PATCH net-next v5 2/4] dpll: zl3073x: use per-operation poll timeouts Ivan Vecera
2026-05-31 19:44 ` [PATCH net-next v5 3/4] dpll: zl3073x: add per-DPLL serialization lock Ivan Vecera
2026-06-04 1:40 ` Jakub Kicinski
2026-06-04 1:51 ` Jakub Kicinski [this message]
2026-05-31 19:44 ` [PATCH net-next v5 4/4] dpll: zl3073x: add NCO virtual input pin Ivan Vecera
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=20260604015127.2872457-1-kuba@kernel.org \
--to=kuba@kernel.org \
--cc=Prathosh.Satish@microchip.com \
--cc=arkadiusz.kubalewski@intel.com \
--cc=davem@davemloft.net \
--cc=donald.hunter@gmail.com \
--cc=edumazet@google.com \
--cc=horms@kernel.org \
--cc=ivecera@redhat.com \
--cc=jiri@resnulli.us \
--cc=linux-kernel@vger.kernel.org \
--cc=mschmidt@redhat.com \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=poros@redhat.com \
--cc=pvaanane@redhat.com \
--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