Thread (32 messages) 32 messages, 7 authors, 2026-03-23

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

From: "Danilo Krummrich" <dakr@kernel.org>
Date: 2026-03-19 12:06:07
Also in: amd-gfx, dri-devel, intel-gfx, intel-xe, linux-doc, lkml, rust-for-linux

On Thu Mar 19, 2026 at 12:39 PM CET, Gary Guo wrote:
On Tue Mar 17, 2026 at 8:17 PM GMT, Joel Fernandes wrote:
quoted
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 <redacted>
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

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

?
quoted
+
+        // 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.
Either you are proposing to not wrap unsafe code within unsafe {} within the
macro, such that the user is forced to write an unsafe {} around the macro, but
then they calls within the macro are not justified individually, or you propose
to let the user write an unsafe {} around the macro regardless of the inner
unsafe {} blocks, but then then the compiler warns about an unnecessary unsafe
and nothing forces the user to actually wrap it in unsafe {}.

Is there a third option I'm not aware of? I.e. for the above reason
impl_device_context_deref!() was designed the same way.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/rust/kernel/device.rs#n650
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help