From: sashiko-bot@kernel.org
To: "Jishnu Prakash" <jishnu.prakash@oss.qualcomm.com>
Cc: robh@kernel.org, conor+dt@kernel.org, devicetree@vger.kernel.org
Subject: Re: [PATCH v4 4/4] regulator: qcom-rpmh: Add debounce delay before disabling regulator
Date: Thu, 01 Oct 2026 13:05:11 +0000 [thread overview]
Message-ID: <20261001130511.C511F1F000FF@smtp.kernel.org> (raw)
In-Reply-To: <20261001-regulator-off-on-delay-v4-4-258ba9612da8@oss.qualcomm.com>
Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
- [High] regulator: qcom-rpmh: Use-After-Free due to devres LIFO ordering
- [High] regulator: qcom-rpmh: Data race in worker thread bypassing regulator_lock
- [High] regulator: qcom-rpmh: NULL pointer dereference if delayed disable fires before init completes
- [Medium] regulator: qcom-rpmh: State desynchronization on driver removal drops pending disable
--
commit b0211424f1ad79c3af4f67d5c03d4546a1bd442e
Author: Jishnu Prakash <jishnu.prakash@oss.qualcomm.com>
regulator: qcom-rpmh: Add debounce delay before disabling regulator
This commit adds a debounce delay to the Qualcomm RPMh regulator driver to
prevent rapid disable/enable cycles. It introduces a delayed work item that
defers sending disable requests to the hardware. A devres action is also
added to cancel the delayed work upon driver removal.
> diff --git a/drivers/regulator/qcom-rpmh-regulator.c b/drivers/regulator/qcom-rpmh-regulator.c
> --- a/drivers/regulator/qcom-rpmh-regulator.c
> +++ b/drivers/regulator/qcom-rpmh-regulator.c
[ ... ]
> @@ -347 +347,54 @@ static int rpmh_regulator_set_enable_state(struct regulator_dev *rdev,
> return ret;
> }
>
> +static void rpmh_delayed_off_work(struct work_struct *work)
> +{
> + struct rpmh_vreg *vreg = container_of(work,
> + struct rpmh_vreg, delayed_off_work.work);
> +
> + if (!_rpmh_regulator_set_enable_state(vreg, vreg->rdev, false))
[Severity: High]
Does this worker thread modify the hardware state without holding the
regulator core lock?
The core consumer APIs execute under the regulator_lock. Running
_rpmh_regulator_set_enable_state() here asynchronously might cause a data
race on shared structures like vreg->enabled and vreg->voltage_selector if a
consumer calls regulator_set_voltage() concurrently.
> + vreg->last_off = ktime_get_boottime();
> +}
[ ... ]
> static int rpmh_regulator_disable(struct regulator_dev *rdev)
> {
> + struct rpmh_vreg *vreg = rdev_get_drvdata(rdev);
> +
> + if (vreg->debounce_delay) {
> + queue_delayed_work(system_percpu_wq, &vreg->delayed_off_work,
> + usecs_to_jiffies(vreg->debounce_delay));
> + return 0;
> + }
[Severity: High]
Can this lead to a use-after-free during driver teardown?
When the driver unbinds, devres destroys resources in LIFO order.
The custom devres action rpmh_regulator_cancel_delayed_off_work runs first,
canceling the delayed work. Then devm_regulator_release() runs, which calls
regulator_unregister().
If regulator_unregister() flushes pending core disables, it invokes
rpmh_regulator_disable() which re-queues the delayed work here. After devres
finishes freeing vreg, the newly queued work would execute and dereference
the freed memory.
> +
> return rpmh_regulator_set_enable_state(rdev, false);
> }
[ ... ]
> @@ -551 +551,13 @@ static const struct regulator_ops rpmh_regulator_xob_ops = {
> .is_enabled = rpmh_regulator_is_enabled,
> };
>
> +static void rpmh_regulator_cancel_delayed_off_work(void *data)
> +{
> + struct rpmh_vreg *vreg = data;
> +
> + cancel_delayed_work_sync(&vreg->delayed_off_work);
> +}
[Severity: Medium]
Does cancelling the work here without syncing the hardware state leave the
regulator permanently enabled if a disable request was pending?
The regulator core would consider it disabled, leading to leaked power and
incorrect hardware state.
> +
> /**
> * rpmh_regulator_init_vreg() - initialize all attributes of an rpmh-regulator
[ ... ]
> @@ -677 +677,14 @@ static int rpmh_regulator_init_vreg(struct rpmh_vreg *vreg, struct device *dev,
> node, ret);
> return ret;
> }
> + vreg->rdev = rdev;
[Severity: High]
Could vreg->rdev be NULL if the delayed disable worker fires too early?
The regulator is exposed to consumers as soon as devm_regulator_register()
returns. If a fast consumer probes, sets a voltage, and immediately disables
the regulator before vreg->rdev is assigned here, the delayed off worker
might execute with vreg->rdev set to NULL.
This would cause a NULL pointer dereference when
_rpmh_regulator_set_enable_state() attempts to set the voltage and passes
the NULL rdev to rdev_get_drvdata().
> +
> + if (vreg->debounce_delay) {
> + ret = devm_add_action_or_reset(dev, rpmh_regulator_cancel_delayed_off_work,
> + vreg);
> + if (ret)
> + return ret;
> + }
>
> dev_dbg(dev, "%pOFn regulator registered for RPMh resource %s @ 0x%05X\n",
> node, rpmh_resource_name, vreg->addr);
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261001-regulator-off-on-delay-v4-0-258ba9612da8@oss.qualcomm.com?part=4
prev parent reply other threads:[~2026-10-01 13:05 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-01 12:46 [PATCH v4 0/4] regulator: qcom-rpmh: Add support for off-on-delay and debounce-delay Jishnu Prakash
2026-10-01 12:46 ` [PATCH v4 1/4] regulator: dt-bindings: Add 'regulator-off-on-delay-us' property Jishnu Prakash
2026-10-07 20:36 ` Rob Herring (Arm)
2026-10-01 12:46 ` [PATCH v4 2/4] regulator: qcom-rpmh: Add support for regulator-off-on-delay-us Jishnu Prakash
2026-10-07 16:12 ` Mark Brown
2026-10-01 12:46 ` [PATCH v4 3/4] regulator: dt-bindings: qcom,rpmh-regulator: Add debounce delay property Jishnu Prakash
2026-10-07 20:37 ` Rob Herring (Arm)
2026-10-01 12:46 ` [PATCH v4 4/4] regulator: qcom-rpmh: Add debounce delay before disabling regulator Jishnu Prakash
2026-10-01 13:05 ` sashiko-bot [this message]
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=20261001130511.C511F1F000FF@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=jishnu.prakash@oss.qualcomm.com \
--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