[PATCH v2 14/31] gpu: nova-core: generalize allocate_command() for variable headers

John Hubbard <[email protected]>
Newsgroups dev.linux.lists.nova-gpu,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
The GMC command path uses a different message element header from the
VGPU-style RPC path, but the two share the queue, the space accounting,
and the wrapping rules. Make allocate_command() and GspCommand generic
over the header type, defaulting to GspMsgElement so the existing RPC
callers are unchanged.

No functional changes.

Assisted-by: Cursor:claude-opus-5
Reviewed-by: Timur Tabi <[email protected]>
Reviewed-by: Zhi Wang <[email protected]>
Signed-off-by: John Hubbard <[email protected]>
---
 drivers/gpu/nova-core/gsp/cmdq.rs | 22 +++++++++++++++-------
 1 file changed, 15 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/nova-core/gsp/cmdq.rs b/drivers/gpu/nova-core/gsp/cmdq.rs
index a46d8927da1b..babec37716b5 100644
--- a/drivers/gpu/nova-core/gsp/cmdq.rs
+++ b/drivers/gpu/nova-core/gsp/cmdq.rs
@@ -365,6 +365,8 @@ fn driver_write_area_size(&self) -> usize {
     /// Allocates a region on the command queue that is large enough to send a command of `size`
     /// bytes, waiting for space to become available based on the provided timeout.
     ///
+    /// The type parameter `H` selects the message element header, [`GspMsgElement`] for RM RPC.
+    ///
     /// This returns a [`GspCommand`] ready to be written to by the caller.
     ///
     /// # Errors
@@ -372,13 +374,17 @@ fn driver_write_area_size(&self) -> usize {
     /// - `EMSGSIZE` if the command is larger than [`GSP_MSG_QUEUE_ELEMENT_SIZE_MAX`].
     /// - `ETIMEDOUT` if space does not become available within the timeout.
     /// - `EIO` if the command header is not properly aligned.
-    fn allocate_command(&mut self, size: usize, timeout: Delta) -> Result<GspCommand<'_>> {
-        if size_of::<GspMsgElement>() + size > GSP_MSG_QUEUE_ELEMENT_SIZE_MAX {
+    fn allocate_command<H: FromBytes + AsBytes>(
+        &mut self,
+        size: usize,
+        timeout: Delta,
+    ) -> Result<GspCommand<'_, H>> {
+        if size_of::<H>() + size > GSP_MSG_QUEUE_ELEMENT_SIZE_MAX {
             return Err(EMSGSIZE);
         }
         read_poll_timeout(
             || Ok(self.driver_write_area_size()),
-            |available_bytes| *available_bytes >= size_of::<GspMsgElement>() + size,
+            |available_bytes| *available_bytes >= size_of::<H>() + size,
             Delta::from_micros(1),
             timeout,
         )?;
@@ -390,8 +396,8 @@ fn allocate_command(&mut self, size: usize, timeout: Delta) -> Result<GspCommand
             (slice_1.as_flattened_mut(), slice_2.as_flattened_mut())
         };
 
-        // Extract area for the `GspMsgElement`.
-        let (header, slice_1) = GspMsgElement::from_bytes_mut_prefix(slice_1).ok_or(EIO)?;
+        // Extract area for the message element header.
+        let (header, slice_1) = H::from_bytes_mut_prefix(slice_1).ok_or(EIO)?;
 
         // Create the contents area.
         let (slice_1, slice_2) = if slice_1.len() > size {
@@ -609,10 +615,12 @@ fn driver_read_area_v2(
 
 /// A command ready to be sent on the command queue.
 ///
+/// The type parameter `H` is the message element header type, [`GspMsgElement`] for RM RPC.
+///
 /// This is the type returned by [`DmaGspMem::allocate_command`].
-struct GspCommand<'a> {
+struct GspCommand<'a, H = GspMsgElement> {
     // Writable reference to the header of the command.
-    header: &'a mut GspMsgElement,
+    header: &'a mut H,
     // Writable slices to the contents of the command. The second slice is zero unless the command
     // loops over the command queue.
     contents: (&'a mut [u8], &'a mut [u8]),
-- 
2.55.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.