[PATCH v2 9/9] gpu: nova-core: gsp: add CeGetFaultMethodBufferSize RM control command

Eliot Courtney posted 9 patches 2 weeks, 5 days ago
There is a newer version of this series
[PATCH v2 9/9] gpu: nova-core: gsp: add CeGetFaultMethodBufferSize RM control command
Posted by Eliot Courtney 2 weeks, 5 days ago
Add `CeGetFaultMethodBufferSizeParams` which wraps the bindings.

Add `get_ce_fault_method_buffer_size` which sends the RM control RPC
and returns the buffer size. This is needed for channel allocation.

Reviewed-by: Joel Fernandes <joelagnelf@nvidia.com>
Signed-off-by: Eliot Courtney <ecourtney@nvidia.com>
---
 drivers/gpu/nova-core/gsp/fw/rm.rs       | 16 +++++++++++++
 drivers/gpu/nova-core/gsp/rm/commands.rs | 39 ++++++++++++++++++++++++++++----
 2 files changed, 50 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/nova-core/gsp/fw/rm.rs b/drivers/gpu/nova-core/gsp/fw/rm.rs
index 1c6e8b4c4865..561f358ec4f1 100644
--- a/drivers/gpu/nova-core/gsp/fw/rm.rs
+++ b/drivers/gpu/nova-core/gsp/fw/rm.rs
@@ -85,3 +85,19 @@ unsafe impl FromBytes for GspRmControl {}
 
 // SAFETY: This struct contains no padding.
 unsafe impl AsBytes for GspRmControl {}
+
+/// Wrapper for [`bindings::NV2080_CTRL_CE_GET_FAULT_METHOD_BUFFER_SIZE_PARAMS`].
+#[repr(transparent)]
+pub(crate) struct CeGetFaultMethodBufferSizeParams(
+    bindings::NV2080_CTRL_CE_GET_FAULT_METHOD_BUFFER_SIZE_PARAMS,
+);
+
+impl CeGetFaultMethodBufferSizeParams {
+    /// Returns the CE fault method buffer size in bytes.
+    pub(crate) fn size(&self) -> u32 {
+        self.0.size
+    }
+}
+
+// SAFETY: This struct only contains integer types for which all bit patterns are valid.
+unsafe impl FromBytes for CeGetFaultMethodBufferSizeParams {}
diff --git a/drivers/gpu/nova-core/gsp/rm/commands.rs b/drivers/gpu/nova-core/gsp/rm/commands.rs
index 5a3ac7bd415a..05a8cfae385c 100644
--- a/drivers/gpu/nova-core/gsp/rm/commands.rs
+++ b/drivers/gpu/nova-core/gsp/rm/commands.rs
@@ -2,10 +2,14 @@
 
 use core::{
     array,
-    convert::Infallible, //
+    convert::Infallible,
+    mem::size_of, //
 };
 
