From: Zhi Wang <zhiw@nvidia.com>
To: <dakr@kernel.org>, <acourbot@nvidia.com>
Cc: <airlied@gmail.com>, <simona@ffwll.ch>, <ojeda@kernel.org>,
<alex.gaynor@gmail.com>, <boqun.feng@gmail.com>,
<gary@garyguo.net>, <bjorn3_gh@protonmail.com>,
<lossin@kernel.org>, <a.hindborg@kernel.org>,
<aliceryhl@google.com>, <tmgross@umich.edu>,
<jhubbard@nvidia.com>, <ecourtney@nvidia.com>,
<joelagnelf@nvidia.com>, <apopple@nvidia.com>, <cjia@nvidia.com>,
<smitra@nvidia.com>, <kjaju@nvidia.com>, <alkumar@nvidia.com>,
<ankita@nvidia.com>, <aniketa@nvidia.com>, <kwankhede@nvidia.com>,
<targupta@nvidia.com>, <nova-gpu@lists.linux.dev>,
<linux-kernel@vger.kernel.org>, <zhiwang@kernel.org>,
Zhi Wang <zhiw@nvidia.com>
Subject: [PATCH 1/3] gpu: nova-core: add formatted tracing
Date: Wed, 5 Aug 2026 10:57:21 +0300 [thread overview]
Message-ID: <cdb03b9b0262ef59f3dd93ee3c7bfaa38312ddc4.1785907106.git.zhiw@nvidia.com> (raw)
In-Reply-To: <cover.1785907106.git.zhiw@nvidia.com>
Provide formatted trace events for general driver, FSP, GSP and vGPU
messages. Add a shared event class and a formatting helper that avoids
formatting disabled events and uses a fixed-size stack buffer.
Signed-off-by: Zhi Wang <zhiw@nvidia.com>
---
drivers/gpu/Makefile | 4 +-
drivers/gpu/nova-core/nova_core.rs | 1 +
drivers/gpu/nova-core/trace.c | 5 +
drivers/gpu/nova-core/trace.h | 52 +++++++++
drivers/gpu/nova-core/trace.rs | 162 +++++++++++++++++++++++++++++
rust/bindings/bindings_helper.h | 4 +
6 files changed, 227 insertions(+), 1 deletion(-)
create mode 100644 drivers/gpu/nova-core/trace.c
create mode 100644 drivers/gpu/nova-core/trace.h
create mode 100644 drivers/gpu/nova-core/trace.rs
diff --git a/drivers/gpu/Makefile b/drivers/gpu/Makefile
index e372fc02139f..d26e7dea9e66 100644
--- a/drivers/gpu/Makefile
+++ b/drivers/gpu/Makefile
@@ -14,7 +14,9 @@ obj-$(CONFIG_TRACE_GPU_MEM) += trace/
# system supports cross-crate dependencies natively.
obj-$(CONFIG_NOVA_CORE) += nova-core.o
-nova-core-y := nova-core/nova_core.o nova-core/nova_core_exports.o
+nova-core-y := nova-core/nova_core.o \
+ nova-core/trace.o \
+ nova-core/nova_core_exports.o
obj-$(CONFIG_DRM_NOVA) += nova-drm.o
nova-drm-y := drm/nova/nova.o
diff --git a/drivers/gpu/nova-core/nova_core.rs b/drivers/gpu/nova-core/nova_core.rs
index 35a8b1214b0e..85ee5067ef56 100644
--- a/drivers/gpu/nova-core/nova_core.rs
+++ b/drivers/gpu/nova-core/nova_core.rs
@@ -22,6 +22,7 @@
mod num;
mod regs;
mod sbuffer;
+mod trace;
mod vbios;
mod vgpu;
diff --git a/drivers/gpu/nova-core/trace.c b/drivers/gpu/nova-core/trace.c
new file mode 100644
index 000000000000..c72cb0f65b47
--- /dev/null
+++ b/drivers/gpu/nova-core/trace.c
@@ -0,0 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#define CREATE_TRACE_POINTS
+#define CREATE_RUST_TRACE_POINTS
+#include "trace.h"
diff --git a/drivers/gpu/nova-core/trace.h b/drivers/gpu/nova-core/trace.h
new file mode 100644
index 000000000000..a8e5181ba302
--- /dev/null
+++ b/drivers/gpu/nova-core/trace.h
@@ -0,0 +1,52 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM nova_core
+
+#if !defined(_NOVA_CORE_TRACE_H_) || defined(TRACE_HEADER_MULTI_READ)
+#define _NOVA_CORE_TRACE_H_
+
+#include <linux/tracepoint.h>
+
+DECLARE_EVENT_CLASS(nova_core_trace_class,
+ TP_PROTO(const char *dev, const char *message, size_t message_len),
+ TP_ARGS(dev, message, message_len),
+ TP_STRUCT__entry(
+ __string(dev, dev)
+ __string_len(message, message, message_len)
+ ),
+ TP_fast_assign(
+ __assign_str(dev);
+ __assign_str(message);
+ ),
+ TP_printk("%s %s", __get_str(dev), __get_str(message))
+);
+
+DEFINE_EVENT(nova_core_trace_class, nova_core_trace_driver,
+ TP_PROTO(const char *dev, const char *message, size_t message_len),
+ TP_ARGS(dev, message, message_len)
+);
+
+DEFINE_EVENT(nova_core_trace_class, nova_core_trace_fsp,
+ TP_PROTO(const char *dev, const char *message, size_t message_len),
+ TP_ARGS(dev, message, message_len)
+);
+
+DEFINE_EVENT(nova_core_trace_class, nova_core_trace_gsp,
+ TP_PROTO(const char *dev, const char *message, size_t message_len),
+ TP_ARGS(dev, message, message_len)
+);
+
+DEFINE_EVENT(nova_core_trace_class, nova_core_trace_vgpu,
+ TP_PROTO(const char *dev, const char *message, size_t message_len),
+ TP_ARGS(dev, message, message_len)
+);
+
+#endif /* _NOVA_CORE_TRACE_H_ */
+
+#undef TRACE_INCLUDE_PATH
+#define TRACE_INCLUDE_PATH ../../drivers/gpu/nova-core
+#undef TRACE_INCLUDE_FILE
+#define TRACE_INCLUDE_FILE trace
+
+#include <trace/define_trace.h>
diff --git a/drivers/gpu/nova-core/trace.rs b/drivers/gpu/nova-core/trace.rs
new file mode 100644
index 000000000000..893479b3fcb5
--- /dev/null
+++ b/drivers/gpu/nova-core/trace.rs
@@ -0,0 +1,162 @@
+// SPDX-License-Identifier: GPL-2.0
+
+//! Nova tracepoint helpers.
+
+use kernel::{
+ ffi::c_char,
+ fmt::{
+ self,
+ Write, //
+ },
+ str::{
+ CStr,
+ CStrExt,
+ Formatter, //
+ }, //
+};
+
+const MESSAGE_MAX: usize = 512;
+
+// To add another formatted Nova Core trace event:
+//
+// 1. Define it from `nova_core_trace_class` in `trace.h`.
+// 2. Declare its Rust entry point with `declare_nova_core_trace!` below.
+// 3. Add a public frontend macro that passes its event name to
+// `nova_core_trace_impl!`, following the examples at the end of this file.
+pub(crate) mod raw {
+ use super::c_char;
+
+ macro_rules! declare_nova_core_trace {
+ ($event:ident) => {
+ kernel::tracepoint::declare_trace! {
+ /// # Safety
+ ///
+ /// `dev` must point to a valid NUL-terminated string, and
+ /// `message` must point to `message_len` readable bytes for
+ /// this call.
+ pub(crate) unsafe fn $event(
+ dev: *const c_char,
+ message: *const c_char,
+ message_len: usize,
+ );
+ }
+ };
+ }
+
+ declare_nova_core_trace!(nova_core_trace_driver);
+ declare_nova_core_trace!(nova_core_trace_fsp);
+ declare_nova_core_trace!(nova_core_trace_gsp);
+ declare_nova_core_trace!(nova_core_trace_vgpu);
+}
+
+/// Formats and emits a Nova Core text trace event.
+///
+/// # Safety
+///
+/// `trace` must synchronously consume `dev`, `message`, and `message_len`
+/// according to the `nova_core_trace_class` event prototype.
+#[expect(dead_code)]
+pub(crate) unsafe fn nova_core_trace_fmt(
+ dev: &CStr,
+ args: fmt::Arguments<'_>,
+ trace: unsafe fn(*const c_char, *const c_char, usize),
+) {
+ let mut message = [0u8; MESSAGE_MAX];
+ let message_len = {
+ let mut formatter = Formatter::new(&mut message);
+
+ let _ = formatter.write_fmt(args);
+ formatter.bytes_written().min(MESSAGE_MAX)
+ };
+
+ // SAFETY: The caller guarantees that `trace` synchronously consumes its
+ // arguments. The device name is NUL-terminated, and `message` contains
+ // `message_len` initialized bytes.
+ unsafe {
+ trace(
+ dev.as_char_ptr(),
+ message.as_ptr().cast::<c_char>(),
+ message_len,
+ )
+ }
+}
+
+#[expect(unused_macros)]
+macro_rules! nova_core_trace_impl {
+ ($event:ident, $dev:expr, $($arg:tt)*) => {{
+ #[cfg(CONFIG_TRACEPOINTS)]
+ let should_trace = {
+ // SAFETY: `$event` names a real C tracepoint static key.
+ unsafe {
+ kernel::macros::paste! {
+ kernel::jump_label::static_branch_unlikely!(
+ kernel::bindings::[<__tracepoint_ $event>],
+ kernel::bindings::tracepoint,
+ key
+ )
+ }
+ }
+ };
+
+ #[cfg(not(CONFIG_TRACEPOINTS))]
+ let should_trace = false;
+
+ if should_trace {
+ match ($dev, kernel::prelude::fmt!($($arg)*)) {
+ (dev, args) => {
+ // SAFETY: `$event` has the event-class prototype required
+ // by `nova_core_trace_fmt`.
+ unsafe {
+ $crate::trace::nova_core_trace_fmt(
+ dev.as_ref().name(),
+ args,
+ $crate::trace::raw::$event,
+ )
+ }
+ }
+ }
+ }
+ }};
+}
+
+// Frontend macros expand in their caller's module and invoke this helper by
+// path, so the re-export must be visible from the parent module.
+#[expect(unused_imports)]
+pub(super) use nova_core_trace_impl;
+
+#[expect(unused_macros)]
+macro_rules! nova_core_trace_driver {
+ ($dev:expr, $($arg:tt)*) => {
+ $crate::trace::nova_core_trace_impl!(nova_core_trace_driver, $dev, $($arg)*)
+ };
+}
+
+#[expect(unused_macros)]
+macro_rules! nova_core_trace_fsp {
+ ($dev:expr, $($arg:tt)*) => {
+ $crate::trace::nova_core_trace_impl!(nova_core_trace_fsp, $dev, $($arg)*)
+ };
+}
+
+#[expect(unused_macros)]
+macro_rules! nova_core_trace_gsp {
+ ($dev:expr, $($arg:tt)*) => {
+ $crate::trace::nova_core_trace_impl!(nova_core_trace_gsp, $dev, $($arg)*)
+ };
+}
+
+#[expect(unused_macros)]
+macro_rules! nova_core_trace_vgpu {
+ ($dev:expr, $($arg:tt)*) => {
+ $crate::trace::nova_core_trace_impl!(nova_core_trace_vgpu, $dev, $($arg)*)
+ };
+}
+
+#[expect(unused_imports)]
+pub(crate) use nova_core_trace_driver;
+#[expect(unused_imports)]
+pub(crate) use nova_core_trace_fsp;
+#[expect(unused_imports)]
+pub(crate) use nova_core_trace_gsp;
+#[expect(unused_imports)]
+pub(crate) use nova_core_trace_vgpu;
diff --git a/rust/bindings/bindings_helper.h b/rust/bindings/bindings_helper.h
index 1124785e210b..d1e0a60e370f 100644
--- a/rust/bindings/bindings_helper.h
+++ b/rust/bindings/bindings_helper.h
@@ -165,3 +165,7 @@ const unsigned long RUST_CONST_HELPER_GPU_BUDDY_TRIM_DISABLE = GPU_BUDDY_TRIM_DI
#include "../../drivers/android/binder/rust_binder.h"
#include "../../drivers/android/binder/rust_binder_events.h"
#endif
+
+#if IS_ENABLED(CONFIG_NOVA_CORE)
+#include "../../drivers/gpu/nova-core/trace.h"
+#endif
--
2.53.0
next prev parent reply other threads:[~2026-08-05 7:58 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-05 7:57 [PATCH 0/3] gpu: nova-core: add formatted trace events Zhi Wang
2026-08-05 7:57 ` Zhi Wang [this message]
2026-08-05 7:57 ` [PATCH 2/3] gpu: nova-core: trace driver probe and firmware messages Zhi Wang
2026-08-05 7:57 ` [PATCH 3/3] gpu: nova-core: trace vGPU state Zhi Wang
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=cdb03b9b0262ef59f3dd93ee3c7bfaa38312ddc4.1785907106.git.zhiw@nvidia.com \
--to=zhiw@nvidia.com \
--cc=a.hindborg@kernel.org \
--cc=acourbot@nvidia.com \
--cc=airlied@gmail.com \
--cc=alex.gaynor@gmail.com \
--cc=aliceryhl@google.com \
--cc=alkumar@nvidia.com \
--cc=aniketa@nvidia.com \
--cc=ankita@nvidia.com \
--cc=apopple@nvidia.com \
--cc=bjorn3_gh@protonmail.com \
--cc=boqun.feng@gmail.com \
--cc=cjia@nvidia.com \
--cc=dakr@kernel.org \
--cc=ecourtney@nvidia.com \
--cc=gary@garyguo.net \
--cc=jhubbard@nvidia.com \
--cc=joelagnelf@nvidia.com \
--cc=kjaju@nvidia.com \
--cc=kwankhede@nvidia.com \
--cc=linux-kernel@vger.kernel.org \
--cc=lossin@kernel.org \
--cc=nova-gpu@lists.linux.dev \
--cc=ojeda@kernel.org \
--cc=simona@ffwll.ch \
--cc=smitra@nvidia.com \
--cc=targupta@nvidia.com \
--cc=tmgross@umich.edu \
--cc=zhiwang@kernel.org \
/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®