From: "Remo Senekowitsch" <remo@buenzli.dev>
To: "Benno Lossin" <lossin@kernel.org>,
"Rob Herring" <robh@kernel.org>,
"Saravana Kannan" <saravanak@google.com>,
"Miguel Ojeda" <ojeda@kernel.org>,
"Alex Gaynor" <alex.gaynor@gmail.com>,
"Boqun Feng" <boqun.feng@gmail.com>,
"Gary Guo" <gary@garyguo.net>,
"Björn Roy Baron" <bjorn3_gh@protonmail.com>,
"Benno Lossin" <benno.lossin@proton.me>,
"Andreas Hindborg" <a.hindborg@kernel.org>,
"Alice Ryhl" <aliceryhl@google.com>,
"Trevor Gross" <tmgross@umich.edu>,
"Danilo Krummrich" <dakr@kernel.org>,
"Greg Kroah-Hartman" <gregkh@linuxfoundation.org>,
"Rafael J. Wysocki" <rafael@kernel.org>,
"Dirk Behme" <dirk.behme@de.bosch.com>
Cc: <linux-kernel@vger.kernel.org>, <devicetree@vger.kernel.org>,
<rust-for-linux@vger.kernel.org>
Subject: Re: [PATCH v4 6/9] rust: device: Add bindings for reading device properties
Date: Tue, 20 May 2025 12:32:05 +0200 [thread overview]
Message-ID: <DA0X3RE11LJI.3GDSU2DK09HQ0@buenzli.dev> (raw)
In-Reply-To: <DA0TDQ2DPTRX.1T9O4NZEME2JX@kernel.org>
On Tue May 20, 2025 at 9:37 AM CEST, Benno Lossin wrote:
> On Sun May 4, 2025 at 7:31 PM CEST, Remo Senekowitsch wrote:
>> +/// Implemented for all integers that can be read as properties.
>> +///
>> +/// This helper trait is needed on top of the existing [`Property`]
>> +/// trait to associate the integer types of various sizes with their
>> +/// corresponding `fwnode_property_read_*_array` functions.
>> +pub trait PropertyInt: Copy {
>> + /// # Safety
>> + ///
>> + /// Callers must uphold the same safety invariants as for the various
>> + /// `fwnode_property_read_*_array` functions.
>> + unsafe fn read_array_from_fwnode_property(
>> + fwnode: *const bindings::fwnode_handle,
>> + propname: *const ffi::c_char,
>> + val: *mut Self,
>> + nval: usize,
>> + ) -> ffi::c_int;
>
> I really, really dislike that this trait has to have an unsafe function
> with all those raw pointer inputs.
What is the concrete problem with that? Or is it just "not pretty"?
(I'm fine with making it prettier, just making sure I understand
correctly.)
>> +}
>> +// This macro generates implementations of the traits `Property` and
>> +// `PropertyInt` for integers of various sizes. Its input is a list
>> +// of pairs separated by commas. The first element of the pair is the
>> +// type of the integer, the second one is the name of its corresponding
>> +// `fwnode_property_read_*_array` function.
>> +macro_rules! impl_property_for_int {
>> + ($($int:ty: $f:ident),* $(,)?) => { $(
>> + impl PropertyInt for $int {
>> + unsafe fn read_array_from_fwnode_property(
>> + fwnode: *const bindings::fwnode_handle,
>> + propname: *const ffi::c_char,
>> + val: *mut Self,
>> + nval: usize,
>> + ) -> ffi::c_int {
>> + // SAFETY: The safety invariants on the trait require
>> + // callers to uphold the invariants of the functions
>> + // this macro is called with.
>> + unsafe {
>> + bindings::$f(fwnode, propname, val.cast(), nval)
>> + }
>> + }
>> + }
>> + )* };
>> +}
>> +impl_property_for_int! {
>> + u8: fwnode_property_read_u8_array,
>> + u16: fwnode_property_read_u16_array,
>> + u32: fwnode_property_read_u32_array,
>> + u64: fwnode_property_read_u64_array,
>> + i8: fwnode_property_read_u8_array,
>> + i16: fwnode_property_read_u16_array,
>> + i32: fwnode_property_read_u32_array,
>> + i64: fwnode_property_read_u64_array,
>> +}
>> +/// # Safety
>> +///
>> +/// Callers must ensure that if `len` is non-zero, `out_param` must be
>> +/// valid and point to memory that has enough space to hold at least
>> +/// `len` number of elements.
>> +unsafe fn read_array_out_param<T: PropertyInt>(
>> + fwnode: &FwNode,
>> + name: &CStr,
>> + out_param: *mut T,
>> + len: usize,
>> +) -> ffi::c_int {
>> + // SAFETY: `name` is non-null and null-terminated.
>> + // `fwnode.as_raw` is valid because `fwnode` is valid.
>> + // `out_param` is valid and has enough space for at least
>> + // `len` number of elements as per the safety requirement.
>> + unsafe {
>> + T::read_array_from_fwnode_property(fwnode.as_raw(), name.as_char_ptr(), out_param, len)
>> + }
>> +}
>
> Why does this function exist? It doesn't do anything and just delegates
> the call to `T::read_array_from_fwnode_property`.
It's used in three places. Taking Rust references as input reduces the
safety requirements the callers must uphold. But I guess it's a small
benefit, I can remove it.
> This feels like you're dragging the C interface through the lower layers
> of your Rust abstractions, which I wouldn't do. I also looked a bit at
> the C code and saw this comment in `driver/base/property.c:324`:
>
> * It's recommended to call fwnode_property_count_u8() instead of calling
> * this function with @val equals %NULL and @nval equals 0.
>
> That probably holds also for the other functions, so maybe we should do
> that instead? (although `fwnode_property_count_u8` just delegates and
> calls with `fwnode_property_read_u8_array`...)
Yeah, I saw that too. The original implementation is from Rob. I assume
the recommendation is for users, maybe for clarity and readability of
the code. These Rust abstractions are pretty low level, so I thought
it's probably fine.
> How about we do it like this:
>
> pub trait PropertyInt: Copy + Sized + private::Sealed {
> /// ...
> ///
> /// Returns a reference to `out` containing all written elements.
> fn read<'a>(
> fwnode: &FwNode,
> name: &CStr,
> out: &'a mut [MaybeUninit<Self>],
> ) -> Result<&'a mut [Self]>;
>
> fn length(fwnode: &FwNode, name: &CStr) -> Result<usize>;
> }
>
> And then have a macro to implement it on all the integers.
I think I tried to make the macro as small as possible and use regular
generics on top, because I was concerned people would be put off by big
complicated macros. I'm fine with moving the actual trait implementation
into the macro body, seems reasonable.
But still, I'm not sure why we're trying to make the PropertyInt trait's
interface pretty or rusty. It's not supposed to be used, implemented or
in any way interacted with outside this module. It's just a low-level
building block to make some functions generic, giving users type
inference.
Best regards,
Remo
next prev parent reply other threads:[~2025-05-20 10:32 UTC|newest]
Thread overview: 34+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-05-04 17:31 [PATCH v4 0/9] More Rust bindings for device property reads Remo Senekowitsch
2025-05-04 17:31 ` [PATCH v4 1/9] rust: device: Create FwNode abstraction for accessing device properties Remo Senekowitsch
2025-05-12 13:59 ` Danilo Krummrich
2025-05-12 14:12 ` Danilo Krummrich
2025-05-04 17:31 ` [PATCH v4 2/9] rust: device: Enable accessing the FwNode of a Device Remo Senekowitsch
2025-05-04 17:31 ` [PATCH v4 3/9] rust: device: Move property_present() to FwNode Remo Senekowitsch
2025-05-12 17:29 ` Rob Herring
2025-05-12 17:44 ` Danilo Krummrich
2025-05-04 17:31 ` [PATCH v4 4/9] rust: device: Enable printing fwnode name and path Remo Senekowitsch
2025-05-04 17:31 ` [PATCH v4 5/9] rust: device: Introduce PropertyGuard Remo Senekowitsch
2025-05-05 5:14 ` Dirk Behme
2025-05-05 13:02 ` Remo Senekowitsch
2025-05-05 15:37 ` Rob Herring
2025-05-05 15:53 ` Remo Senekowitsch
2025-05-05 16:12 ` Danilo Krummrich
2025-05-05 18:33 ` Rob Herring
2025-05-12 17:09 ` Rob Herring
2025-05-04 17:31 ` [PATCH v4 6/9] rust: device: Add bindings for reading device properties Remo Senekowitsch
2025-05-12 13:36 ` Danilo Krummrich
2025-05-19 15:43 ` Remo Senekowitsch
2025-05-19 16:55 ` Danilo Krummrich
2025-05-19 19:51 ` Remo Senekowitsch
2025-05-20 7:21 ` Benno Lossin
2025-05-20 7:40 ` Benno Lossin
2025-05-20 10:37 ` Remo Senekowitsch
2025-05-20 7:37 ` Benno Lossin
2025-05-20 10:32 ` Remo Senekowitsch [this message]
2025-05-20 11:04 ` Benno Lossin
2025-05-04 17:31 ` [PATCH v4 7/9] rust: device: Add child accessor and iterator Remo Senekowitsch
2025-05-04 17:31 ` [PATCH v4 8/9] rust: device: Add property_get_reference_args Remo Senekowitsch
2025-05-04 17:31 ` [PATCH v4 9/9] samples: rust: platform: Add property read examples Remo Senekowitsch
2025-05-12 13:54 ` Danilo Krummrich
2025-05-12 11:49 ` [PATCH v4 0/9] More Rust bindings for device property reads Remo Senekowitsch
2025-05-12 12:04 ` Danilo Krummrich
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=DA0X3RE11LJI.3GDSU2DK09HQ0@buenzli.dev \
--to=remo@buenzli.dev \
--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=dakr@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=dirk.behme@de.bosch.com \
--cc=gary@garyguo.net \
--cc=gregkh@linuxfoundation.org \
--cc=linux-kernel@vger.kernel.org \
--cc=lossin@kernel.org \
--cc=ojeda@kernel.org \
--cc=rafael@kernel.org \
--cc=robh@kernel.org \
--cc=rust-for-linux@vger.kernel.org \
--cc=saravanak@google.com \
--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®