mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 09:36:22 +02:00
gpu: nova-core: use lifetime for Bar
Take advantage of the lifetime-parameterized pci::Bar<'bound> to hold the BAR mapping directly in NovaCore<'bound>, and pass a borrowed reference to Gpu<'bound>. This eliminates the Arc<Devres<Bar0>> indirection, removes runtime revocation checks for BAR access, and simplifies Gpu::unbind(). Reviewed-by: Eliot Courtney <ecourtney@nvidia.com> Reviewed-by: Alexandre Courbot <acourbot@nvidia.com> Tested-by: Alexandre Courbot <acourbot@nvidia.com> Link: https://patch.msgid.link/20260525225838.276108-2-dakr@kernel.org Signed-off-by: Danilo Krummrich <dakr@kernel.org>
This commit is contained in:
parent
a3e50e7279
commit
88b70f5a05
|
|
@ -13,12 +13,9 @@
|
|||
},
|
||||
prelude::*,
|
||||
sizes::SZ_16M,
|
||||
sync::{
|
||||
atomic::{
|
||||
Atomic,
|
||||
Relaxed, //
|
||||
},
|
||||
Arc,
|
||||
sync::atomic::{
|
||||
Atomic,
|
||||
Relaxed, //
|
||||
},
|
||||
types::ForLt,
|
||||
};
|
||||
|
|
@ -31,7 +28,8 @@
|
|||
#[pin_data]
|
||||
pub(crate) struct NovaCore<'bound> {
|
||||
#[pin]
|
||||
pub(crate) gpu: Gpu,
|
||||
pub(crate) gpu: Gpu<'bound>,
|
||||
bar: pci::Bar<'bound, BAR0_SIZE>,
|
||||
#[allow(clippy::type_complexity)]
|
||||
_reg: auxiliary::Registration<'bound, ForLt!(())>,
|
||||
}
|
||||
|
|
@ -48,7 +46,7 @@ pub(crate) struct NovaCore<'bound> {
|
|||
// DMA addresses. These systems should be quite rare.
|
||||
const GPU_DMA_BITS: u32 = 47;
|
||||
|
||||
pub(crate) type Bar0 = pci::Bar<'static, BAR0_SIZE>;
|
||||
pub(crate) type Bar0 = kernel::io::Mmio<BAR0_SIZE>;
|
||||
|
||||
kernel::pci_device_table!(
|
||||
PCI_TABLE,
|
||||
|
|
@ -95,14 +93,14 @@ fn probe<'bound>(
|
|||
// other threads of execution.
|
||||
unsafe { pdev.dma_set_mask_and_coherent(DmaMask::new::<GPU_DMA_BITS>())? };
|
||||
|
||||
let bar = Arc::new(
|
||||
pdev.iomap_region_sized::<BAR0_SIZE>(0, c"nova-core/bar0")?
|
||||
.into_devres()?,
|
||||
GFP_KERNEL,
|
||||
)?;
|
||||
|
||||
Ok(try_pin_init!(NovaCore {
|
||||
gpu <- Gpu::new(pdev, bar.clone(), bar.access(pdev.as_ref())?),
|
||||
bar: pdev.iomap_region_sized::<BAR0_SIZE>(0, c"nova-core/bar0")?,
|
||||
// TODO: Use `&bar` self-referential pin-init syntax once available.
|
||||
//
|
||||
// SAFETY: `bar` is initialized before this expression is evaluated
|
||||
// (`try_pin_init!()` initializes fields in declaration order), lives at a pinned
|
||||
// stable address, and is dropped after `gpu` (struct field drop order).
|
||||
gpu <- Gpu::new(pdev, unsafe { &*core::ptr::from_ref(bar) }),
|
||||
_reg: auxiliary::Registration::new(
|
||||
pdev.as_ref(),
|
||||
c"nova-drm",
|
||||
|
|
@ -116,7 +114,7 @@ fn probe<'bound>(
|
|||
})
|
||||
}
|
||||
|
||||
fn unbind<'bound>(pdev: &'bound pci::Device<Core<'_>>, this: Pin<&Self::Data<'bound>>) {
|
||||
this.gpu.unbind(pdev.as_ref());
|
||||
fn unbind<'bound>(_pdev: &'bound pci::Device<Core<'_>>, this: Pin<&Self::Data<'bound>>) {
|
||||
this.gpu.unbind();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,13 +2,11 @@
|
|||
|
||||
use kernel::{
|
||||
device,
|
||||
devres::Devres,
|
||||
fmt,
|
||||
io::Io,
|
||||
num::Bounded,
|
||||
pci,
|
||||
prelude::*,
|
||||
sync::Arc, //
|
||||
prelude::*, //
|
||||
};
|
||||
|
||||
use crate::{
|
||||
|
|
@ -246,10 +244,10 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|||
|
||||
/// Structure holding the resources required to operate the GPU.
|
||||
#[pin_data]
|
||||
pub(crate) struct Gpu {
|
||||
pub(crate) struct Gpu<'gpu> {
|
||||
spec: Spec,
|
||||
/// MMIO mapping of PCI BAR 0
|
||||
bar: Arc<Devres<Bar0>>,
|
||||
/// MMIO mapping of PCI BAR 0.
|
||||
bar: &'gpu Bar0,
|
||||
/// System memory page required for flushing all pending GPU-side memory writes done through
|
||||
/// PCIE into system memory, via sysmembar (A GPU-initiated HW memory-barrier operation).
|
||||
sysmem_flush: SysmemFlush,
|
||||
|
|
@ -262,12 +260,11 @@ pub(crate) struct Gpu {
|
|||
gsp: Gsp,
|
||||
}
|
||||
|
||||
impl Gpu {
|
||||
pub(crate) fn new<'a>(
|
||||
pdev: &'a pci::Device<device::Bound>,
|
||||
devres_bar: Arc<Devres<Bar0>>,
|
||||
bar: &'a Bar0,
|
||||
) -> impl PinInit<Self, Error> + 'a {
|
||||
impl<'gpu> Gpu<'gpu> {
|
||||
pub(crate) fn new(
|
||||
pdev: &'gpu pci::Device<device::Bound>,
|
||||
bar: &'gpu Bar0,
|
||||
) -> impl PinInit<Self, Error> + 'gpu {
|
||||
try_pin_init!(Self {
|
||||
spec: Spec::new(pdev.as_ref(), bar).inspect(|spec| {
|
||||
dev_info!(pdev,"NVIDIA ({})\n", spec);
|
||||
|
|
@ -279,6 +276,8 @@ pub(crate) fn new<'a>(
|
|||
.inspect_err(|_| dev_err!(pdev, "GFW boot did not complete\n"))?;
|
||||
},
|
||||
|
||||
bar,
|
||||
|
||||
sysmem_flush: SysmemFlush::register(pdev.as_ref(), bar, spec.chipset)?,
|
||||
|
||||
gsp_falcon: Falcon::new(
|
||||
|
|
@ -292,19 +291,13 @@ pub(crate) fn new<'a>(
|
|||
gsp <- Gsp::new(pdev),
|
||||
|
||||
_: { gsp.boot(pdev, bar, spec.chipset, gsp_falcon, sec2_falcon)? },
|
||||
|
||||
bar: devres_bar,
|
||||
})
|
||||
}
|
||||
|
||||
/// Called when the corresponding [`Device`](device::Device) is unbound.
|
||||
///
|
||||
/// Note: This method must only be called from `Driver::unbind`.
|
||||
pub(crate) fn unbind(&self, dev: &device::Device<device::Core<'_>>) {
|
||||
kernel::warn_on!(self
|
||||
.bar
|
||||
.access(dev)
|
||||
.inspect(|bar| self.sysmem_flush.unregister(bar))
|
||||
.is_err());
|
||||
pub(crate) fn unbind(&self) {
|
||||
self.sysmem_flush.unregister(self.bar);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user