From: Vladislav Zaharov <vladazaharova2018@gmail.com>
To: dakr@kernel.org, jhubbard@nvidia.com
Cc: acourbot@nvidia.com, aliceryhl@google.com, ttabi@nvidia.com,
gary@garyguo.net, nova-gpu@lists.linux.dev,
dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org,
linux-doc@vger.kernel.org, vladazaharova2018@gmail.com
Subject: [PATCH v7 1/4] gpu: nova-core: move the debugfs root into the module data
Date: Fri, 13 Nov 2026 14:53:14 +0700 [thread overview]
Message-ID: <20261113075317.934264-2-vladazaharova2018@gmail.com> (raw)
In-Reply-To: <20261113075317.934264-1-vladazaharova2018@gmail.com>
The debugfs root lives in a static that is cleared by a guard field of
the module data. The guard is built after the driver registration, so if
the registration fails, the root is never removed and the next module
load finds the name taken.
Move the root into a DebugfsData owned by the module data, and keep only
a pointer to it in the static, for devices that cannot reach the module
data yet. If the registration fails, the root is dropped with the rest
of the module data.
Fixes: 09691f5d8070 ("gpu: nova-core: create debugfs root in module init")
Signed-off-by: Vladislav Zaharov <vladazaharova2018@gmail.com>
---
drivers/gpu/nova-core/debugfs.rs | 29 ++++++++++++++
drivers/gpu/nova-core/gsp.rs | 11 +-----
drivers/gpu/nova-core/nova_core.rs | 62 ++++++++++++++++++------------
3 files changed, 69 insertions(+), 33 deletions(-)
create mode 100644 drivers/gpu/nova-core/debugfs.rs
diff --git a/drivers/gpu/nova-core/debugfs.rs b/drivers/gpu/nova-core/debugfs.rs
new file mode 100644
index 000000000000..6c6ed129f0da
--- /dev/null
+++ b/drivers/gpu/nova-core/debugfs.rs
@@ -0,0 +1,29 @@
+// SPDX-License-Identifier: GPL-2.0
+
+//! Debugfs data shared by all GPUs of the driver.
+
+use kernel::{
+ debugfs,
+ prelude::*, //
+};
+
+/// Debugfs data the module shares with every GPU it drives.
+#[pin_data]
+pub(crate) struct DebugfsData {
+ /// Root directory of the driver in debugfs.
+ root: debugfs::Dir,
+}
+
+impl DebugfsData {
+ /// Creates the debugfs data of the module.
+ pub(crate) fn new() -> impl PinInit<Self> {
+ pin_init!(Self {
+ root: debugfs::Dir::new(c"nova-core"),
+ })
+ }
+
+ /// Returns the root directory of the driver.
+ pub(crate) fn root(&self) -> &debugfs::Dir {
+ &self.root
+ }
+}
diff --git a/drivers/gpu/nova-core/gsp.rs b/drivers/gpu/nova-core/gsp.rs
index a4b832f6aec1..79ee74a0a16f 100644
--- a/drivers/gpu/nova-core/gsp.rs
+++ b/drivers/gpu/nova-core/gsp.rs
@@ -200,15 +200,8 @@ pub(crate) fn new(
logrm,
};
- #[allow(static_mut_refs)]
- // SAFETY: `DEBUGFS_ROOT` is created before driver registration and cleared
- // after driver unregistration, so no probe() can race with its modification.
- //
- // PANIC: `DEBUGFS_ROOT` cannot be `None` here. It is set before driver
- // registration and cleared after driver unregistration, so it is always
- // `Some` for the entire lifetime that probe() can be called.
- let log_parent: &debugfs::Dir = unsafe { crate::DEBUGFS_ROOT.as_ref() }
- .expect("DEBUGFS_ROOT not initialized");
+ let log_parent: &debugfs::Dir =
+ crate::NovaCoreModule::debugfs_data(dev).root();
log_parent.scope(log_buffers, dev.name(), |logs, dir| {
dir.read_binary_file(c"loginit", &logs.loginit.0);
diff --git a/drivers/gpu/nova-core/nova_core.rs b/drivers/gpu/nova-core/nova_core.rs
index a8f6dc22057b..f5d08de8a212 100644
--- a/drivers/gpu/nova-core/nova_core.rs
+++ b/drivers/gpu/nova-core/nova_core.rs
@@ -3,7 +3,7 @@
//! Nova Core GPU Driver
use kernel::{
- debugfs,
+ device,
driver::Registration,
pci,
prelude::*,
@@ -11,6 +11,7 @@
};
pub mod api;
+mod debugfs;
mod driver;
mod falcon;
mod fb;
@@ -30,42 +31,55 @@
mod vbios;
mod vgpu;
-pub(crate) const MODULE_NAME: &core::ffi::CStr = <LocalModule as kernel::ModuleMetadata>::NAME;
-
-// TODO: Move this into per-module data once that exists.
-static mut DEBUGFS_ROOT: Option<debugfs::Dir> = None;
+use debugfs::DebugfsData;
-/// Guard that clears `DEBUGFS_ROOT` when dropped.
-struct DebugfsRootGuard;
+pub(crate) const MODULE_NAME: &core::ffi::CStr = <LocalModule as kernel::ModuleMetadata>::NAME;
-impl Drop for DebugfsRootGuard {
- fn drop(&mut self) {
- // SAFETY: This guard is dropped after `_driver` (due to field order),
- // so the driver is unregistered and no probe() can be running.
- unsafe { DEBUGFS_ROOT = None };
- }
-}
+/// Pointer to the [`DebugfsData`] of the module.
+///
+/// A device currently has no way to reach the data of its module, so it goes through here.
+///
+/// # Invariants
+///
+/// - Only written once before the driver is registered.
+/// - Points to a valid [`DebugfsData`] for as long as the driver is registered.
+// TODO: Drop this once devices can reach the data of their module.
+static mut DEBUGFS_DATA: *const DebugfsData = core::ptr::null();
#[pin_data]
struct NovaCoreModule {
- // Fields are dropped in declaration order, so `_driver` is dropped first,
- // then `_debugfs_guard` clears `DEBUGFS_ROOT`.
+ // Fields are dropped in declaration order. `_driver` must be dropped before `_debugfs` to
+ // uphold the invariant of `DEBUGFS_DATA` that it remains valid for as long as the driver is
+ // registered.
#[pin]
_driver: Registration<pci::Adapter<driver::NovaCoreDriver>>,
- _debugfs_guard: DebugfsRootGuard,
+ #[pin]
+ _debugfs: DebugfsData,
+}
+
+impl NovaCoreModule {
+ /// Returns the debugfs data of the module.
+ pub(crate) fn debugfs_data<'a>(_dev: &'a device::Device<device::Bound>) -> &'a DebugfsData {
+ // SAFETY: `_dev` is bound, so the driver is registered. Per the invariants of
+ // `DEBUGFS_DATA`, the pointer is thus valid and not being written to. The `'a` lifetime
+ // ensures that the returned reference cannot outlive the bound device.
+ unsafe { &*DEBUGFS_DATA }
+ }
}
impl InPlaceModule for NovaCoreModule {
fn init(module: &'static kernel::ThisModule) -> impl PinInit<Self, Error> {
- let dir = debugfs::Dir::new(c"nova-core");
-
- // SAFETY: We are the only driver code running during init, so there
- // cannot be any concurrent access to `DEBUGFS_ROOT`.
- unsafe { DEBUGFS_ROOT = Some(dir) };
-
try_pin_init!(Self {
+ _debugfs <- DebugfsData::new(),
+ _: {
+ // SAFETY: The driver is not registered yet, meaning that no device can be probed
+ // and thus nothing can access `DEBUGFS_DATA` concurrently.
+ //
+ // INVARIANT: `DEBUGFS_DATA` is written before the driver is registered below and
+ // points to `_debugfs`, which is pinned and dropped after `_driver`.
+ unsafe { DEBUGFS_DATA = &*_debugfs };
+ },
_driver <- Registration::new(MODULE_NAME, module),
- _debugfs_guard: DebugfsRootGuard,
})
}
}
--
2.56.0
next prev parent reply other threads:[~2026-11-13 7:53 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-13 7:53 [PATCH v7 0/4] gpu: nova-core: retain the GSP-RM log buffers Vladislav Zaharov
2026-11-13 7:53 ` Vladislav Zaharov [this message]
2026-11-13 7:53 ` [PATCH v7 2/4] gpu: nova-core: gsp: move the log buffers into their own file Vladislav Zaharov
2026-11-13 7:53 ` [PATCH v7 3/4] gpu: nova-core: gsp: retain the GSP-RM log buffers after unbind Vladislav Zaharov
2026-11-13 20:34 ` Danilo Krummrich
2026-11-13 7:53 ` [PATCH v7 4/4] Documentation: nova: remove completed GSP log buffer task Vladislav Zaharov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261113075317.934264-2-vladazaharova2018@gmail.com \
--to=vladazaharova2018@gmail.com \
--cc=acourbot@nvidia.com \
--cc=aliceryhl@google.com \
--cc=dakr@kernel.org \
--cc=dri-devel@lists.freedesktop.org \
--cc=gary@garyguo.net \
--cc=jhubbard@nvidia.com \
--cc=linux-doc@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=nova-gpu@lists.linux.dev \
--cc=ttabi@nvidia.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®