All of lore.kernel.org
 help / color / mirror / Atom feed
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

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

Thread overview: 11+ 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-13  9:43     ` Jishnu Prakash
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]
2026-10-13  9:43     ` Jishnu Prakash

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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.