Skip to contentSkip to conversation

rust: list: undo unintended replacement of method name

PATCH Applied Miguel Ojeda 4 participants 6 messages Jul 19, 2025 – Jul 20, 2025 Rust

lore
Share & tools
lore

Miguel Ojeda

author maintainer
#0 lore raw

PATCH 1/1 rust: list: undo unintended replacement of method name

When we renamed Opaque::raw_get to cast_into, there was one replacement that was not supposed to be there.

It does not cause an issue so far because it is inside a macro rule (the ListLinksSelfPtr one) that is unused so far. However, it will start to be used soon.

Thus fix it now.

Fixes 64fb810bce03 ("rust: types: rename Opaque::raw_get to cast_into")
---
 rust/kernel/list/impl_list_item_mod.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
rust/kernel/list/impl_list_item_mod.rs +1 -1
index c1edba0a9501..3f6c30e14904 100644
@@ -252,7 +252,7 @@ unsafe fn view_value(links_field: *mut $crate::list::ListLinks<$num>) -> *const
                 // the pointer stays in bounds of the allocation.
                 let self_ptr = unsafe { (links_field as *const u8).add(spoff) }
                     as *const ::core::cell::UnsafeCell<*const Self>;
-                let cell_inner = ::core::cell::UnsafeCell::cast_into(self_ptr);
+                let cell_inner = ::core::cell::UnsafeCell::raw_get(self_ptr);
                 // SAFETY: This is not a data race, because the only function that writes to this
                 // value is `prepare_to_insert`, but by the safety requirements the
                 // `prepare_to_insert` method may not be called in parallel with `view_value` or

base-commit: 23b128bba76776541dc09efaf3acf6242917e1f0 --
2.50.1

#1 lore raw

PATCH 1/1 rust: list: Add an example for `ListLinksSelfPtr` usage

It appears that the support for ListLinksSelfPtr is dead code at the moment [1]. Hence add an example similar to ListLinks usage to help catching bugs and demonstrating the usage.

The example is mostly based on Alice's usage in binder driver[2].

---
 rust/kernel/list.rs | 125 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 125 insertions(+)
rust/kernel/list.rs +125 -0
index 7ebb81b2a3d4..f66898738b31 100644
@@ -38,6 +38,8 @@
 ///
 /// # Examples
 ///
+/// Use [`ListLinks`] as the type of the intrusive field.
+///
 /// ```
 /// use kernel::list::*;
 ///
@@ -143,6 +145,129 @@
 /// }
 /// # Result::<(), Error>::Ok(())
 /// ```
