Re: [PATCH v13 1/1] rust: interop: Add list module for C linked list interface

From: Gary Guo

Date: Thu Mar 19 2026 - 07:48:38 EST


On Tue Mar 17, 2026 at 8:17 PM GMT, 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@xxxxxxxxxx>
> Reviewed-by: Daniel Almeida <daniel.almeida@xxxxxxxxxxxxx>
> Reviewed-by: Alexandre Courbot <acourbot@xxxxxxxxxx>
> Acked-by: Alexandre Courbot <acourbot@xxxxxxxxxx>
> Acked-by: Gary Guo <gary@xxxxxxxxxxx>
> Acked-by: Miguel Ojeda <ojeda@xxxxxxxxxx>
> Signed-off-by: Joel Fernandes <joelagnelf@xxxxxxxxxx>
> ---
> 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
>
> +/// Create a C doubly-circular linked list interface [`CList`] from a raw `list_head` pointer.
> +///
> +/// This macro creates a `CList<T, OFFSET>` that can iterate over items of type `$rust_type`
> +/// linked via the `$field` field in the underlying C struct `$c_type`.
> +///
> +/// # Arguments
> +///
> +/// - `$head`: Raw pointer to the sentinel `list_head` object (`*mut bindings::list_head`).
> +/// - `$rust_type`: Each item's rust wrapper type.
> +/// - `$c_type`: Each item's C struct type that contains the embedded `list_head`.
> +/// - `$field`: The name of the `list_head` field within the C struct.
> +///
> +/// # Safety
> +///
> +/// The caller must ensure:
> +///
> +/// - `$head` is a valid, initialized sentinel `list_head` (e.g. via `INIT_LIST_HEAD()`)
> +/// pointing to a list that is not concurrently modified for the lifetime of the [`CList`].
> +/// - The list contains items of type `$c_type` linked via an embedded `$field`.
> +/// - `$rust_type` is `#[repr(transparent)]` over `$c_type` or has compatible layout.
> +///
> +/// # Examples
> +///
> +/// Refer to the examples in the [`crate::interop::list`] module documentation.
> +#[macro_export]
> +macro_rules! clist_create {
> + (unsafe { $head:ident, $rust_type:ty, $c_type:ty, $($field:tt).+ }) => {{
> + // Compile-time check that field path is a `list_head`.
> + // SAFETY: `p` is a valid pointer to `$c_type`.
> + let _: fn(*const $c_type) -> *const $crate::bindings::list_head =
> + |p| unsafe { &raw const (*p).$($field).+ };

Actually, this check is insufficient, you should create a reference instead
(just in case people put this inside `repr(packed)`.

This could be something like

let _ = |p: &$c_type| { _ = &p.$($field).+ }

?

> +
> + // Calculate offset and create `CList`.
> + const OFFSET: usize = ::core::mem::offset_of!($c_type, $($field).+);
> + // SAFETY: The caller of this macro is responsible for ensuring safety.
> + unsafe { $crate::interop::list::CList::<$rust_type, OFFSET>::from_raw($head) }

Given that this is unsafe, I am not sure why the macro should have unsafe
keyword in it, rather than just being `clist_create(a, b, c, d)` and just have
user write unsafe.

The offset could probably benefit from similar strategies we used for other
embedded data structure like Rust list and work items. Boqun has a series
unifying these and clist could probably use it, too. (As a follow-up)

Best,
Gary

> + }};
> +}
> diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs
> index d93292d47420..bdcf632050ee 100644
> --- a/rust/kernel/lib.rs
> +++ b/rust/kernel/lib.rs
> @@ -29,6 +29,7 @@
> #![feature(lint_reasons)]
> //
> // Stable since Rust 1.82.0.
> +#![feature(offset_of_nested)]
> #![feature(raw_ref_op)]
> //
> // Stable since Rust 1.83.0.
> @@ -107,6 +108,7 @@
> #[doc(hidden)]
> pub mod impl_flags;
> pub mod init;
> +pub mod interop;
> pub mod io;
> pub mod ioctl;
> pub mod iommu;
G