Rust for Linux List
 help / color / mirror / Atom feed
* [PATCH v2 0/6] Rework index projection syntax
@ 2026-06-02 14:17 Gary Guo
  2026-06-02 14:17 ` [PATCH v2 1/6] rust: ptr: rename `ProjectIndex::index` to `build_index` Gary Guo
                   ` (6 more replies)
  0 siblings, 7 replies; 8+ messages in thread
From: Gary Guo @ 2026-06-02 14:17 UTC (permalink / raw)
  To: Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron,
	Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
	Danilo Krummrich, Abdiel Janulgue, Daniel Almeida, Robin Murphy,
	Alexandre Courbot, David Airlie, Simona Vetter
  Cc: rust-for-linux, linux-kernel, driver-core, nova-gpu, dri-devel

This series reworks the index projection syntax in the pointer
projection infrastructure to use the keyworded syntax to be more explicit.

Doing this allows adding a new panicking variant of index projection,
just like the normal index operator. This is useful for cases where
compiler cannot prove (or cannot reliably prove) access is inbounds.

The new syntax looks like this:
- `[try: index]`: Fallible indexing (replaces `[index]?`).
- `[build: index]`: Build-time checked indexing (replaces `[index]`).
- `[panic: index]`: Runtime panicking indexing (newly added).

DMA sample driver and nova core is updated.

Danilo, we previously discussed merging this series with I/O projection for
patch logistics. However, I'll need more time for next version of I/O
projection (implementing view types that have original container type
erased) which won't make it this cycle. This new version for projection
syntax rework is minor changes only comparde to v1, so I think it's worth
sending out so it can still land this cycle and get out of the way.

---
Changes in v2:
- Fix missing colon in documentation (Alice)
- Reworded safety comment (Andreas)
- Convert `unwrap_or_else` to match (Alice)
- Split rename of `index` to `build_index` to a separate patch (Alex)
- Dropped nova cmdq refactor as this will be better served in the I/O
  projection series.
- Link to v1: https://patch.msgid.link/20260415-projection-syntax-rework-v1-0-450723cb3727@garyguo.net

To: Miguel Ojeda <ojeda@kernel.org>
To: Boqun Feng <boqun@kernel.org>
To: Gary Guo <gary@garyguo.net>
To: Björn Roy Baron <bjorn3_gh@protonmail.com>
To: Benno Lossin <lossin@kernel.org>
To: Andreas Hindborg <a.hindborg@kernel.org>
To: Alice Ryhl <aliceryhl@google.com>
To: Trevor Gross <tmgross@umich.edu>
To: Danilo Krummrich <dakr@kernel.org>
To: Abdiel Janulgue <abdiel.janulgue@gmail.com>
To: Daniel Almeida <daniel.almeida@collabora.com>
To: Robin Murphy <robin.murphy@arm.com>
To: Alexandre Courbot <acourbot@nvidia.com>
To: David Airlie <airlied@gmail.com>
To: Simona Vetter <simona@ffwll.ch>
Cc: rust-for-linux@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Cc: driver-core@lists.linux.dev
Cc: nova-gpu@lists.linux.dev
Cc: dri-devel@lists.freedesktop.org

---
Gary Guo (6):
      rust: ptr: rename `ProjectIndex::index` to `build_index`
      rust: ptr: use `match` instead of `unwrap_or_else` for `build_index`
      rust: ptr: add panicking index projection variant
      rust: dma: update to keyworded index projection syntax
      gpu: nova-core: convert to keyworded projection syntax
      rust: ptr: remove implicit index projection syntax

 drivers/gpu/nova-core/gsp/cmdq.rs |  6 +--
 rust/kernel/dma.rs                | 15 +++---
 rust/kernel/ptr/projection.rs     | 97 +++++++++++++++++++++++++++++++--------
 samples/rust/rust_dma.rs          | 12 ++---
 4 files changed, 93 insertions(+), 37 deletions(-)
---
base-commit: 46def663dd34da36464ba059f7cfeacf29d98e5e
change-id: 20260415-projection-syntax-rework-b790a305bc52

Best regards,
--  
Gary Guo <gary@garyguo.net>


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH v2 1/6] rust: ptr: rename `ProjectIndex::index` to `build_index`
  2026-06-02 14:17 [PATCH v2 0/6] Rework index projection syntax Gary Guo
@ 2026-06-02 14:17 ` Gary Guo
  2026-06-02 14:17 ` [PATCH v2 2/6] rust: ptr: use `match` instead of `unwrap_or_else` for `build_index` Gary Guo
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Gary Guo @ 2026-06-02 14:17 UTC (permalink / raw)
  To: Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron,
	Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
	Danilo Krummrich, Abdiel Janulgue, Daniel Almeida, Robin Murphy,
	Alexandre Courbot, David Airlie, Simona Vetter
  Cc: rust-for-linux, linux-kernel, driver-core, nova-gpu, dri-devel