+///
+/// Use [`ListLinksSelfPtr`] as the type of the intrusive field. This allows a list of trait object
+/// type.
+///
+/// ```
+/// use kernel::list::*;
+///
+/// trait Trait {
+///     fn foo(&self) -> (&'static str, i32);
+/// }
+///
+/// #[pin_data]
+/// struct DTWrap<T: ?Sized> {
+///     #[pin]
+///     links: ListLinksSelfPtr<DTWrap<dyn Trait>>,
+///     value: T,
+/// }
+///
+/// impl<T> DTWrap<T> {
+///     fn new(value: T) -> Result<ListArc<Self>> {
+///         ListArc::pin_init(try_pin_init!(Self {
+///             value,
+///             links <- ListLinksSelfPtr::new(),
+///         }), GFP_KERNEL)
+///     }
+/// }
+///
+/// impl_has_list_links_self_ptr! {
+///     impl HasSelfPtr<DTWrap<dyn Trait>> for DTWrap<dyn Trait> { self.links }
+/// }
+/// impl_list_arc_safe! {
+///     impl{T: ?Sized} ListArcSafe<0> for DTWrap<T> { untracked; }
+/// }
+/// impl_list_item! {
+///     impl ListItem<0> for DTWrap<dyn Trait> { using ListLinksSelfPtr; }
+/// }
+///
+/// // Create a new empty list.
+/// let mut list = List::<DTWrap<dyn Trait>>::new();
+/// {
+///     assert!(list.is_empty());
+/// }
+///
+/// struct A(i32);
+///
+/// // `A` returns the inner value for `foo`.
+/// impl Trait for A { fn foo(&self) -> (&'static str, i32) { ("a", self.0) } }
+///
+/// struct B;
+/// // `B` always returns 42.
+/// impl Trait for B { fn foo(&self) -> (&'static str, i32) { ("b", 42) } }
+///
+/// // Insert 3 element using `push_back()`.
+/// list.push_back(DTWrap::new(A(15))?);
+/// list.push_back(DTWrap::new(A(32))?);
+/// list.push_back(DTWrap::new(B)?);
+///
+/// // Iterate over the list to verify the nodes were inserted correctly.
+/// // [A(15), A(32), B]
+/// {
+///     let mut iter = list.iter();
+///     assert_eq!(iter.next().ok_or(EINVAL)?.value.foo(), ("a", 15));
+///     assert_eq!(iter.next().ok_or(EINVAL)?.value.foo(), ("a", 32));
+///     assert_eq!(iter.next().ok_or(EINVAL)?.value.foo(), ("b", 42));
+///     assert!(iter.next().is_none());
+///
+///     // Verify the length of the list.
+///     assert_eq!(list.iter().count(), 3);
+/// }
+///
+/// // Pop the items from the list using `pop_back()` and verify the content.
+/// {
+///     assert_eq!(list.pop_back().ok_or(EINVAL)?.value.foo(), ("b", 42));
+///     assert_eq!(list.pop_back().ok_or(EINVAL)?.value.foo(), ("a", 32));
+///     assert_eq!(list.pop_back().ok_or(EINVAL)?.value.foo(), ("a", 15));
+/// }
+///
+/// // Insert 3 elements using `push_front()`.
+/// list.push_front(DTWrap::new(A(15))?);
+/// list.push_front(DTWrap::new(A(32))?);
+/// list.push_front(DTWrap::new(B)?);
+///
+/// // Iterate over the list to verify the nodes were inserted correctly.
+/// // [B, A(32), A(15)]
+/// {
+///     let mut iter = list.iter();
+///     assert_eq!(iter.next().ok_or(EINVAL)?.value.foo(), ("b", 42));
+///     assert_eq!(iter.next().ok_or(EINVAL)?.value.foo(), ("a", 32));
+///     assert_eq!(iter.next().ok_or(EINVAL)?.value.foo(), ("a", 15));
+///     assert!(iter.next().is_none());
+///
+///     // Verify the length of the list.
+///     assert_eq!(list.iter().count(), 3);
+/// }
+///
+/// // Pop the items from the list using `pop_front()` and verify the content.
+/// {
+///     assert_eq!(list.pop_back().ok_or(EINVAL)?.value.foo(), ("a", 15));
+///     assert_eq!(list.pop_back().ok_or(EINVAL)?.value.foo(), ("a", 32));
+/// }
+///
+/// // Push `list2` to `list` through `push_all_back()`.
+/// // list: [B]
+/// // list2: [B, A(25)]
+/// {
+///     let mut list2 = List::<DTWrap<dyn Trait>>::new();
+///     list2.push_back(DTWrap::new(B)?);
+///     list2.push_back(DTWrap::new(A(25))?);
+///
+///     list.push_all_back(&mut list2);
+///
+///     // list: [B, B, A(25)]
+///     // list2: []
+///     let mut iter = list.iter();
+///     assert_eq!(iter.next().ok_or(EINVAL)?.value.foo(), ("b", 42));
+///     assert_eq!(iter.next().ok_or(EINVAL)?.value.foo(), ("b", 42));
+///     assert_eq!(iter.next().ok_or(EINVAL)?.value.foo(), ("a", 25));
+///     assert!(iter.next().is_none());
+///     assert!(list2.is_empty());
+/// }
+/// # Result::<(), Error>::Ok(())
+/// ```
+///
 pub struct List<T: ?Sized + ListItem<ID>, const ID: u64 = 0> {
     first: *mut ListLinksFields,
     _ty: PhantomData<ListArc<T, ID>>,
Signature · 1 line
2.39.5 (Apple Git-154)
#2 lore raw

Re: [PATCH] rust: list: Add an example for `ListLinksSelfPtr` usage

Quoted 10 lines · Boqun Feng

It appears that the support for ListLinksSelfPtr is dead code at the moment [1]. Hence add an example similar to ListLinks usage to help catching bugs and demonstrating the usage.

The example is mostly based on Alice's usage in binder driver[2].

I sent that one because I am applying Tamir's series, which triggered the error -- maybe you can put it on top of those?

If you do, please note that you need a couple changes -- I will push them to rust-next so that you have them.

    https://lore.kernel.org/rust-for-linux/[email protected]/

Thanks!

Cheers,
Miguel

#3 lore raw

Re: [PATCH] rust: list: Add an example for `ListLinksSelfPtr` usage

Quoted 6 lines · Miguel Ojeda
Quoted 5 lines · Boqun Feng

It appears that the support for ListLinksSelfPtr is dead code at the moment [1]. Hence add an example similar to ListLinks usage to help catching bugs and demonstrating the usage.

Quoted 9 lines
Quoted 5 lines

The example is mostly based on Alice's usage in binder driver[2].

I sent that one because I am applying Tamir's series, which triggered the error -- maybe you can put it on top of those?

Sure. I overlooked Tamir's series.

Quoted 3 lines

If you do, please note that you need a couple changes -- I will push them to rust-next so that you have them.

Will do, thank you. ;-)

