mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
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

  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®