On 3/18/2026 2:31 PM, Joel Fernandes wrote:
>
>
> 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.
Here is the clist fixup fixing both the clippy errors in list.rs:
https://git.kernel.org/pub/scm/linux/kernel/git/jfern/linux.git/commit/?h=nova/mm&id=226e1c75932aec3fde66b4b4a36abd8de919c6da
Thanks.