Regards,
Boqun

Quoted 6 lines
    https://lore.kernel.org/rust-for-linux/[email protected]/

Thanks!

Cheers,
Miguel

Reviewed-by on v1 1/1
#4 lore raw
In reply to Miguel Ojeda
Quoted 4 lines · Miguel Ojeda

When we renamed Opaque::raw_get to cast_into, there was one replacement that was not supposed to be there.

Quoted 8 lines

It does not cause an issue so far because it is inside a macro rule (the ListLinksSelfPtr one) that is unused so far. However, it will start to be used soon.

Thus fix it now.

Fixes 64fb810bce03 ("rust: types: rename Opaque::raw_get to cast_into")
Quoted 22 lines
---
 rust/kernel/list/impl_list_item_mod.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
rust/kernel/list/impl_list_item_mod.rs +1 -1
index c1edba0a9501..3f6c30e14904 100644
@@ -252,7 +252,7 @@ unsafe fn view_value(links_field: *mut $crate::list::ListLinks<$num>) -> *const
                 // the pointer stays in bounds of the allocation.
                 let self_ptr = unsafe { (links_field as *const u8).add(spoff) }
                     as *const ::core::cell::UnsafeCell<*const Self>;
-                let cell_inner = ::core::cell::UnsafeCell::cast_into(self_ptr);
+                let cell_inner = ::core::cell::UnsafeCell::raw_get(self_ptr);
                 // SAFETY: This is not a data race, because the only function that writes to this
                 // value is `prepare_to_insert`, but by the safety requirements the
                 // `prepare_to_insert` method may not be called in parallel with `view_value` or

base-commit: 23b128bba76776541dc09efaf3acf6242917e1f0 --
2.50.1

Applied
#5 lore raw
In reply to Miguel Ojeda
Quoted 4 lines · Miguel Ojeda

When we renamed Opaque::raw_get to cast_into, there was one replacement that was not supposed to be there.

Quoted 8 lines

It does not cause an issue so far because it is inside a macro rule (the ListLinksSelfPtr one) that is unused so far. However, it will start to be used soon.

Thus fix it now.

Fixes 64fb810bce03 ("rust: types: rename Opaque::raw_get to cast_into")

Applied to rust-next -- thanks everyone!

Cheers,
Miguel