Messages in this thread |  | | Date | Wed, 18 Mar 2026 14:31:35 -0400 | | From | Joel Fernandes <> | | Subject | Re: [PATCH v13 1/1] rust: interop: Add list module for C linked list interface |
| |
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 <ndjukic@nvidia.com> >> Reviewed-by: Daniel Almeida <daniel.almeida@collabora.com> >> Reviewed-by: Alexandre Courbot <acourbot@nvidia.com> >> Acked-by: Alexandre Courbot <acourbot@nvidia.com> >> Acked-by: Gary Guo <gary@garyguo.net> >> Acked-by: Miguel Ojeda <ojeda@kernel.org> >> Signed-off-by: Joel Fernandes <joelagnelf@nvidia.com> >> --- >> 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 <joelagnelf@nvidia.com> >> +M: Alexandre Courbot <acourbot@nvidia.com> >> +L: rust-for-linux@vger.kernel.org >> +S: Maintained >> +T: git https://github.com/Rust-for-Linux/linux.git interop-next >> +F: rust/kernel/interop/ >> + >> RUST [NUM] >> M: Alexandre Courbot <acourbot@nvidia.com> >> R: Yury Norov <yury.norov@gmail.com> >> 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-yQJk77dPid89LExw@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
|  |