]> www.infradead.org Git - users/hch/misc.git/commitdiff
gpu: nova-core: take advantage of pci::Device::unbind()
authorDanilo Krummrich <dakr@kernel.org>
Mon, 1 Sep 2025 15:01:53 +0000 (17:01 +0200)
committerAlexandre Courbot <acourbot@nvidia.com>
Sat, 6 Sep 2025 11:07:42 +0000 (20:07 +0900)
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: Danilo Krummrich <dakr@kernel.org>
Reviewed-by: Alexandre Courbot <acourbot@nvidia.com>
Link: https://lore.kernel.org/r/20250901150207.63094-1-dakr@kernel.org
Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
drivers/gpu/nova-core/driver.rs
drivers/gpu/nova-core/gpu.rs

index 274989ea1fb4a5e3e6678a08920ddc76d2809ab2..02b3edd7bbdccb22d75db5999eb9b4a71cef58c1 100644 (file)
@@ -54,4 +54,8 @@ impl pci::Driver for NovaCore {
 
         Ok(this)
     }
+
+    fn unbind(pdev: &pci::Device<Core>, this: Pin<&Self>) {
+        this.gpu.unbind(pdev.as_ref());
+    }
 }
index 4d0f759610ec6eb8a716c039a2e67859410da17c..a0878ecdc18bc9e9d975b9ab9c85dd7ab9c3d995 100644 (file)
@@ -163,7 +163,7 @@ impl 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 @@ impl Gpu {
             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());
+    }
 }