On 3/18/2026 8:40 AM, Alice Ryhl wrote:
> On Tue, Mar 17, 2026 at 04:17:10PM -0400, Joel Fernandes wrote:
>> Add a new module `kernel::interop::list` for working with C's doubly
>> circular linked lists. Provide low-level iteration over list nodes.
>>
>> Typed iteration over actual items is provided with a `clist_create`
>> macro to assist in creation of the `CList` type.
>>
>> Cc: Nikola Djukic <[email protected]>
>> Reviewed-by: Daniel Almeida <[email protected]>
>> Reviewed-by: Alexandre Courbot <[email protected]>
>> Acked-by: Alexandre Courbot <[email protected]>
>> Acked-by: Gary Guo <[email protected]>
>> Acked-by: Miguel Ojeda <[email protected]>
>> Signed-off-by: Joel Fernandes <[email protected]>
>> ---
>>  MAINTAINERS                 |   8 +
>>  rust/helpers/helpers.c      |   1 +
>>  rust/helpers/list.c         |  17 ++
>>  rust/kernel/interop.rs      |   9 +
>>  rust/kernel/interop/list.rs | 342 ++++++++++++++++++++++++++++++++++++
>>  rust/kernel/lib.rs          |   2 +
>>  6 files changed, 379 insertions(+)
>>  create mode 100644 rust/helpers/list.c
>>  create mode 100644 rust/kernel/interop.rs
>>  create mode 100644 rust/kernel/interop/list.rs
>>
>> diff --git a/MAINTAINERS b/MAINTAINERS
>> index 4bd6b538a51f..e847099efcc2 100644
>> --- a/MAINTAINERS
>> +++ b/MAINTAINERS
>> @@ -23251,6 +23251,14 @@ T:  git https://github.com/Rust-for-Linux/linux.git 
>> alloc-next
>>  F:  rust/kernel/alloc.rs
>>  F:  rust/kernel/alloc/
>>  
>> +RUST [INTEROP]
>> +M:  Joel Fernandes <[email protected]>
>> +M:  Alexandre Courbot <[email protected]>
>> +L:  [email protected]
>> +S:  Maintained
>> +T:  git https://github.com/Rust-for-Linux/linux.git interop-next
>> +F:  rust/kernel/interop/
>> +
>>  RUST [NUM]
>>  M:  Alexandre Courbot <[email protected]>
>>  R:  Yury Norov <[email protected]>
>> diff --git a/rust/helpers/helpers.c b/rust/helpers/helpers.c
>> index a3c42e51f00a..724fcb8240ac 100644
>> --- a/rust/helpers/helpers.c
>> +++ b/rust/helpers/helpers.c
>> @@ -35,6 +35,7 @@
>>  #include "io.c"
>>  #include "jump_label.c"
>>  #include "kunit.c"
>> +#include "list.c"
>>  #include "maple_tree.c"
>>  #include "mm.c"
>>  #include "mutex.c"
>> diff --git a/rust/helpers/list.c b/rust/helpers/list.c
>> new file mode 100644
>> index 000000000000..18095a5593c5
>> --- /dev/null
>> +++ b/rust/helpers/list.c
>> @@ -0,0 +1,17 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +
>> +/*
>> + * Helpers for C circular doubly linked list implementation.
>> + */
>> +
>> +#include <linux/list.h>
>> +
>> +__rust_helper void rust_helper_INIT_LIST_HEAD(struct list_head *list)
>> +{
>> +    INIT_LIST_HEAD(list);
>> +}
>> +
>> +__rust_helper void rust_helper_list_add_tail(struct list_head *new, struct 
>> list_head *head)
>> +{
>> +    list_add_tail(new, head);
>> +}
>> diff --git a/rust/kernel/interop.rs b/rust/kernel/interop.rs
>> new file mode 100644
>> index 000000000000..b88140cf76dc
>> --- /dev/null
>> +++ b/rust/kernel/interop.rs
>> @@ -0,0 +1,9 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +
>> +//! Infrastructure for interfacing Rust code with C kernel subsystems.
>> +//!
>> +//! This module is intended for low-level, unsafe Rust infrastructure code
>> +//! that interoperates between Rust and C. It is NOT for use directly in
>> +//! Rust drivers.
>> +
>> +pub mod list;
>> diff --git a/rust/kernel/interop/list.rs b/rust/kernel/interop/list.rs
>> new file mode 100644
>> index 000000000000..328f6b0de2ce
>> --- /dev/null
>> +++ b/rust/kernel/interop/list.rs
>> @@ -0,0 +1,342 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +
>> +//! Rust interface for C doubly circular intrusive linked lists.
>> +//!
>> +//! This module provides Rust abstractions for iterating over C 
>> `list_head`-based
>> +//! linked lists. It should only be used for cases where C and Rust code 
>> share
>> +//! direct access to the same linked list through a C interop interface.
>> +//!
>> +//! Note: This *must not* be used by Rust components that just need a 
>> linked list
>> +//! primitive. Use [`kernel::list::List`] instead.
>> +//!
>> +//! # Examples
>> +//!
>> +//! ```
>> +//! use kernel::{
>> +//!     bindings,
>> +//!     clist_create,
>> +//!     types::Opaque,
>> +//! };
>> +//! # // Create test list with values (0, 10, 20) - normally done by C code 
>> but it is
>> +//! # // emulated here for doctests using the C bindings.
>> +//! # use core::mem::MaybeUninit;
>> +//! #
>> +//! # /// C struct with embedded `list_head` (typically will be allocated 
>> by C code).
>> +//! # #[repr(C)]
>> +//! # pub struct SampleItemC {
>> +//! #     pub value: i32,
>> +//! #     pub link: bindings::list_head,
>> +//! # }
>> +//! #
>> +//! # let mut head = MaybeUninit::<bindings::list_head>::uninit();
>> +//! #
>> +//! # let head = head.as_mut_ptr();
>> +//! # // SAFETY: `head` and all the items are test objects allocated in 
>> this scope.
>> +//! # unsafe { bindings::INIT_LIST_HEAD(head) };
>> +//! #
>> +//! # let mut items = [
>> +//! #     MaybeUninit::<SampleItemC>::uninit(),
>> +//! #     MaybeUninit::<SampleItemC>::uninit(),
>> +//! #     MaybeUninit::<SampleItemC>::uninit(),
>> +//! # ];
>> +//! #
>> +//! # for (i, item) in items.iter_mut().enumerate() {
>> +//! #     let ptr = item.as_mut_ptr();
>> +//! #     // SAFETY: `ptr` points to a valid `MaybeUninit<SampleItemC>`.
>> +//! #     unsafe { (*ptr).value = i as i32 * 10 };
>> +//! #     // SAFETY: `&raw mut` creates a pointer valid for 
>> `INIT_LIST_HEAD`.
>> +//! #     unsafe { bindings::INIT_LIST_HEAD(&raw mut (*ptr).link) };
>> +//! #     // SAFETY: `link` was just initialized and `head` is a valid list 
>> head.
>> +//! #     unsafe { bindings::list_add_tail(&mut (*ptr).link, head) };
>> +//! # }
>> +//!
>> +//! //
>> +//! /// Rust wrapper for the C struct.
>> +//! ///
>> +//! /// The list item struct in this example is defined in C code as:
>> +//! ///
>> +//! /// ```c
>> +//! /// struct SampleItemC {
>> +//! ///     int value;
>> +//! ///     struct list_head link;
>> +//! /// };
>> +//! /// ```
>> +//! #[repr(transparent)]
>> +//! pub struct Item(Opaque<SampleItemC>);
>> +//!
>> +//! impl Item {
>> +//!     pub fn value(&self) -> i32 {
>> +//!         // SAFETY: `Item` has same layout as `SampleItemC`.
>> +//!         unsafe { (*self.0.get()).value }
>> +//!     }
>> +//! }
>> +//!
>> +//!
>> +//! // Create typed [`CList`] from sentinel head.
>> +//! // SAFETY: `head` is valid and initialized, items are `SampleItemC` with
>> +//! // embedded `link` field, and `Item` is `#[repr(transparent)]` over 
>> `SampleItemC`.
>> +//! let list = clist_create!(unsafe { head, Item, SampleItemC, link });
> 
> Bad news.
> 
> My build triggers this warning:
> 
> error: statement has unnecessary safety comment
>     --> rust/doctests_kernel_generated.rs:7103:1
>      |
> 7103 | let list = clist_create!(unsafe { head, Item, SampleItemC, link });
>      | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>      |
> help: consider removing the safety comment
>     --> rust/doctests_kernel_generated.rs:7101:4
>      |
> 7101 | // SAFETY: `head` is valid and initialized, items are `SampleItemC` 
> with
>      |    
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>      = help: for further information visit 
> https://rust-lang.github.io/rust-clippy/rust-1.94.0/index.html#unnecessary_safety_comment
>      = note: `-D clippy::unnecessary-safety-comment` implied by `-D warnings`
>      = help: to override `-D warnings` add 
> `#[allow(clippy::unnecessary_safety_comment)]`
> 
> This probably needs to be:
> 
>       unsafe { clist_create!(head, Item, SampleItemC, link) }

Oops, I sometimes run clippy wrong. I did: "CLIPPY=1 make" instead of "make
CLIPPY=1", the reason is habit. I have been doing "LLVM=1 make" for llvm
builds since many years.

Anyway, the fix is simple, just need to do // SAFETY*: as Miguel suggests
here, instead of // SAFETY:
https://lore.kernel.org/all/caniq72kendyupnwmzmhejytjioeijuk_c-yqjk77dpid89l...@mail.gmail.com/

Should be easy to do on apply if Danilo doesn't mind. :) I verified on my
setup that it fixes it.

thanks,

--
Joel Fernandes

Reply via email to