* [PATCH 0/2] rust: device: remove ref-to-ref transmute
@ 2026-05-26 14:39 Tamir Duberstein
2026-05-26 14:39 ` [PATCH 1/2] rust: device: remove unused " Tamir Duberstein
2026-05-26 14:39 ` [PATCH 2/2] rust: device: remove array copy Tamir Duberstein
0 siblings, 2 replies; 7+ messages in thread
From: Tamir Duberstein @ 2026-05-26 14:39 UTC (permalink / raw)
To: Greg Kroah-Hartman, Rafael J. Wysocki, Danilo Krummrich,
Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron,
Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross
Cc: driver-core, rust-for-linux, linux-kernel, Tamir Duberstein
This series came out of discussion with Alice in another series[1]. It
removes an unnecessary unsafe block and optimizes away an array copy.
Link: https://lore.kernel.org/all/CAH5fLgibt_BQmOtkfEfo1=48zUeoWBJ-=u5gzw_a3X6Q7=aUSA@mail.gmail.com/ [1]
Signed-off-by: Tamir Duberstein <tamird@kernel.org>
---
Tamir Duberstein (2):
rust: device: remove unused ref-to-ref transmute
rust: device: remove array copy
rust/kernel/device/property.rs | 46 ++++++++++++++++++------------------------
1 file changed, 20 insertions(+), 26 deletions(-)
---
base-commit: fc1ce3afa2e61b4b15e71436ece91b0441a9f4f0
change-id: 20260526-trasnmute_ptr_to_ptr-a0e442749cc1
Best regards,
--
Tamir Duberstein <tamird@kernel.org>
^ permalink raw reply [flat|nested] 7+ messages in thread* [PATCH 1/2] rust: device: remove unused ref-to-ref transmute 2026-05-26 14:39 [PATCH 0/2] rust: device: remove ref-to-ref transmute Tamir Duberstein @ 2026-05-26 14:39 ` Tamir Duberstein 2026-05-26 18:45 ` Onur Özkan 2026-05-28 13:29 ` Gary Guo 2026-05-26 14:39 ` [PATCH 2/2] rust: device: remove array copy Tamir Duberstein 1 sibling, 2 replies; 7+ messages in thread From: Tamir Duberstein @ 2026-05-26 14:39 UTC (permalink / raw) To: Greg Kroah-Hartman, Rafael J. Wysocki, Danilo Krummrich, Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross Cc: driver-core, rust-for-linux, linux-kernel, Tamir Duberstein The Ok return value of `read_array_from_fwnode_property` requires a reference-to-reference transmute to construct but is never read, thus remove it. Signed-off-by: Tamir Duberstein <tamird@kernel.org> --- rust/kernel/device/property.rs | 42 +++++++++++++++++------------------------- 1 file changed, 17 insertions(+), 25 deletions(-) diff --git a/rust/kernel/device/property.rs b/rust/kernel/device/property.rs index 5aead835fbbc..87be2784f7a7 100644 --- a/rust/kernel/device/property.rs +++ b/rust/kernel/device/property.rs @@ -136,18 +136,15 @@ pub fn property_read_array_vec<'fwnode, 'name, T: PropertyInt>( let mut val: KVec<T> = KVec::with_capacity(len, GFP_KERNEL)?; let res = T::read_array_from_fwnode_property(self, name, val.spare_capacity_mut()); - let res = match res { - Ok(_) => { - // SAFETY: - // - `len` is equal to `val.capacity - val.len`, because - // `val.capacity` is `len` and `val.len` is zero. - // - All elements within the interval [`0`, `len`) were initialized - // by `read_array_from_fwnode_property`. - unsafe { val.inc_len(len) } - Ok(val) - } - Err(e) => Err(e), - }; + let res = res.map(|()| { + // SAFETY: + // - `len` is equal to `val.capacity - val.len`, because + // `val.capacity` is `len` and `val.len` is zero. + // - All elements within the interval [`0`, `len`) were initialized + // by `read_array_from_fwnode_property`. + unsafe { val.inc_len(len) } + val + }); Ok(PropertyGuard { inner: res, fwnode: self, @@ -474,12 +471,12 @@ fn read_from_fwnode_property(fwnode: &FwNode, name: &CStr) -> Result<Self> { /// It must be public, because it appears in the signatures of other public /// functions, but its methods shouldn't be used outside the kernel crate. pub trait PropertyInt: Copy + Sealed { - /// Reads a property array. - fn read_array_from_fwnode_property<'a>( + /// Reads a property array into `out`. + fn read_array_from_fwnode_property( fwnode: &FwNode, name: &CStr, - out: &'a mut [MaybeUninit<Self>], - ) -> Result<&'a mut [Self]>; + out: &mut [MaybeUninit<Self>], + ) -> Result; /// Reads the length of a property array. fn read_array_len_from_fwnode_property(fwnode: &FwNode, name: &CStr) -> Result<usize>; @@ -495,11 +492,11 @@ impl Sealed for $int {} impl<const N: usize> Sealed for [$int; N] {} impl PropertyInt for $int { - fn read_array_from_fwnode_property<'a>( + fn read_array_from_fwnode_property( fwnode: &FwNode, name: &CStr, - out: &'a mut [MaybeUninit<Self>], - ) -> Result<&'a mut [Self]> { + out: &mut [MaybeUninit<Self>], + ) -> Result { // SAFETY: // - `fwnode`, `name` and `out` are all valid by their type // invariants. @@ -515,12 +512,7 @@ fn read_array_from_fwnode_property<'a>( out.len(), ) }; - to_result(ret)?; - // SAFETY: Transmuting from `&'a mut [MaybeUninit<Self>]` to - // `&'a mut [Self]` is sound, because the previous call to a - // `fwnode_property_read_*_array` function (which didn't fail) - // fully initialized the slice. - Ok(unsafe { core::mem::transmute::<&mut [MaybeUninit<Self>], &mut [Self]>(out) }) + to_result(ret) } fn read_array_len_from_fwnode_property(fwnode: &FwNode, name: &CStr) -> Result<usize> { -- 2.54.0 ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 1/2] rust: device: remove unused ref-to-ref transmute 2026-05-26 14:39 ` [PATCH 1/2] rust: device: remove unused " Tamir Duberstein @ 2026-05-26 18:45 ` Onur Özkan 2026-05-28 13:29 ` Gary Guo 1 sibling, 0 replies; 7+ messages in thread From: Onur Özkan @ 2026-05-26 18:45 UTC (permalink / raw) To: Tamir Duberstein Cc: Greg Kroah-Hartman, Rafael J. Wysocki, Danilo Krummrich, Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross, driver-core, rust-for-linux, linux-kernel, Onur Özkan On Tue, 26 May 2026 10:39:31 -0400 Tamir Duberstein <tamird@kernel.org> wrote: > The Ok return value of `read_array_from_fwnode_property` requires a > reference-to-reference transmute to construct but is never read, thus > remove it. > > Signed-off-by: Tamir Duberstein <tamird@kernel.org> > --- > rust/kernel/device/property.rs | 42 +++++++++++++++++------------------------- > 1 file changed, 17 insertions(+), 25 deletions(-) > > diff --git a/rust/kernel/device/property.rs b/rust/kernel/device/property.rs > index 5aead835fbbc..87be2784f7a7 100644 > --- a/rust/kernel/device/property.rs > +++ b/rust/kernel/device/property.rs > @@ -136,18 +136,15 @@ pub fn property_read_array_vec<'fwnode, 'name, T: PropertyInt>( > let mut val: KVec<T> = KVec::with_capacity(len, GFP_KERNEL)?; > > let res = T::read_array_from_fwnode_property(self, name, val.spare_capacity_mut()); > - let res = match res { > - Ok(_) => { > - // SAFETY: > - // - `len` is equal to `val.capacity - val.len`, because > - // `val.capacity` is `len` and `val.len` is zero. > - // - All elements within the interval [`0`, `len`) were initialized > - // by `read_array_from_fwnode_property`. > - unsafe { val.inc_len(len) } > - Ok(val) > - } > - Err(e) => Err(e), > - }; > + let res = res.map(|()| { > + // SAFETY: > + // - `len` is equal to `val.capacity - val.len`, because > + // `val.capacity` is `len` and `val.len` is zero. > + // - All elements within the interval [`0`, `len`) were initialized > + // by `read_array_from_fwnode_property`. > + unsafe { val.inc_len(len) } > + val > + }); > Ok(PropertyGuard { > inner: res, > fwnode: self, > @@ -474,12 +471,12 @@ fn read_from_fwnode_property(fwnode: &FwNode, name: &CStr) -> Result<Self> { > /// It must be public, because it appears in the signatures of other public > /// functions, but its methods shouldn't be used outside the kernel crate. > pub trait PropertyInt: Copy + Sealed { > - /// Reads a property array. > - fn read_array_from_fwnode_property<'a>( > + /// Reads a property array into `out`. > + fn read_array_from_fwnode_property( > fwnode: &FwNode, > name: &CStr, > - out: &'a mut [MaybeUninit<Self>], > - ) -> Result<&'a mut [Self]>; > + out: &mut [MaybeUninit<Self>], > + ) -> Result; > > /// Reads the length of a property array. > fn read_array_len_from_fwnode_property(fwnode: &FwNode, name: &CStr) -> Result<usize>; > @@ -495,11 +492,11 @@ impl Sealed for $int {} > impl<const N: usize> Sealed for [$int; N] {} > > impl PropertyInt for $int { > - fn read_array_from_fwnode_property<'a>( > + fn read_array_from_fwnode_property( > fwnode: &FwNode, > name: &CStr, > - out: &'a mut [MaybeUninit<Self>], > - ) -> Result<&'a mut [Self]> { > + out: &mut [MaybeUninit<Self>], > + ) -> Result { > // SAFETY: > // - `fwnode`, `name` and `out` are all valid by their type > // invariants. > @@ -515,12 +512,7 @@ fn read_array_from_fwnode_property<'a>( > out.len(), > ) > }; > - to_result(ret)?; > - // SAFETY: Transmuting from `&'a mut [MaybeUninit<Self>]` to > - // `&'a mut [Self]` is sound, because the previous call to a > - // `fwnode_property_read_*_array` function (which didn't fail) > - // fully initialized the slice. > - Ok(unsafe { core::mem::transmute::<&mut [MaybeUninit<Self>], &mut [Self]>(out) }) > + to_result(ret) > } > > fn read_array_len_from_fwnode_property(fwnode: &FwNode, name: &CStr) -> Result<usize> { > > -- > 2.54.0 > Reviewed-by: Onur Özkan <work@onurozkan.dev> ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 1/2] rust: device: remove unused ref-to-ref transmute 2026-05-26 14:39 ` [PATCH 1/2] rust: device: remove unused " Tamir Duberstein 2026-05-26 18:45 ` Onur Özkan @ 2026-05-28 13:29 ` Gary Guo 2026-05-30 11:17 ` Tamir Duberstein 1 sibling, 1 reply; 7+ messages in thread From: Gary Guo @ 2026-05-28 13:29 UTC (permalink / raw) To: Tamir Duberstein, Greg Kroah-Hartman, Rafael J. Wysocki, Danilo Krummrich, Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross Cc: driver-core, rust-for-linux, linux-kernel On Tue May 26, 2026 at 3:39 PM BST, Tamir Duberstein wrote: > The Ok return value of `read_array_from_fwnode_property` requires a > reference-to-reference transmute to construct but is never read, thus > remove it. > > Signed-off-by: Tamir Duberstein <tamird@kernel.org> > --- > rust/kernel/device/property.rs | 42 +++++++++++++++++------------------------- > 1 file changed, 17 insertions(+), 25 deletions(-) > > diff --git a/rust/kernel/device/property.rs b/rust/kernel/device/property.rs > index 5aead835fbbc..87be2784f7a7 100644 > --- a/rust/kernel/device/property.rs > +++ b/rust/kernel/device/property.rs > @@ -136,18 +136,15 @@ pub fn property_read_array_vec<'fwnode, 'name, T: PropertyInt>( > let mut val: KVec<T> = KVec::with_capacity(len, GFP_KERNEL)?; > > let res = T::read_array_from_fwnode_property(self, name, val.spare_capacity_mut()); > - let res = match res { > - Ok(_) => { > - // SAFETY: > - // - `len` is equal to `val.capacity - val.len`, because > - // `val.capacity` is `len` and `val.len` is zero. > - // - All elements within the interval [`0`, `len`) were initialized > - // by `read_array_from_fwnode_property`. > - unsafe { val.inc_len(len) } > - Ok(val) > - } > - Err(e) => Err(e), > - }; > + let res = res.map(|()| { > + // SAFETY: > + // - `len` is equal to `val.capacity - val.len`, because > + // `val.capacity` is `len` and `val.len` is zero. > + // - All elements within the interval [`0`, `len`) were initialized > + // by `read_array_from_fwnode_property`. > + unsafe { val.inc_len(len) } > + val > + }); > Ok(PropertyGuard { > inner: res, > fwnode: self, > @@ -474,12 +471,12 @@ fn read_from_fwnode_property(fwnode: &FwNode, name: &CStr) -> Result<Self> { > /// It must be public, because it appears in the signatures of other public > /// functions, but its methods shouldn't be used outside the kernel crate. > pub trait PropertyInt: Copy + Sealed { > - /// Reads a property array. > - fn read_array_from_fwnode_property<'a>( > + /// Reads a property array into `out`. > + fn read_array_from_fwnode_property( > fwnode: &FwNode, > name: &CStr, > - out: &'a mut [MaybeUninit<Self>], > - ) -> Result<&'a mut [Self]>; > + out: &mut [MaybeUninit<Self>], > + ) -> Result; I think the old signature is quite reasonable. You provide storage and the buffer is filled and that the return value is the proof of initialization. If you're concerned with `transmute` it should just be replaced with `assume_init_mut()`. Best, Gary > > /// Reads the length of a property array. > fn read_array_len_from_fwnode_property(fwnode: &FwNode, name: &CStr) -> Result<usize>; > @@ -495,11 +492,11 @@ impl Sealed for $int {} > impl<const N: usize> Sealed for [$int; N] {} > > impl PropertyInt for $int { > - fn read_array_from_fwnode_property<'a>( > + fn read_array_from_fwnode_property( > fwnode: &FwNode, > name: &CStr, > - out: &'a mut [MaybeUninit<Self>], > - ) -> Result<&'a mut [Self]> { > + out: &mut [MaybeUninit<Self>], > + ) -> Result { > // SAFETY: > // - `fwnode`, `name` and `out` are all valid by their type > // invariants. > @@ -515,12 +512,7 @@ fn read_array_from_fwnode_property<'a>( > out.len(), > ) > }; > - to_result(ret)?; > - // SAFETY: Transmuting from `&'a mut [MaybeUninit<Self>]` to > - // `&'a mut [Self]` is sound, because the previous call to a > - // `fwnode_property_read_*_array` function (which didn't fail) > - // fully initialized the slice. > - Ok(unsafe { core::mem::transmute::<&mut [MaybeUninit<Self>], &mut [Self]>(out) }) > + to_result(ret) > } > > fn read_array_len_from_fwnode_property(fwnode: &FwNode, name: &CStr) -> Result<usize> { ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 1/2] rust: device: remove unused ref-to-ref transmute 2026-05-28 13:29 ` Gary Guo @ 2026-05-30 11:17 ` Tamir Duberstein 0 siblings, 0 replies; 7+ messages in thread From: Tamir Duberstein @ 2026-05-30 11:17 UTC (permalink / raw) To: Gary Guo Cc: Greg Kroah-Hartman, Rafael J. Wysocki, Danilo Krummrich, Miguel Ojeda, Boqun Feng, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross, driver-core, rust-for-linux, linux-kernel On Sat, May 30, 2026 at 7:07 AM Gary Guo <gary@garyguo.net> wrote: > > On Tue May 26, 2026 at 3:39 PM BST, Tamir Duberstein wrote: > > The Ok return value of `read_array_from_fwnode_property` requires a > > reference-to-reference transmute to construct but is never read, thus > > remove it. > > > > Signed-off-by: Tamir Duberstein <tamird@kernel.org> > > --- > > rust/kernel/device/property.rs | 42 +++++++++++++++++------------------------- > > 1 file changed, 17 insertions(+), 25 deletions(-) > > > > diff --git a/rust/kernel/device/property.rs b/rust/kernel/device/property.rs > > index 5aead835fbbc..87be2784f7a7 100644 > > --- a/rust/kernel/device/property.rs > > +++ b/rust/kernel/device/property.rs > > @@ -136,18 +136,15 @@ pub fn property_read_array_vec<'fwnode, 'name, T: PropertyInt>( > > let mut val: KVec<T> = KVec::with_capacity(len, GFP_KERNEL)?; > > > > let res = T::read_array_from_fwnode_property(self, name, val.spare_capacity_mut()); > > - let res = match res { > > - Ok(_) => { > > - // SAFETY: > > - // - `len` is equal to `val.capacity - val.len`, because > > - // `val.capacity` is `len` and `val.len` is zero. > > - // - All elements within the interval [`0`, `len`) were initialized > > - // by `read_array_from_fwnode_property`. > > - unsafe { val.inc_len(len) } > > - Ok(val) > > - } > > - Err(e) => Err(e), > > - }; > > + let res = res.map(|()| { > > + // SAFETY: > > + // - `len` is equal to `val.capacity - val.len`, because > > + // `val.capacity` is `len` and `val.len` is zero. > > + // - All elements within the interval [`0`, `len`) were initialized > > + // by `read_array_from_fwnode_property`. > > + unsafe { val.inc_len(len) } > > + val > > + }); > > Ok(PropertyGuard { > > inner: res, > > fwnode: self, > > @@ -474,12 +471,12 @@ fn read_from_fwnode_property(fwnode: &FwNode, name: &CStr) -> Result<Self> { > > /// It must be public, because it appears in the signatures of other public > > /// functions, but its methods shouldn't be used outside the kernel crate. > > pub trait PropertyInt: Copy + Sealed { > > - /// Reads a property array. > > - fn read_array_from_fwnode_property<'a>( > > + /// Reads a property array into `out`. > > + fn read_array_from_fwnode_property( > > fwnode: &FwNode, > > name: &CStr, > > - out: &'a mut [MaybeUninit<Self>], > > - ) -> Result<&'a mut [Self]>; > > + out: &mut [MaybeUninit<Self>], > > + ) -> Result; > > I think the old signature is quite reasonable. You provide storage and the > buffer is filled and that the return value is the proof of initialization. > > If you're concerned with `transmute` it should just be replaced with > `assume_init_mut()`. The signature is reasonable, but it is dead code. This is a private function; I see no benefit in keeping dead code around. If it is needed in the future, it can be easily restored. ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH 2/2] rust: device: remove array copy 2026-05-26 14:39 [PATCH 0/2] rust: device: remove ref-to-ref transmute Tamir Duberstein 2026-05-26 14:39 ` [PATCH 1/2] rust: device: remove unused " Tamir Duberstein @ 2026-05-26 14:39 ` Tamir Duberstein 2026-05-26 16:29 ` Tamir Duberstein 1 sibling, 1 reply; 7+ messages in thread From: Tamir Duberstein @ 2026-05-26 14:39 UTC (permalink / raw) To: Greg Kroah-Hartman, Rafael J. Wysocki, Danilo Krummrich, Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross Cc: driver-core, rust-for-linux, linux-kernel, Tamir Duberstein `[T; N]::map` constructs a copy of the array which is not necessary here, thus follow the example in the `MaybeUninit` documentation and transmute `[MaybeUninit<T>; N]` to `[T; N]`. Signed-off-by: Tamir Duberstein <tamird@kernel.org> --- rust/kernel/device/property.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/rust/kernel/device/property.rs b/rust/kernel/device/property.rs index 87be2784f7a7..a85467c99636 100644 --- a/rust/kernel/device/property.rs +++ b/rust/kernel/device/property.rs @@ -549,7 +549,9 @@ fn read_from_fwnode_property(fwnode: &FwNode, name: &CStr) -> Result<Self> { // SAFETY: `val` is always initialized when // `fwnode_property_read_*_array` is successful. - Ok(val.map(|v| unsafe { v.assume_init() })) + // + // See https://doc.rust-lang.org/stable/core/mem/union.MaybeUninit.html#initializing-an-array-element-by-element. + Ok(unsafe { mem::transmute::<_, [$int; N]>(val) }) } } )* }; -- 2.54.0 ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH 2/2] rust: device: remove array copy 2026-05-26 14:39 ` [PATCH 2/2] rust: device: remove array copy Tamir Duberstein @ 2026-05-26 16:29 ` Tamir Duberstein 0 siblings, 0 replies; 7+ messages in thread From: Tamir Duberstein @ 2026-05-26 16:29 UTC (permalink / raw) To: Greg Kroah-Hartman, Rafael J. Wysocki, Danilo Krummrich, Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross Cc: driver-core, rust-for-linux, linux-kernel On Tue, May 26, 2026 at 10:39 AM Tamir Duberstein <tamird@kernel.org> wrote: > > `[T; N]::map` constructs a copy of the array which is not necessary > here, thus follow the example in the `MaybeUninit` documentation and > transmute `[MaybeUninit<T>; N]` to `[T; N]`. > > Signed-off-by: Tamir Duberstein <tamird@kernel.org> Please disregard this patch from consideration (but please still consider patch 1/2). ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-05-30 11:18 UTC | newest] Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2026-05-26 14:39 [PATCH 0/2] rust: device: remove ref-to-ref transmute Tamir Duberstein 2026-05-26 14:39 ` [PATCH 1/2] rust: device: remove unused " Tamir Duberstein 2026-05-26 18:45 ` Onur Özkan 2026-05-28 13:29 ` Gary Guo 2026-05-30 11:17 ` Tamir Duberstein 2026-05-26 14:39 ` [PATCH 2/2] rust: device: remove array copy Tamir Duberstein 2026-05-26 16:29 ` Tamir Duberstein
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®