[PATCH v5 11/14] gpu: nova-core: gsp: cmdq: use consume_element to implement drain
From: Alexandre Courbot
Date: Tue Oct 20 2026 - 06:12:31 EST
`consume_element` can be used to factor out the code of `drain` that
advanced the read pointer.
No functional change intended.
Signed-off-by: Alexandre Courbot <acourbot@xxxxxxxxxx>
---
drivers/gpu/nova-core/gsp/cmdq.rs | 32 +++++++++++++++++---------------
1 file changed, 17 insertions(+), 15 deletions(-)
diff --git a/drivers/gpu/nova-core/gsp/cmdq.rs b/drivers/gpu/nova-core/gsp/cmdq.rs
index 7db3d28e8902..54e87fd7158c 100644
--- a/drivers/gpu/nova-core/gsp/cmdq.rs
+++ b/drivers/gpu/nova-core/gsp/cmdq.rs
@@ -651,6 +651,15 @@ enum GspParsedMessage<'a> {
Rpc(RpcMessage<'a>),
}
+impl GspParsedMessage<'_> {
+ /// Log the message on `dev`.
+ fn log(&self, dev: &device::Device) {
+ match self {
+ GspParsedMessage::Rpc(rpc) => rpc.log(dev),
+ }
+ }
+}
+
/// GSP command queue.
///
/// Provides the ability to send commands and receive messages from the GSP using a shared memory
@@ -1054,21 +1063,14 @@ fn await_msg<M: MessageFromGsp>(&mut self) -> Result<M>
/// `EIO` if a message fails framing or checksum validation, or if a message's page count
/// overflows a `u32`.
fn drain(&mut self) -> Result {
- while !self.gsp_mem.driver_read_area().0.is_empty() {
- // A message is available, so this returns without waiting.
- let msg = self.wait_for_msg(Delta::ZERO)?;
-
- let pages =
- u32::try_from(msg.header.msg_length().div_ceil(GSP_PAGE_SIZE)).map_err(|_| {
- dev_err!(&self.dev, "GSP drain: message length overflow\n");
- EIO
- })?;
-
- RpcMessage::parse(self.dev, msg)?.log(self.dev);
-
- self.gsp_mem.advance_cpu_read_ptr(pages);
+ loop {
+ match self.consume_element(Delta::ZERO, |message| message.log(self.dev)) {
+ Ok(()) => (),
+ // No more message pending on the queue, drain is complete.
+ Err(ETIMEDOUT) => return Ok(()),
+ // Other errors are fatal, and stall the queue.
+ Err(e) => return Err(e),
+ }
}
-
- Ok(())
}
}
--
2.56.0