From: Daniel Almeida <daniel.almeida@collabora.com>
To: Mark Brown <broonie@kernel.org>
Cc: lgirdwood@gmail.com, sebastian.reichel@collabora.com,
sjoerd.simons@collabora.co.uk, ojeda@kernel.org,
alex.gaynor@gmail.com, boqun.feng@gmail.com, gary@garyguo.net,
bjorn3_gh@protonmail.com, a.hindborg@kernel.org,
benno.lossin@proton.me, aliceryhl@google.com, tmgross@umich.edu,
dakr@kernel.org, rust-for-linux@vger.kernel.org,
linux-kernel@vger.kernel.org
Subject: Re: [PATCH] rust: regulator: add a bare minimum regulator abstraction
Date: Wed, 19 Feb 2025 20:35:47 -0300 [thread overview]
Message-ID: <5E354BB7-9CD5-4615-8EAF-98B9F498713A@collabora.com> (raw)
In-Reply-To: <Z7ZjzJ2Rfrt8j0s1@finisterre.sirena.org.uk>
Hi Mark,
> On 19 Feb 2025, at 20:05, Mark Brown <broonie@kernel.org> wrote:
>
> On Wed, Feb 19, 2025 at 01:25:16PM -0300, Daniel Almeida wrote:
>
>> Add a bare minimum regulator abstraction to be used by Rust drivers.
>> This abstraction adds a small subset of the regulator API, which is
>> thought to be sufficient for the drivers we have now.
>
> ...
>
>> Note that each instance of [`Regulator`] obtained from
>> `Regulator::get()` can only be enabled once. This ensures that the calls
>> to enable and disable are perfectly balanced before `regulator_put()` is
>> called, as mandated by the C API.
>
> This sounds very wrong, a major use case for consumers is to enable and
> disable regulators at runtime. I would expect that the Rust code might
> want to have it's own reference counting (and probably should), but not
> being able to disable a regulator after enabling it seems to be a great
> big red flag.
>
>> + /// Enable the regulator.
>> + pub fn enable(&mut self) -> Result {
>> + if self.enabled {
>> + return Ok(());
>> + }
>
> This isn't what the changelog claimed, it's silently ignoring duplicate
> attempts to enable and...
>
>> + // SAFETY: Safe as per the type invariants of `Regulator`.
>> + let res = to_result(unsafe { bindings::regulator_disable(self.inner.as_ptr()) });
>> + if res.is_ok() {
>> + self.enabled = false;
>> + }
>
> ...we actually support disabling and reenabling multiple times, it's
> just that there's a maximum of one enable at once from the consumer and
> we silently ignore duplicated enables and disables. That's better but
> it's asking for trouble.
Maybe there was a language issue on my end here.
When I say once, I mean exactly what the source code shows, i.e.: it can be
enabled once, and further calls will be ignored. If it is disabled, it can then be
enabled once, with all further calls ignored, etc.
What I wanted to say is that this abstraction does not support exactly what you
suggested, i.e.: a refcount of how many times it was enabled.
I agree that this is not what the word “once” means. Sorry for the confusion.
>
> If you're going to support both enable and disable (and all things
> considered you probably should TBH) it would be better to just reference
> count the enables like the C code does and then complain about it if
> someone tries to free the regulator object without underwinding their
> enables, or just possibly just clean them up. Silently ignoring
> duplicate enables or overflowing disables doesn't seem like it plays
> well with the safety goals that Rust has, it's asking for bugs - a big
> part of the reason the C API does things the way it does is that it will
> notice if the enables and disables aren't joined up. You can easily
> wind up with one part of the code disabling the regulator underneath
> another part that's still trying to use the hardware and things tend not
> to go well when that happens.
I thought about that, something like:
```
fn drop(&mut self) {
// someone probably forgot to call disable?
while self.enabled_count > 0 {
// Try to disable, this will decrement self.enabled_count
if let Err(e) = self.disable() {
// But don’t loop forever if it fails
break;
}
}
}
```
I asked for a few opinions privately and was told that “if the C API prefers not to do that
why should you?”
>
> Perhaps an enable should be an object that's allocated and carried about
> by whatever's holding the reference, I don't know if that plays nicely
> with how Rust likes to ensure safety with this stuff?
As I said, this doesn’t work very well, unless someone corrects my reasoning on a
previous email. Having a single type “Regulator” is probably much saner than “Regulator”
and “EnabledRegulator”.
Your “refcount” idea works just fine, though. I’ll send a v2.
— Daniel
next prev parent reply other threads:[~2025-02-19 23:36 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-02-19 16:25 Daniel Almeida
2025-02-19 16:28 ` Alice Ryhl
2025-02-19 17:10 ` Daniel Almeida
2025-02-20 12:09 ` Mark Brown
2025-02-20 13:48 ` Daniel Almeida
2025-02-20 14:14 ` Mark Brown
2025-02-23 7:58 ` Boqun Feng
2025-03-04 15:36 ` Alice Ryhl
2025-02-19 23:05 ` Mark Brown
2025-02-19 23:35 ` Daniel Almeida [this message]
2025-02-20 1:37 ` Mark Brown
2025-02-20 9:42 ` Daniel Almeida
2025-02-20 11:58 ` Mark Brown
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=5E354BB7-9CD5-4615-8EAF-98B9F498713A@collabora.com \
--to=daniel.almeida@collabora.com \
--cc=a.hindborg@kernel.org \
--cc=alex.gaynor@gmail.com \
--cc=aliceryhl@google.com \
--cc=benno.lossin@proton.me \
--cc=bjorn3_gh@protonmail.com \
--cc=boqun.feng@gmail.com \
--cc=broonie@kernel.org \
--cc=dakr@kernel.org \
--cc=gary@garyguo.net \
--cc=lgirdwood@gmail.com \
--cc=linux-kernel@vger.kernel.org \
--cc=ojeda@kernel.org \
--cc=rust-for-linux@vger.kernel.org \
--cc=sebastian.reichel@collabora.com \
--cc=sjoerd.simons@collabora.co.uk \
--cc=tmgross@umich.edu \
/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®