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]>

I have a few nits below. But overall I think this looks ok:

Reviewed-by: Alice Ryhl <[email protected]>

Please do consider my mod.rs suggestion too, though.

> +//! ```
> +//! use kernel::{
> +//!     bindings,
> +//!     clist_create,

IMO the automatic re-exports of macros at the root shouldn't be used.
Import it from kernel::interop::list::clist_create instead.

Note that you need to put a re-export below macro definition to do this.

        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).+ };
        
                // 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) }
            }};
        }
        pub use clist_create; // <-- you need this

See tracepoint.rs or any of the other macros for an example.

> +//! // 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 });

Did you try using this in your real use-case? You require `head` to be
an :ident, but I think for any 'struct list_head' not stored on the
stack, accepting an :expr would be easier to use so that you can just
pass `&raw mut my_c_struct.the_list_head` directly to the macro. Right
now you have to put the raw pointer in a local variable first.

Alice

Reply via email to