-use kernel::prelude::*;
+use kernel::{
+    prelude::*,
+    transmute::FromBytes, //
+};
 
 use crate::{
     driver::Bar0,
@@ -17,7 +21,8 @@
         },
         commands::{
             Client,
-            Handle, //
+            Handle,
+            Subdevice, //
         },
         fw::{
             rm::*,
@@ -47,7 +52,6 @@ struct RmControl<'a, T> {
 
 impl<'a, T> RmControl<'a, T> {
     /// Creates a new RM control command.
-    #[expect(dead_code)]
     fn new(
         client: Handle<Client>,
         object: Handle<T>,
@@ -108,7 +112,6 @@ fn read(
 }
 
 /// Sends an RM control command, checks the reply status, and returns the raw parameter bytes.
-#[expect(dead_code)]
 fn send_rm_control<T>(cmdq: &Cmdq, bar: &Bar0, cmd: RmControl<'_, T>) -> Result<KVVec<u8>> {
     let reply = cmdq.send_command(bar, cmd)?;
 
@@ -116,3 +119,29 @@ fn send_rm_control<T>(cmdq: &Cmdq, bar: &Bar0, cmd: RmControl<'_, T>) -> Result<
 
     Ok(reply.params)
 }
+
+/// Sends the `CeGetFaultMethodBufferSize` RM control command and waits for its reply.
+///
+/// Returns the CE fault method buffer size in bytes.
+#[expect(dead_code)]
+pub(crate) fn get_ce_fault_method_buffer_size(
+    cmdq: &Cmdq,
+    bar: &Bar0,
+    client: Handle<Client>,
+    subdevice: Handle<Subdevice>,
+) -> Result<u32> {
+    // Stack-allocate the request; CeGetFaultMethodBufferSizeParams is small (4 bytes).
+    let req = [0u8; size_of::<CeGetFaultMethodBufferSizeParams>()];
+
+    let cmd = RmControl::new(
+        client,
+        subdevice,
+        RmControlMsgFunction::CeGetFaultMethodBufferSize,
+        &req,
+    );
+    let reply = send_rm_control(cmdq, bar, cmd)?;
+
+    let params = CeGetFaultMethodBufferSizeParams::from_bytes(&reply).ok_or(EINVAL)?;
+
+    Ok(params.size())
+}

-- 
2.53.0
Re: [PATCH v2 9/9] gpu: nova-core: gsp: add CeGetFaultMethodBufferSize RM control command
Posted by Danilo Krummrich 2 weeks, 3 days ago
On Wed Mar 18, 2026 at 8:14 AM CET, Eliot Courtney wrote:
> +/// Sends the `CeGetFaultMethodBufferSize` RM control command and waits for its reply.
> +///
> +/// Returns the CE fault method buffer size in bytes.
> +#[expect(dead_code)]
> +pub(crate) fn get_ce_fault_method_buffer_size(
> +    cmdq: &Cmdq,
> +    bar: &Bar0,
> +    client: Handle<Client>,
> +    subdevice: Handle<Subdevice>,
> +) -> Result<u32> {
> +    // Stack-allocate the request; CeGetFaultMethodBufferSizeParams is small (4 bytes).
> +    let req = [0u8; size_of::<CeGetFaultMethodBufferSizeParams>()];
> +
> +    let cmd = RmControl::new(
> +        client,
> +        subdevice,
> +        RmControlMsgFunction::CeGetFaultMethodBufferSize,
> +        &req,
> +    );
> +    let reply = send_rm_control(cmdq, bar, cmd)?;
> +
> +    let params = CeGetFaultMethodBufferSizeParams::from_bytes(&reply).ok_or(EINVAL)?;
> +
> +    Ok(params.size())
> +}

This is similar to send_rm_control(), I think RmControl should be generic over
the control message type, so you could just write something along the lines of:

	RmControl::<CeGetFaultMethodBufferSize>::new(...).send();

Admittedly, CeGetFaultMethodBufferSize is a bit long, but that's GSP naming and
get_ce_fault_method_buffer_size() isn't shorter anyway.

(Btw. please try to avoid building functions named get_*() or *_get(), though
I'm aware that it is part of the struct name in this case. Yet another reason
not to solve this with a helper function. :)

Alternatively, you could also consider a builder pattern approach.
Re: [PATCH v2 9/9] gpu: nova-core: gsp: add CeGetFaultMethodBufferSize RM control command
Posted by Eliot Courtney 1 week, 5 days ago
On Fri Mar 20, 2026 at 10:27 PM JST, Danilo Krummrich wrote:
> On Wed Mar 18, 2026 at 8:14 AM CET, Eliot Courtney wrote:
>> +/// Sends the `CeGetFaultMethodBufferSize` RM control command and waits for its reply.
>> +///
>> +/// Returns the CE fault method buffer size in bytes.
>> +#[expect(dead_code)]
>> +pub(crate) fn get_ce_fault_method_buffer_size(
>> +    cmdq: &Cmdq,
>> +    bar: &Bar0,
>> +    client: Handle<Client>,
>> +    subdevice: Handle<Subdevice>,
>> +) -> Result<u32> {
>> +    // Stack-allocate the request; CeGetFaultMethodBufferSizeParams is small (4 bytes).
>> +    let req = [0u8; size_of::<CeGetFaultMethodBufferSizeParams>()];
>> +
>> +    let cmd = RmControl::new(
>> +        client,
>> +        subdevice,
>> +        RmControlMsgFunction::CeGetFaultMethodBufferSize,
>> +        &req,
>> +    );
>> +    let reply = send_rm_control(cmdq, bar, cmd)?;
>> +
>> +    let params = CeGetFaultMethodBufferSizeParams::from_bytes(&reply).ok_or(EINVAL)?;
>> +
>> +    Ok(params.size())
>> +}
>
> This is similar to send_rm_control(), I think RmControl should be generic over
> the control message type, so you could just write something along the lines of:
>
> 	RmControl::<CeGetFaultMethodBufferSize>::new(...).send();
>
> Admittedly, CeGetFaultMethodBufferSize is a bit long, but that's GSP naming and
> get_ce_fault_method_buffer_size() isn't shorter anyway.
>
> (Btw. please try to avoid building functions named get_*() or *_get(), though
> I'm aware that it is part of the struct name in this case. Yet another reason
> not to solve this with a helper function. :)
>
> Alternatively, you could also consider a builder pattern approach.

I agree with this, and after thinking about it I also think we should
get rid of the other helper type methods like `get_gsp_info`. I was
trying to make this consistent with the existing way it's done (the
helper methods) but it does look increasingly bad.