The corresponding `SliceIndex` trait in Rust uses `index` to mean the
panicking variant, which is also being added to `ProjectIndex`. Hence
rename our custom `build_error!` index variant to `build_index`.

Suggested-by: Alexandre Courbot <acourbot@nvidia.com>
Link: https://lore.kernel.org/rust-for-linux/DI5LLN2V3XCS.34H4CG99N4MPA@nvidia.com
Signed-off-by: Gary Guo <gary@garyguo.net>
---
 rust/kernel/ptr/projection.rs | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/rust/kernel/ptr/projection.rs b/rust/kernel/ptr/projection.rs
index 140ea8e21617..fbe172e493c2 100644
--- a/rust/kernel/ptr/projection.rs
+++ b/rust/kernel/ptr/projection.rs
@@ -26,14 +26,14 @@ fn from(_: OutOfBound) -> Self {
 ///
 /// # Safety
 ///
-/// The implementation of `index` and `get` (if [`Some`] is returned) must ensure that, if provided
-/// input pointer `slice` and returned pointer `output`, then:
+/// For given input pointer `slice` and return value `output`, the implementation of `build_index`
+/// and `get` (if [`Some`] is returned) must ensure that:
 /// - `output` has the same provenance as `slice`;
 /// - `output.byte_offset_from(slice)` is between 0 to
 ///   `KnownSize::size(slice) - KnownSize::size(output)`.
 ///
-/// This means that if the input pointer is valid, then pointer returned by `get` or `index` is
-/// also valid.
+/// This means that if the input pointer is valid, then pointer returned by `get` or `build_index`
+/// is also valid.
 #[diagnostic::on_unimplemented(message = "`{Self}` cannot be used to index `{T}`")]
 #[doc(hidden)]
 pub unsafe trait ProjectIndex<T: ?Sized>: Sized {
@@ -44,7 +44,7 @@ pub unsafe trait ProjectIndex<T: ?Sized>: Sized {
 
     /// Returns an index-projected pointer; fail the build if it cannot be proved to be in bounds.
     #[inline(always)]
-    fn index(self, slice: *mut T) -> *mut Self::Output {
+    fn build_index(self, slice: *mut T) -> *mut Self::Output {
         Self::get(self, slice).unwrap_or_else(|| build_error!())
     }
 }
@@ -64,8 +64,8 @@ fn index(self, slice: *mut T) -> *mut Self::Output {
     }
 
     #[inline(always)]
-    fn index(self, slice: *mut [T; N]) -> *mut Self::Output {
-        <I as ProjectIndex<[T]>>::index(self, slice)
+    fn build_index(self, slice: *mut [T; N]) -> *mut Self::Output {
+        <I as ProjectIndex<[T]>>::build_index(self, slice)
     }
 }
 
@@ -287,7 +287,7 @@ macro_rules! project_pointer {
     };
     // Build-time checked index projection.
     (@gen $ptr:ident, [$index:expr] $($rest:tt)*) => {
-        let $ptr = $crate::ptr::projection::ProjectIndex::index($index, $ptr);
+        let $ptr = $crate::ptr::projection::ProjectIndex::build_index($index, $ptr);
         $crate::ptr::project!(@gen $ptr, $($rest)*)
     };
     (mut $ptr:expr, $($proj:tt)*) => {{

-- 
2.54.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v2 2/6] rust: ptr: use `match` instead of `unwrap_or_else` for `build_index`
  2026-06-02 14:17 [PATCH v2 0/6] Rework index projection syntax Gary Guo
  2026-06-02 14:17 ` [PATCH v2 1/6] rust: ptr: rename `ProjectIndex::index` to `build_index` Gary Guo
@ 2026-06-02 14:17 ` Gary Guo
  2026-06-02 14:17 ` [PATCH v2 3/6] rust: ptr: add panicking index projection variant Gary Guo
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Gary Guo @ 2026-06-02 14:17 UTC (permalink / raw)
  To: Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron,
	Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
	Danilo Krummrich, Abdiel Janulgue, Daniel Almeida, Robin Murphy,
	Alexandre Courbot, David Airlie, Simona Vetter
  Cc: rust-for-linux, linux-kernel, driver-core, nova-gpu, dri-devel

Use `match` to avoid potential inlining issues of the `unwrap_or_else`
function.

Suggested-by: Alice Ryhl <aliceryhl@google.com>
Link: https://lore.kernel.org/rust-for-linux/aeCKlut-88SbNsyW@google.com/
Signed-off-by: Gary Guo <gary@garyguo.net>
---
 rust/kernel/ptr/projection.rs | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/rust/kernel/ptr/projection.rs b/rust/kernel/ptr/projection.rs
index fbe172e493c2..1b54616c6cbb 100644
--- a/rust/kernel/ptr/projection.rs
+++ b/rust/kernel/ptr/projection.rs
@@ -45,7 +45,10 @@ pub unsafe trait ProjectIndex<T: ?Sized>: Sized {
     /// Returns an index-projected pointer; fail the build if it cannot be proved to be in bounds.
     #[inline(always)]
     fn build_index(self, slice: *mut T) -> *mut Self::Output {
-        Self::get(self, slice).unwrap_or_else(|| build_error!())
+        match Self::get(self, slice) {
+            Some(v) => v,
+            None => build_error!(),
+        }
     }
 }
 

-- 
2.54.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v2 3/6] rust: ptr: add panicking index projection variant
  2026-06-02 14:17 [PATCH v2 0/6] Rework index projection syntax Gary Guo
  2026-06-02 14:17 ` [PATCH v2 1/6] rust: ptr: rename `ProjectIndex::index` to `build_index` Gary Guo
  2026-06-02 14:17 ` [PATCH v2 2/6] rust: ptr: use `match` instead of `unwrap_or_else` for `build_index` Gary Guo
@ 2026-06-02 14:17 ` Gary Guo
  2026-06-02 14:17 ` [PATCH v2 4/6] rust: dma: update to keyworded index projection syntax Gary Guo
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Gary Guo @ 2026-06-02 14:17 UTC (permalink / raw)
  To: Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron,
	Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
	Danilo Krummrich, Abdiel Janulgue, Daniel Almeida, Robin Murphy,
	Alexandre Courbot, David Airlie, Simona Vetter
  Cc: rust-for-linux, linux-kernel, driver-core, nova-gpu, dri-devel

There have been a few cases where the programmer knows that the indices are
in bounds but the compiler cannot deduce that. This is also
compiler-version-dependent, so using build indexing here can be
problematic. On the other hand, it is also not ideal to use the fallible
variant, as it adds an error handling path that is never hit.

Add a new panicking index projection for this scenario. Like all panicking
operations, this should be used carefully only in cases where the user
knows the index is going to be in bounds, and panicking would indicate
something is catastrophically wrong.

To signify this, require users to explicitly denote the type of index being
used. The existing two types of index projections also gain the keyworded
version, which will be the recommended way going forward.

The keyworded syntax also paves the way of perhaps adding more flavors in
the future, e.g. `unsafe` index projection. However, unless the code is
extremely performance sensitive and bounds checking cannot be tolerated,
the panicking variant is safer and should be preferred, so it will be left
to the future when demand arises.

Signed-off-by: Gary Guo <gary@garyguo.net>
---
 rust/kernel/dma.rs            |  3 ++
 rust/kernel/ptr/projection.rs | 96 ++++++++++++++++++++++++++++++++++++-------
 2 files changed, 84 insertions(+), 15 deletions(-)

diff --git a/rust/kernel/dma.rs b/rust/kernel/dma.rs
index 8f97916e0688..ff69739eae35 100644
--- a/rust/kernel/dma.rs
+++ b/rust/kernel/dma.rs
@@ -1207,6 +1207,9 @@ macro_rules! dma_write {
     (@parse [$dma:expr] [$($proj:tt)*] [.$field:tt $($rest:tt)*]) => {
         $crate::dma_write!(@parse [$dma] [$($proj)* .$field] [$($rest)*])
     };
+    (@parse [$dma:expr] [$($proj:tt)*] [[$flavor:ident: $index:expr] $($rest:tt)*]) => {
+        $crate::dma_write!(@parse [$dma] [$($proj)* [$flavor: $index]] [$($rest)*])
+    };
     (@parse [$dma:expr] [$($proj:tt)*] [[$index:expr]? $($rest:tt)*]) => {
         $crate::dma_write!(@parse [$dma] [$($proj)* [$index]?] [$($rest)*])
     };
diff --git a/rust/kernel/ptr/projection.rs b/rust/kernel/ptr/projection.rs
index 1b54616c6cbb..e46877a208d9 100644
--- a/rust/kernel/ptr/projection.rs
+++ b/rust/kernel/ptr/projection.rs
@@ -26,14 +26,14 @@ fn from(_: OutOfBound) -> Self {
 ///
 /// # Safety
 ///
-/// For given input pointer `slice` and return value `output`, the implementation of `build_index`
-/// and `get` (if [`Some`] is returned) must ensure that:
+/// For given input pointer `slice` and return value `output`, the implementation of `index`,
+/// `build_index` and `get` (if [`Some`] is returned) must ensure that:
 /// - `output` has the same provenance as `slice`;
 /// - `output.byte_offset_from(slice)` is between 0 to
 ///   `KnownSize::size(slice) - KnownSize::size(output)`.
 ///
-/// This means that if the input pointer is valid, then pointer returned by `get` or `build_index`
-/// is also valid.
+/// This means that if the input pointer is valid, then pointer returned by `get`, `index` or
+/// `build_index` is also valid.
 #[diagnostic::on_unimplemented(message = "`{Self}` cannot be used to index `{T}`")]
 #[doc(hidden)]
 pub unsafe trait ProjectIndex<T: ?Sized>: Sized {
@@ -42,6 +42,9 @@ pub unsafe trait ProjectIndex<T: ?Sized>: Sized {
     /// Returns an index-projected pointer, if in bounds.
     fn get(self, slice: *mut T) -> Option<*mut Self::Output>;
 
+    /// Returns an index-projected pointer; panic if out of bounds.
+    fn index(self, slice: *mut T) -> *mut Self::Output;
+
     /// Returns an index-projected pointer; fail the build if it cannot be proved to be in bounds.
     #[inline(always)]
     fn build_index(self, slice: *mut T) -> *mut Self::Output {
@@ -66,6 +69,11 @@ fn build_index(self, slice: *mut T) -> *mut Self::Output {
         <I as ProjectIndex<[T]>>::get(self, slice)
     }
 
+    #[inline(always)]
+    fn index(self, slice: *mut [T; N]) -> *mut Self::Output {
+        <I as ProjectIndex<[T]>>::index(self, slice)
+    }
+
     #[inline(always)]
     fn build_index(self, slice: *mut [T; N]) -> *mut Self::Output {
         <I as ProjectIndex<[T]>>::build_index(self, slice)
@@ -85,6 +93,16 @@ fn get(self, slice: *mut [T]) -> Option<*mut T> {
             Some(slice.cast::<T>().wrapping_add(self))
         }
     }
+
+    #[inline(always)]
+    fn index(self, slice: *mut [T]) -> *mut T {
+        // Leverage Rust built-in operators for bounds checking.
+        // SAFETY: All non-null and aligned pointers are valid for ZST read.
+        let zst_slice =
+            unsafe { core::slice::from_raw_parts::<()>(core::ptr::dangling(), slice.len()) };
+        let () = zst_slice[self];
+        slice.cast::<T>().wrapping_add(self)
+    }
 }
 
 // SAFETY: `get`-returned pointer has the same provenance as `slice` and the offset is checked to
@@ -103,6 +121,18 @@ fn get(self, slice: *mut [T]) -> Option<*mut [T]> {
             new_len,
         ))
     }
+
+    #[inline(always)]
+    fn index(self, slice: *mut [T]) -> *mut [T] {
+        // Leverage Rust built-in operators for bounds checking.
+        // SAFETY: All non-null and aligned pointers are valid for ZST read.
+        let zst_slice =
+            unsafe { core::slice::from_raw_parts::<()>(core::ptr::dangling(), slice.len()) };
+        _ = zst_slice[self.clone()];
+
+        // SAFETY: bounds checked.
+        unsafe { self.get(slice).unwrap_unchecked() }
+    }
 }
 
 // SAFETY: Safety requirement guaranteed by the forwarded impl.
@@ -113,6 +143,11 @@ unsafe impl<T> ProjectIndex<[T]> for core::ops::RangeTo<usize> {
     fn get(self, slice: *mut [T]) -> Option<*mut [T]> {
         (0..self.end).get(slice)
     }
+
+    #[inline(always)]
+    fn index(self, slice: *mut [T]) -> *mut [T] {
+        (0..self.end).index(slice)
+    }
 }
 
 // SAFETY: Safety requirement guaranteed by the forwarded impl.
@@ -123,6 +158,11 @@ unsafe impl<T> ProjectIndex<[T]> for core::ops::RangeFrom<usize> {
     fn get(self, slice: *mut [T]) -> Option<*mut [T]> {
         (self.start..slice.len()).get(slice)
     }
+
+    #[inline(always)]
+    fn index(self, slice: *mut [T]) -> *mut [T] {
+        (self.start..slice.len()).index(slice)
+    }
 }
 
 // SAFETY: `get` returned the pointer as is, so it always has the same provenance and offset of 0.
@@ -133,6 +173,11 @@ unsafe impl<T> ProjectIndex<[T]> for core::ops::RangeFull {
     fn get(self, slice: *mut [T]) -> Option<*mut [T]> {
         Some(slice)
     }
+
+    #[inline(always)]
+    fn index(self, slice: *mut [T]) -> *mut [T] {
+        slice
+    }
 }
 
 /// A helper trait to perform field projection.
@@ -211,9 +256,12 @@ unsafe fn proj<F>(_: *mut Self, _: impl FnOnce(*mut Self) -> *mut F) -> *mut F {
 /// `kernel::ptr::project!(mut ptr, projection)`. By default, a const pointer is created.
 ///
 /// `ptr::project!` macro can perform both fallible indexing and build-time checked indexing.
-/// `[index]` form performs build-time bounds checking; if compiler fails to prove `[index]` is in
-/// bounds, compilation will fail. `[index]?` can be used to perform runtime bounds checking;
-/// `OutOfBound` error is raised via `?` if the index is out of bounds.
+/// The syntax is of form `[<flavor>: index]` where `flavor` indicates the way of handling index
+/// out-of-bound errors.
+/// - `try` will raise an `OutOfBound` error (which is convertible to `ERANGE`).
+/// - `build` will use [`build_assert!`](kernel::build_assert::build_assert) mechanism to have
+///   compiler validate the index is in bounds.
+/// - `panic` will cause a Rust [`panic!`] if index goes out of bound.
 ///
 /// # Examples
 ///
@@ -231,17 +279,21 @@ unsafe fn proj<F>(_: *mut Self, _: impl FnOnce(*mut Self) -> *mut F) -> *mut F {
 /// }
 /// ```
 ///
-/// Index projections are performed with `[index]`:
+/// Index projections are performed with `[<flavor>: index]`, where `flavor` is `try`, `build` or
+/// `panic`:
 ///
 /// ```
 /// fn proj(ptr: *const [u8; 32]) -> Result {
-///     let field_ptr: *const u8 = kernel::ptr::project!(ptr, [1]);
+///     let field_ptr: *const u8 = kernel::ptr::project!(ptr, [build: 1]);
 ///     // The following invocation, if uncommented, would fail the build.
 ///     //
-///     // kernel::ptr::project!(ptr, [128]);
+///     // kernel::ptr::project!(ptr, [build: 128]);
 ///
 ///     // This will raise an `OutOfBound` error (which is convertible to `ERANGE`).
-///     kernel::ptr::project!(ptr, [128]?);
+///     kernel::ptr::project!(ptr, [try: 128]);
+///
+///     // This will panic in runtime if executed.
+///     kernel::ptr::project!(ptr, [panic: 128]);
 ///     Ok(())
 /// }
 /// ```
@@ -251,7 +303,7 @@ unsafe fn proj<F>(_: *mut Self, _: impl FnOnce(*mut Self) -> *mut F) -> *mut F {
 /// ```
 /// let ptr: *const [u8; 32] = core::ptr::dangling();
 /// let field_ptr: Result<*const u8> = (|| -> Result<_> {
-///     Ok(kernel::ptr::project!(ptr, [128]?))
+///     Ok(kernel::ptr::project!(ptr, [try: 128]))
 /// })();
 /// assert!(field_ptr.is_err());
 /// ```
@@ -260,7 +312,7 @@ unsafe fn proj<F>(_: *mut Self, _: impl FnOnce(*mut Self) -> *mut F) -> *mut F {
 ///
 /// ```
 /// let ptr: *mut [(u8, u16); 32] = core::ptr::dangling_mut();
-/// let field_ptr: *mut u16 = kernel::ptr::project!(mut ptr, [1].1);
+/// let field_ptr: *mut u16 = kernel::ptr::project!(mut ptr, [build: 1].1);
 /// ```
 #[macro_export]
 macro_rules! project_pointer {
@@ -283,16 +335,30 @@ macro_rules! project_pointer {
         $crate::ptr::project!(@gen $ptr, $($rest)*)
     };
     // Fallible index projection.
-    (@gen $ptr:ident, [$index:expr]? $($rest:tt)*) => {
+    (@gen $ptr:ident, [try: $index:expr] $($rest:tt)*) => {
         let $ptr = $crate::ptr::projection::ProjectIndex::get($index, $ptr)
             .ok_or($crate::ptr::projection::OutOfBound)?;
         $crate::ptr::project!(@gen $ptr, $($rest)*)
     };
+    // Panicking index projection.
+    (@gen $ptr:ident, [panic: $index:expr] $($rest:tt)*) => {
+        let $ptr = $crate::ptr::projection::ProjectIndex::index($index, $ptr);
+        $crate::ptr::project!(@gen $ptr, $($rest)*)
+    };
     // Build-time checked index projection.
-    (@gen $ptr:ident, [$index:expr] $($rest:tt)*) => {
+    (@gen $ptr:ident, [build: $index:expr] $($rest:tt)*) => {
         let $ptr = $crate::ptr::projection::ProjectIndex::build_index($index, $ptr);
         $crate::ptr::project!(@gen $ptr, $($rest)*)
     };
+
+    // For compatibility
+    (@gen $ptr:ident, [$index:expr]? $($rest:tt)*) => {
+        $crate::ptr::project!(@gen $ptr, [try: $index] $($rest)*)
+    };
+    (@gen $ptr:ident, [$index:expr] $($rest:tt)*) => {
+        $crate::ptr::project!(@gen $ptr, [build: $index] $($rest)*)
+    };
+
     (mut $ptr:expr, $($proj:tt)*) => {{
         let ptr: *mut _ = $ptr;
         $crate::ptr::project!(@gen ptr, $($proj)*);

-- 
2.54.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v2 4/6] rust: dma: update to keyworded index projection syntax
  2026-06-02 14:17 [PATCH v2 0/6] Rework index projection syntax Gary Guo
                   ` (2 preceding siblings ...)
  2026-06-02 14:17 ` [PATCH v2 3/6] rust: ptr: add panicking index projection variant Gary Guo
@ 2026-06-02 14:17 ` Gary Guo
  2026-06-02 14:17 ` [PATCH v2 5/6] gpu: nova-core: convert to keyworded " Gary Guo
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 8+ messages in thread
From: Gary Guo @ 2026-06-02 14:17 UTC (permalink / raw)
  To: Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron,
	Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
	Danilo Krummrich, Abdiel Janulgue, Daniel Almeida, Robin Murphy,
	Alexandre Courbot, David Airlie, Simona Vetter
  Cc: rust-for-linux, linux-kernel, driver-core, nova-gpu, dri-devel

Demonstrate the preferred syntax of index projection in DMA documentation
and examples. A few `[i]?` cases are converted to demonstrate the new
variant.

Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Reviewed-by: Andreas Hindborg <a.hindborg@kernel.org>
Reviewed-by: Alexandre Courbot <acourbot@nvidia.com>
Signed-off-by: Gary Guo <gary@garyguo.net>
---
 rust/kernel/dma.rs       |  8 ++++----
 samples/rust/rust_dma.rs | 12 +++++-------
 2 files changed, 9 insertions(+), 11 deletions(-)

diff --git a/rust/kernel/dma.rs b/rust/kernel/dma.rs
index ff69739eae35..79125ee012a9 100644
--- a/rust/kernel/dma.rs
+++ b/rust/kernel/dma.rs
@@ -1152,8 +1152,8 @@ unsafe impl Sync for CoherentHandle {}
 /// unsafe impl kernel::transmute::AsBytes for MyStruct{};
 ///
 /// # fn test(alloc: &kernel::dma::Coherent<[MyStruct]>) -> Result {
-/// let whole = kernel::dma_read!(alloc, [2]?);
-/// let field = kernel::dma_read!(alloc, [1]?.field);
+/// let whole = kernel::dma_read!(alloc, [try: 2]);
+/// let field = kernel::dma_read!(alloc, [panic: 1].field);
 /// # Ok::<(), Error>(()) }
 /// ```
 #[macro_export]
@@ -1189,8 +1189,8 @@ macro_rules! dma_read {
 /// unsafe impl kernel::transmute::AsBytes for MyStruct{};
 ///
 /// # fn test(alloc: &kernel::dma::Coherent<[MyStruct]>) -> Result {
-/// kernel::dma_write!(alloc, [2]?.member, 0xf);
-/// kernel::dma_write!(alloc, [1]?, MyStruct { member: 0xf });
+/// kernel::dma_write!(alloc, [try: 2].member, 0xf);
+/// kernel::dma_write!(alloc, [panic: 1], MyStruct { member: 0xf });
 /// # Ok::<(), Error>(()) }
 /// ```
 #[macro_export]
diff --git a/samples/rust/rust_dma.rs b/samples/rust/rust_dma.rs
index c4d2d36602af..5046b4628d0e 100644
--- a/samples/rust/rust_dma.rs
+++ b/samples/rust/rust_dma.rs
@@ -77,7 +77,7 @@ fn probe<'bound>(
                 Coherent::zeroed_slice(pdev.as_ref(), TEST_VALUES.len(), GFP_KERNEL)?;
 
             for (i, value) in TEST_VALUES.into_iter().enumerate() {
-                kernel::dma_write!(ca, [i]?, MyStruct::new(value.0, value.1));
+                kernel::dma_write!(ca, [try: i], MyStruct::new(value.0, value.1));
             }
 
             let size = 4 * page::PAGE_SIZE;
@@ -95,16 +95,14 @@ fn probe<'bound>(
 }
 
 impl DmaSampleDriver {
-    fn check_dma(&self) -> Result {
+    fn check_dma(&self) {
         for (i, value) in TEST_VALUES.into_iter().enumerate() {
-            let val0 = kernel::dma_read!(self.ca, [i]?.h);
-            let val1 = kernel::dma_read!(self.ca, [i]?.b);
+            let val0 = kernel::dma_read!(self.ca, [panic: i].h);
+            let val1 = kernel::dma_read!(self.ca, [panic: i].b);
 
             assert_eq!(val0, value.0);
             assert_eq!(val1, value.1);
         }
-
-        Ok(())
     }
 }
 
@@ -113,7 +111,7 @@ impl PinnedDrop for DmaSampleDriver {
     fn drop(self: Pin<&mut Self>) {
         dev_info!(self.pdev, "Unload DMA test driver.\n");
 
-        assert!(self.check_dma().is_ok());
+        self.check_dma();
 
         for (i, entry) in self.sgt.iter().enumerate() {
             dev_info!(

-- 
2.54.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v2 5/6] gpu: nova-core: convert to keyworded projection syntax
  2026-06-02 14:17 [PATCH v2 0/6] Rework index projection syntax Gary Guo
                   ` (3 preceding siblings ...)
  2026-06-02 14:17 ` [PATCH v2 4/6] rust: dma: update to keyworded index projection syntax Gary Guo
@ 2026-06-02 14:17 ` Gary Guo
  2026-06-02 14:17 ` [PATCH v2 6/6] rust: ptr: remove implicit index " Gary Guo
  2026-06-02 15:03 ` [PATCH v2 0/6] Rework " Danilo Krummrich
  6 siblings, 0 replies; 8+ messages in thread
From: Gary Guo @ 2026-06-02 14:17 UTC (permalink / raw)
  To: Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron,
	Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
	Danilo Krummrich, Abdiel Janulgue, Daniel Almeida, Robin Murphy,
	Alexandre Courbot, David Airlie, Simona Vetter
  Cc: rust-for-linux, linux-kernel, driver-core, nova-gpu, dri-devel

Use "build" to denote that the index bounds checking here is performed at
build time.

Reviewed-by: Alexandre Courbot <acourbot@nvidia.com>
Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Signed-off-by: Gary Guo <gary@garyguo.net>
---
 drivers/gpu/nova-core/gsp/cmdq.rs | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/nova-core/gsp/cmdq.rs b/drivers/gpu/nova-core/gsp/cmdq.rs
index 275da9b1ee0e..1c9b2085f5e4 100644
--- a/drivers/gpu/nova-core/gsp/cmdq.rs
+++ b/drivers/gpu/nova-core/gsp/cmdq.rs
@@ -237,7 +237,7 @@ fn new(dev: &device::Device<device::Bound>) -> Result<Self> {
         let start = gsp_mem.dma_handle();
         // Write values one by one to avoid an on-stack instance of `PteArray`.
         for i in 0..GspMem::PTE_ARRAY_SIZE {
-            dma_write!(gsp_mem, .ptes.0[i], PteArray::<0>::entry(start, i)?);
+            dma_write!(gsp_mem, .ptes.0[build: i], PteArray::<0>::entry(start, i)?);
         }
 
         dma_write!(
@@ -260,7 +260,7 @@ fn new(dev: &device::Device<device::Bound>) -> Result<Self> {
         let rx = self.gsp_read_ptr();
 
         // Pointer to the first entry of the CPU message queue.
-        let data = ptr::project!(mut self.0.as_mut_ptr(), .cpuq.msgq.data[0]);
+        let data = ptr::project!(mut self.0.as_mut_ptr(), .cpuq.msgq.data[build: 0]);
 
         let (tail_end, wrap_end) = if rx == 0 {
             // The write area is non-wrapping, and stops at the second-to-last entry of the command
@@ -322,7 +322,7 @@ fn driver_write_area_size(&self) -> usize {
         let rx = self.cpu_read_ptr();
 
         // Pointer to the first entry of the GSP message queue.
-        let data = ptr::project!(self.0.as_ptr(), .gspq.msgq.data[0]);
+        let data = ptr::project!(self.0.as_ptr(), .gspq.msgq.data[build: 0]);
 
         let (tail_end, wrap_end) = if rx <= tx {
             // Read area is non-wrapping and stops right before `tx`.

-- 
2.54.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH v2 6/6] rust: ptr: remove implicit index projection syntax
  2026-06-02 14:17 [PATCH v2 0/6] Rework index projection syntax Gary Guo
                   ` (4 preceding siblings ...)
  2026-06-02 14:17 ` [PATCH v2 5/6] gpu: nova-core: convert to keyworded " Gary Guo
@ 2026-06-02 14:17 ` Gary Guo
  2026-06-02 15:03 ` [PATCH v2 0/6] Rework " Danilo Krummrich
  6 siblings, 0 replies; 8+ messages in thread
From: Gary Guo @ 2026-06-02 14:17 UTC (permalink / raw)
  To: Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron,
	Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
	Danilo Krummrich, Abdiel Janulgue, Daniel Almeida, Robin Murphy,
	Alexandre Courbot, David Airlie, Simona Vetter
  Cc: rust-for-linux, linux-kernel, driver-core, nova-gpu, dri-devel

All users have been converted to use keyworded index projection syntax to
explicitly state their intention when doing index projection.

Reviewed-by: Alexandre Courbot <acourbot@nvidia.com>
Reviewed-by: Andreas Hindborg <a.hindborg@kernel.org>
Reviewed-by: Alice Ryhl <aliceryhl@google.com>
Signed-off-by: Gary Guo <gary@garyguo.net>
---
 rust/kernel/dma.rs            | 6 ------
 rust/kernel/ptr/projection.rs | 8 --------
 2 files changed, 14 deletions(-)

diff --git a/rust/kernel/dma.rs b/rust/kernel/dma.rs
index 79125ee012a9..200def84fb69 100644
--- a/rust/kernel/dma.rs
+++ b/rust/kernel/dma.rs
@@ -1210,12 +1210,6 @@ macro_rules! dma_write {
     (@parse [$dma:expr] [$($proj:tt)*] [[$flavor:ident: $index:expr] $($rest:tt)*]) => {
         $crate::dma_write!(@parse [$dma] [$($proj)* [$flavor: $index]] [$($rest)*])
     };
-    (@parse [$dma:expr] [$($proj:tt)*] [[$index:expr]? $($rest:tt)*]) => {
-        $crate::dma_write!(@parse [$dma] [$($proj)* [$index]?] [$($rest)*])
-    };
-    (@parse [$dma:expr] [$($proj:tt)*] [[$index:expr] $($rest:tt)*]) => {
-        $crate::dma_write!(@parse [$dma] [$($proj)* [$index]] [$($rest)*])
-    };
     ($dma:expr, $($rest:tt)*) => {
         $crate::dma_write!(@parse [$dma] [] [$($rest)*])
     };
diff --git a/rust/kernel/ptr/projection.rs b/rust/kernel/ptr/projection.rs
index e46877a208d9..c6e9dfbc4f9a 100644
--- a/rust/kernel/ptr/projection.rs
+++ b/rust/kernel/ptr/projection.rs
@@ -351,14 +351,6 @@ macro_rules! project_pointer {
         $crate::ptr::project!(@gen $ptr, $($rest)*)
     };
 
-    // For compatibility
-    (@gen $ptr:ident, [$index:expr]? $($rest:tt)*) => {
-        $crate::ptr::project!(@gen $ptr, [try: $index] $($rest)*)
-    };
-    (@gen $ptr:ident, [$index:expr] $($rest:tt)*) => {
-        $crate::ptr::project!(@gen $ptr, [build: $index] $($rest)*)
-    };
-
     (mut $ptr:expr, $($proj:tt)*) => {{
         let ptr: *mut _ = $ptr;
         $crate::ptr::project!(@gen ptr, $($proj)*);

-- 
2.54.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH v2 0/6] Rework index projection syntax
  2026-06-02 14:17 [PATCH v2 0/6] Rework index projection syntax Gary Guo
                   ` (5 preceding siblings ...)
  2026-06-02 14:17 ` [PATCH v2 6/6] rust: ptr: remove implicit index " Gary Guo
@ 2026-06-02 15:03 ` Danilo Krummrich
  6 siblings, 0 replies; 8+ messages in thread
From: Danilo Krummrich @ 2026-06-02 15:03 UTC (permalink / raw)
  To: Gary Guo
  Cc: Miguel Ojeda, Boqun Feng, Björn Roy Baron, Benno Lossin,
	Andreas Hindborg, Alice Ryhl, Trevor Gross, Abdiel Janulgue,
	Daniel Almeida, Robin Murphy, Alexandre Courbot, David Airlie,
	Simona Vetter, rust-for-linux, linux-kernel, driver-core,
	nova-gpu, dri-devel

On Tue Jun 2, 2026 at 4:17 PM CEST, Gary Guo wrote:
> Danilo, we previously discussed merging this series with I/O projection for
> patch logistics. However, I'll need more time for next version of I/O
> projection (implementing view types that have original container type
> erased) which won't make it this cycle. This new version for projection
> syntax rework is minor changes only comparde to v1, so I think it's worth
> sending out so it can still land this cycle and get out of the way.

[...]

> base-commit: 46def663dd34da36464ba059f7cfeacf29d98e5e

Agreed, as discussed; and in this case I think this can go through rust-next.

Acked-by: Danilo Krummrich <dakr@kernel.org>

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2026-06-02 15:03 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-02 14:17 [PATCH v2 0/6] Rework index projection syntax Gary Guo
2026-06-02 14:17 ` [PATCH v2 1/6] rust: ptr: rename `ProjectIndex::index` to `build_index` Gary Guo
2026-06-02 14:17 ` [PATCH v2 2/6] rust: ptr: use `match` instead of `unwrap_or_else` for `build_index` Gary Guo
2026-06-02 14:17 ` [PATCH v2 3/6] rust: ptr: add panicking index projection variant Gary Guo
2026-06-02 14:17 ` [PATCH v2 4/6] rust: dma: update to keyworded index projection syntax Gary Guo
2026-06-02 14:17 ` [PATCH v2 5/6] gpu: nova-core: convert to keyworded " Gary Guo
2026-06-02 14:17 ` [PATCH v2 6/6] rust: ptr: remove implicit index " Gary Guo
2026-06-02 15:03 ` [PATCH v2 0/6] Rework " Danilo Krummrich

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox