Devicetree
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Fil Dunsky" <filipp.dunsky@gmail.com>
Cc: devicetree@vger.kernel.org, linux-gpio@vger.kernel.org,
	linux-watchdog@vger.kernel.org, robh@kernel.org,
	conor+dt@kernel.org
Subject: Re: [PATCH v3 07/11] watchdog: Add ARM TWD (MPCore private) watchdog driver
Date: Tue, 13 Oct 2026 07:03:35 +0000	[thread overview]
Message-ID: <sashiko-outbox-169158@kernel.org> (raw)
In-Reply-To: <20261013-b4-cs75xx-s2-v3-7-181bb0d23f4c@gmail.com>

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
- [High] watchdog: acquiring cpus_read_lock() in clock notifier causes deadlock
- [High] watchdog: arm_twd_wdt: watchdog silently disabled across cpuidle deep sleep
- [High] watchdog: arm_twd_wdt: missed ping on concurrent clock rate change
--

commit 3df85baea3ae83b30f30fe157567af6f425f2a20
Author: Fil Dunsky <filipp.dunsky@gmail.com>

watchdog: Add ARM TWD (MPCore private) watchdog driver

This patch adds a watchdog driver for the ARM Cortex-A9/A5 and ARM11
MPCore private watchdog. It programs, pings and stops the watchdog on
all online CPUs and registers a hotplug state to handle CPUs coming
online and going offline.

> diff --git a/drivers/watchdog/arm_twd_wdt.c b/drivers/watchdog/arm_twd_wdt.c
> new file mode 100644
> index 0000000000000..18875ae24a243
> --- /dev/null
> +++ b/drivers/watchdog/arm_twd_wdt.c
[ ... ]
> +static void twd_wdt_cpu_ping(void *data)
> +{
> +	struct twd_wdt *wdt = data;
> +
> +	/* In watchdog mode a write to the load register reloads the counter */
> +	writel(twd_wdt_ticks(wdt, wdt->wdd.timeout), wdt->base + TWD_WDT_LOAD);
> +}

[Severity: High]
Does this ping routine silently fail to re-enable the watchdog if the CPU
previously entered a deep cpuidle sleep state?

If cpuidle cuts power to the CPU's power domain, TWD_WDT_CONTROL might be
lost. Writing to TWD_WDT_LOAD alone without restoring TWD_WDT_CONTROL could
leave the watchdog permanently disabled upon wakeup.

[ ... ]
> +static int twd_wdt_start(struct watchdog_device *wdd)
> +{
> +	struct twd_wdt *wdt = watchdog_get_drvdata(wdd);
> +
> +	cpus_read_lock();
> +	on_each_cpu(twd_wdt_cpu_start, wdt, 1);
> +	wdt->armed = true;
> +	cpus_read_unlock();
> +
> +	return 0;
> +}

[Severity: High]
Could setting wdt->armed = true after calling on_each_cpu() cause a race
condition with a concurrent clock rate change?

Because this function uses a shared reader lock (cpus_read_lock()), it can
run concurrently with twd_wdt_clk_notify(). If the clock rate increases just
as the watchdog is started, twd_wdt_clk_notify() might see wdt->armed == false
and skip resynchronizing the ping, resulting in the hardware running with a
timeout calculated for the old, slower clock rate.

[ ... ]
> +static int twd_wdt_clk_notify(struct notifier_block *nb, unsigned long event,
> +			      void *data)
> +{
> +	struct twd_wdt *wdt = container_of(nb, struct twd_wdt, clk_nb);
> +	struct clk_notifier_data *cnd = data;
> +	unsigned long rate;
[ ... ]
> +	cpus_read_lock();
> +	wdt->rate = rate;
> +	if (wdt->armed)
> +		on_each_cpu(twd_wdt_cpu_ping, wdt, 1);
> +	cpus_read_unlock();
> +
> +	return NOTIFY_OK;
> +}

[Severity: High]
Can acquiring cpus_read_lock() here cause an AB-BA deadlock with CPU
hotplug?

The clock framework's prepare_lock is already held when this notifier is
called. The CPU hotplug path acquires the global hotplug lock for writing
via cpus_write_lock() and invokes callbacks, including cpuhp_cpufreq_online().

Cpufreq drivers update CPU frequencies during hotplug by calling
clk_set_rate(), which acquires the clock framework's prepare_lock mutex,
establishing a locking order of cpu_hotplug_lock -> prepare_lock.

Acquiring cpus_read_lock() here creates an inverted lock order of
prepare_lock -> cpu_hotplug_lock.

[ ... ]
> +static int twd_wdt_probe(struct platform_device *pdev)
> +{
> +	struct device *dev = &pdev->dev;
> +	struct twd_wdt *wdt;
> +	struct clk *clk;
> +	int ret;
[ ... ]
> +	ret = cpuhp_state_add_instance(twd_wdt_hp_state, &wdt->node);
> +	if (ret)
> +		return ret;

[Severity: High]
Is a call to cpu_pm_register_notifier() missing here to ensure the watchdog
context is saved and restored across deep CPU idle states?

Without this, the watchdog could remain disabled if TWD hardware loses its
state during deep sleep.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261013-b4-cs75xx-s2-v3-0-181bb0d23f4c@gmail.com?part=7

  reply	other threads:[~2026-10-13  7:03 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-13  6:07 [PATCH v3 00/11] Cortina Systems CS75xx: interrupt controller, GPIO, I2C and TWD watchdog Fil Dunsky via B4 Relay
2026-10-13  6:07 ` [PATCH v3 01/11] dt-bindings: interrupt-controller: Add Cortina Systems CS7542 peripheral interrupt controller Fil Dunsky via B4 Relay
2026-10-13  6:07 ` [PATCH v3 02/11] irqchip: Add Cortina Systems CS75xx " Fil Dunsky via B4 Relay
2026-10-13  6:07 ` [PATCH v3 03/11] dt-bindings: gpio: Add Cortina Systems CS7542 GPIO controller Fil Dunsky via B4 Relay
2026-10-13  6:07 ` [PATCH v3 04/11] gpio: Add Cortina Systems CS75xx GPIO driver Fil Dunsky via B4 Relay
2026-10-13  6:44   ` sashiko-bot
2026-10-13  6:07 ` [PATCH v3 05/11] dt-bindings: i2c: Add Cortina Systems CS7542 I2C controller Fil Dunsky via B4 Relay
2026-10-13  6:07 ` [PATCH v3 06/11] i2c: Add Cortina Systems CS75xx I2C controller driver Fil Dunsky via B4 Relay
2026-10-13  6:07 ` [PATCH v3 07/11] watchdog: Add ARM TWD (MPCore private) watchdog driver Fil Dunsky via B4 Relay
2026-10-13  7:03   ` sashiko-bot [this message]
2026-10-13  6:07 ` [PATCH v3 08/11] ARM: dts: cortina: cs7542: Add interrupt controller, GPIO and I2C Fil Dunsky via B4 Relay
2026-10-13  6:07 ` [PATCH v3 09/11] ARM: dts: cortina: almondplus: Add reset button and enable I2C Fil Dunsky via B4 Relay
2026-10-13  6:07 ` [PATCH v3 10/11] ARM: multi_v7_defconfig: Enable Cortina Systems CS75xx GPIO, I2C and TWD watchdog Fil Dunsky via B4 Relay
2026-10-13  6:07 ` [PATCH v3 11/11] MAINTAINERS: Add Cortina Systems CS75xx interrupt controller, GPIO and I2C Fil Dunsky via B4 Relay
2026-10-13  6:18 ` [PATCH v3 00/11] Cortina Systems CS75xx: interrupt controller, GPIO, I2C and TWD watchdog Krzysztof Kozlowski
2026-10-13  6:19   ` Fil Dunsky

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=sashiko-outbox-169158@kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=conor+dt@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=filipp.dunsky@gmail.com \
    --cc=linux-gpio@vger.kernel.org \
    --cc=linux-watchdog@vger.kernel.org \
    --cc=robh@kernel.org \
    --cc=sashiko-reviews@lists.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