Commit e2580413 authored by Danilo Krummrich's avatar Danilo Krummrich Committed by Alexandre Courbot
Browse files

gpu: nova-core: take advantage of pci::Device::unbind()



Now that we have pci::Device::unbind() we can unregister the sysmem
flush page with a direct access the I/O resource, i.e. without RCU read
side critical section.

Signed-off-by: default avatarDanilo Krummrich <dakr@kernel.org>
Reviewed-by: default avatarAlexandre Courbot <acourbot@nvidia.com>
Link: https://lore.kernel.org/r/20250901150207.63094-1-dakr@kernel.org


Signed-off-by: default avatarAlexandre Courbot <acourbot@nvidia.com>
parent c58466b8
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -54,4 +54,8 @@ fn probe(pdev: &pci::Device<Core>, _info: &Self::IdInfo) -> Result<Pin<KBox<Self

        Ok(this)
    }

    fn unbind(pdev: &pci::Device<Core>, this: Pin<&Self>) {
        this.gpu.unbind(pdev.as_ref());
    }
}
+12 −10
Original line number Diff line number Diff line
@@ -163,7 +163,7 @@ fn new(bar: &Bar0) -> Result<Spec> {
}

/// Structure holding the resources required to operate the GPU.
#[pin_data(PinnedDrop)]
#[pin_data]
pub(crate) struct Gpu {
    spec: Spec,
    /// MMIO mapping of PCI BAR 0
@@ -174,15 +174,6 @@ pub(crate) struct Gpu {
    sysmem_flush: SysmemFlush,
}

#[pinned_drop]
impl PinnedDrop for Gpu {
    fn drop(self: Pin<&mut Self>) {
        // Unregister the sysmem flush page before we release it.
        self.bar
            .try_access_with(|b| self.sysmem_flush.unregister(b));
    }
}

impl Gpu {
    /// Helper function to load and run the FWSEC-FRTS firmware and confirm that it has properly
    /// created the WPR2 region.
@@ -309,4 +300,15 @@ pub(crate) fn new(
            sysmem_flush,
        }))
    }

    /// 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());
    }
}