[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20260130-coherent-array-v1-9-bcd672dacc70@nvidia.com>
Date: Fri, 30 Jan 2026 17:34:12 +0900
From: Eliot Courtney <ecourtney@...dia.com>
To: Danilo Krummrich <dakr@...nel.org>,
Alexandre Courbot <acourbot@...dia.com>, Alice Ryhl <aliceryhl@...gle.com>,
David Airlie <airlied@...il.com>, Simona Vetter <simona@...ll.ch>,
Abdiel Janulgue <abdiel.janulgue@...il.com>,
Daniel Almeida <daniel.almeida@...labora.com>,
Robin Murphy <robin.murphy@....com>,
Andreas Hindborg <a.hindborg@...nel.org>, Miguel Ojeda <ojeda@...nel.org>,
Boqun Feng <boqun.feng@...il.com>, Gary Guo <gary@...yguo.net>,
Björn Roy Baron <bjorn3_gh@...tonmail.com>,
Benno Lossin <lossin@...nel.org>, Trevor Gross <tmgross@...ch.edu>
Cc: nouveau@...ts.freedesktop.org, dri-devel@...ts.freedesktop.org,
linux-kernel@...r.kernel.org, driver-core@...ts.linux.dev,
rust-for-linux@...r.kernel.org, Eliot Courtney <ecourtney@...dia.com>
Subject: [PATCH 9/9] gpu: nova-core: migrate to CoherentArray and
CoherentObject
Migrate to CoherentArray and CoherentObject. This enables removing
a few unwrap()s.
Signed-off-by: Eliot Courtney <ecourtney@...dia.com>
---
drivers/gpu/nova-core/gsp.rs | 46 ++++++++++++++++++++-------------------
drivers/gpu/nova-core/gsp/boot.rs | 10 ++++-----
drivers/gpu/nova-core/gsp/cmdq.rs | 24 ++++++++++----------
drivers/gpu/nova-core/gsp/fw.rs | 12 +++-------
4 files changed, 43 insertions(+), 49 deletions(-)
diff --git a/drivers/gpu/nova-core/gsp.rs b/drivers/gpu/nova-core/gsp.rs
index 43bc35fd3b55..2513822d43fb 100644
--- a/drivers/gpu/nova-core/gsp.rs
+++ b/drivers/gpu/nova-core/gsp.rs
@@ -5,13 +5,15 @@
use kernel::{
device,
dma::{
- CoherentAllocation,
+ CoherentArray,
+ CoherentObject,
+ CoherentSlice,
DmaAddress, //
},
+ dma_write,
pci,
prelude::*,
- transmute::AsBytes,
- try_dma_write, //
+ transmute::AsBytes, //
};
pub(crate) mod cmdq;
@@ -74,14 +76,14 @@ fn new(start: DmaAddress) -> Result<Self> {
/// then pp points to index into the buffer where the next logging entry will
/// be written. Therefore, the logging data is valid if:
/// 1 <= pp < sizeof(buffer)/sizeof(u64)
-struct LogBuffer(CoherentAllocation<u8>);
+struct LogBuffer(CoherentSlice<u8>);
impl LogBuffer {
/// Creates a new `LogBuffer` mapped on `dev`.
fn new(dev: &device::Device<device::Bound>) -> Result<Self> {
const NUM_PAGES: usize = RM_LOG_BUFFER_NUM_PAGES;
- let mut obj = Self(CoherentAllocation::<u8>::alloc_coherent(
+ let mut obj = Self(CoherentSlice::<u8>::alloc_coherent(
dev,
NUM_PAGES * GSP_PAGE_SIZE,
GFP_KERNEL | __GFP_ZERO,
@@ -100,11 +102,14 @@ fn new(dev: &device::Device<device::Bound>) -> Result<Self> {
}
}
+/// Number of `LibosMemoryRegionInitArgument` entries that fit in a GSP page.
+const LIBOS_REGION_SIZE: usize = GSP_PAGE_SIZE / size_of::<LibosMemoryRegionInitArgument>();
+
/// GSP runtime data.
#[pin_data]
pub(crate) struct Gsp {
/// Libos arguments.
- pub(crate) libos: CoherentAllocation<LibosMemoryRegionInitArgument>,
+ pub(crate) libos: CoherentArray<LibosMemoryRegionInitArgument, LIBOS_REGION_SIZE>,
/// Init log buffer.
loginit: LogBuffer,
/// Interrupts log buffer.
@@ -114,40 +119,37 @@ pub(crate) struct Gsp {
/// Command queue.
pub(crate) cmdq: Cmdq,
/// RM arguments.
- rmargs: CoherentAllocation<GspArgumentsCached>,
+ rmargs: CoherentObject<GspArgumentsCached>,
}
impl Gsp {
// Creates an in-place initializer for a `Gsp` manager for `pdev`.
pub(crate) fn new(pdev: &pci::Device<device::Bound>) -> Result<impl PinInit<Self, Error>> {
let dev = pdev.as_ref();
- let libos = CoherentAllocation::<LibosMemoryRegionInitArgument>::alloc_coherent(
- dev,
- GSP_PAGE_SIZE / size_of::<LibosMemoryRegionInitArgument>(),
- GFP_KERNEL | __GFP_ZERO,
- )?;
+ let libos =
+ CoherentArray::<LibosMemoryRegionInitArgument, LIBOS_REGION_SIZE>::alloc_coherent(
+ dev,
+ GFP_KERNEL | __GFP_ZERO,
+ )?;
// Initialise the logging structures. The OpenRM equivalents are in:
// _kgspInitLibosLoggingStructures (allocates memory for buffers)
// kgspSetupLibosInitArgs_IMPL (creates pLibosInitArgs[] array)
let loginit = LogBuffer::new(dev)?;
- try_dma_write!(libos[0] = LibosMemoryRegionInitArgument::new("LOGINIT", &loginit.0))?;
+ dma_write!(libos[0] = LibosMemoryRegionInitArgument::new("LOGINIT", &loginit.0));
let logintr = LogBuffer::new(dev)?;
- try_dma_write!(libos[1] = LibosMemoryRegionInitArgument::new("LOGINTR", &logintr.0))?;
+ dma_write!(libos[1] = LibosMemoryRegionInitArgument::new("LOGINTR", &logintr.0));
let logrm = LogBuffer::new(dev)?;
- try_dma_write!(libos[2] = LibosMemoryRegionInitArgument::new("LOGRM", &logrm.0))?;
+ dma_write!(libos[2] = LibosMemoryRegionInitArgument::new("LOGRM", &logrm.0));
let cmdq = Cmdq::new(dev)?;
- let rmargs = CoherentAllocation::<GspArgumentsCached>::alloc_coherent(
- dev,
- 1,
- GFP_KERNEL | __GFP_ZERO,
- )?;
- try_dma_write!(rmargs[0] = fw::GspArgumentsCached::new(&cmdq))?;
- try_dma_write!(libos[3] = LibosMemoryRegionInitArgument::new("RMARGS", &rmargs))?;
+ let rmargs =
+ CoherentObject::<GspArgumentsCached>::alloc_coherent(dev, GFP_KERNEL | __GFP_ZERO)?;
+ dma_write!(rmargs[0] = fw::GspArgumentsCached::new(&cmdq));
+ dma_write!(libos[3] = LibosMemoryRegionInitArgument::new("RMARGS", &rmargs));
Ok(try_pin_init!(Self {
libos,
diff --git a/drivers/gpu/nova-core/gsp/boot.rs b/drivers/gpu/nova-core/gsp/boot.rs
index 69e2fb064220..7888a39356f3 100644
--- a/drivers/gpu/nova-core/gsp/boot.rs
+++ b/drivers/gpu/nova-core/gsp/boot.rs
@@ -2,12 +2,12 @@
use kernel::{
device,
- dma::CoherentAllocation,
+ dma::CoherentObject,
+ dma_write,
io::poll::read_poll_timeout,
pci,
prelude::*,
- time::Delta,
- try_dma_write, //
+ time::Delta, //
};
use crate::{
@@ -159,8 +159,8 @@ pub(crate) fn boot(
)?;
let wpr_meta =
- CoherentAllocation::<GspFwWprMeta>::alloc_coherent(dev, 1, GFP_KERNEL | __GFP_ZERO)?;
- try_dma_write!(wpr_meta[0] = GspFwWprMeta::new(&gsp_fw, &fb_layout))?;
+ CoherentObject::<GspFwWprMeta>::alloc_coherent(dev, GFP_KERNEL | __GFP_ZERO)?;
+ dma_write!(wpr_meta[0] = GspFwWprMeta::new(&gsp_fw, &fb_layout));
self.cmdq
.send_command(bar, commands::SetSystemInfo::new(pdev))?;
diff --git a/drivers/gpu/nova-core/gsp/cmdq.rs b/drivers/gpu/nova-core/gsp/cmdq.rs
index 9c94f4c6ff6d..845c9e176b93 100644
--- a/drivers/gpu/nova-core/gsp/cmdq.rs
+++ b/drivers/gpu/nova-core/gsp/cmdq.rs
@@ -12,9 +12,10 @@
use kernel::{
device,
dma::{
- CoherentAllocation,
+ CoherentObject,
DmaAddress, //
},
+ dma_write,
io::poll::read_poll_timeout,
prelude::*,
sync::aref::ARef,
@@ -22,8 +23,7 @@
transmute::{
AsBytes,
FromBytes, //
- },
- try_dma_write, //
+ }, //
};
use crate::{
@@ -191,7 +191,7 @@ unsafe impl FromBytes for GspMem {}
/// pointer and the GSP read pointer. This region is returned by [`Self::driver_write_area`].
/// * The driver owns (i.e. can read from) the part of the GSP message queue between the CPU read
/// pointer and the GSP write pointer. This region is returned by [`Self::driver_read_area`].
-struct DmaGspMem(CoherentAllocation<GspMem>);
+struct DmaGspMem(CoherentObject<GspMem>);
impl DmaGspMem {
/// Allocate a new instance and map it for `dev`.
@@ -199,13 +199,11 @@ fn new(dev: &device::Device<device::Bound>) -> Result<Self> {
const MSGQ_SIZE: u32 = num::usize_into_u32::<{ size_of::<Msgq>() }>();
const RX_HDR_OFF: u32 = num::usize_into_u32::<{ mem::offset_of!(Msgq, rx) }>();
- let gsp_mem =
- CoherentAllocation::<GspMem>::alloc_coherent(dev, 1, GFP_KERNEL | __GFP_ZERO)?;
- try_dma_write!(gsp_mem[0].ptes = PteArray::new(gsp_mem.dma_handle())?)?;
- try_dma_write!(
- gsp_mem[0].cpuq.tx = MsgqTxHeader::new(MSGQ_SIZE, RX_HDR_OFF, MSGQ_NUM_PAGES)
- )?;
- try_dma_write!(gsp_mem[0].cpuq.rx = MsgqRxHeader::new())?;
+ let gsp_mem = CoherentObject::<GspMem>::alloc_coherent(dev, GFP_KERNEL | __GFP_ZERO)?;
+ let ptes = PteArray::new(gsp_mem.dma_handle())?;
+ dma_write!(gsp_mem[0].ptes = ptes);
+ dma_write!(gsp_mem[0].cpuq.tx = MsgqTxHeader::new(MSGQ_SIZE, RX_HDR_OFF, MSGQ_NUM_PAGES));
+ dma_write!(gsp_mem[0].cpuq.rx = MsgqRxHeader::new());
Ok(Self(gsp_mem))
}
@@ -223,7 +221,7 @@ fn new(dev: &device::Device<device::Bound>) -> Result<Self> {
// - The `CoherentAllocation` contains exactly one object.
// - We will only access the driver-owned part of the shared memory.
// - Per the safety statement of the function, no concurrent access will be performed.
- let gsp_mem = &mut unsafe { self.0.try_as_slice_mut(0, 1) }.unwrap()[0];
+ let gsp_mem = &mut unsafe { self.0.as_slice_mut::<0, 1>() }[0];
// PANIC: per the invariant of `cpu_write_ptr`, `tx` is `<= MSGQ_NUM_PAGES`.
let (before_tx, after_tx) = gsp_mem.cpuq.msgq.data.split_at_mut(tx);
@@ -258,7 +256,7 @@ fn new(dev: &device::Device<device::Bound>) -> Result<Self> {
// - The `CoherentAllocation` contains exactly one object.
// - We will only access the driver-owned part of the shared memory.
// - Per the safety statement of the function, no concurrent access will be performed.
- let gsp_mem = &unsafe { self.0.try_as_slice(0, 1) }.unwrap()[0];
+ let gsp_mem = &unsafe { self.0.as_slice::<0, 1>() }[0];
// PANIC: per the invariant of `cpu_read_ptr`, `xx` is `<= MSGQ_NUM_PAGES`.
let (before_rx, after_rx) = gsp_mem.gspq.msgq.data.split_at(rx);
diff --git a/drivers/gpu/nova-core/gsp/fw.rs b/drivers/gpu/nova-core/gsp/fw.rs
index caeb0d251fe5..1877b727cc22 100644
--- a/drivers/gpu/nova-core/gsp/fw.rs
+++ b/drivers/gpu/nova-core/gsp/fw.rs
@@ -9,17 +9,14 @@
use core::ops::Range;
use kernel::{
- dma::CoherentAllocation,
+ dma::CoherentSlice,
fmt,
prelude::*,
ptr::{
Alignable,
Alignment, //
},
- sizes::{
- SZ_128K,
- SZ_1M, //
- },
+ sizes::{SZ_128K, SZ_1M},
transmute::{
AsBytes,
FromBytes, //
@@ -652,10 +649,7 @@ unsafe impl AsBytes for LibosMemoryRegionInitArgument {}
unsafe impl FromBytes for LibosMemoryRegionInitArgument {}
impl LibosMemoryRegionInitArgument {
- pub(crate) fn new<A: AsBytes + FromBytes>(
- name: &'static str,
- obj: &CoherentAllocation<A>,
- ) -> Self {
+ pub(crate) fn new<A: AsBytes + FromBytes>(name: &'static str, obj: &CoherentSlice<A>) -> Self {
/// Generates the `ID8` identifier required for some GSP objects.
fn id8(name: &str) -> u64 {
let mut bytes = [0u8; core::mem::size_of::<u64>()];
--
2.52.0
Powered by blists - more mailing lists