xref: /linux/rust/kernel/tracepoint.rs (revision 7f4f3b14e8079ecde096bd734af10e30d40c27b7)
1*ad37bcd9SAlice Ryhl // SPDX-License-Identifier: GPL-2.0
2*ad37bcd9SAlice Ryhl 
3*ad37bcd9SAlice Ryhl // Copyright (C) 2024 Google LLC.
4*ad37bcd9SAlice Ryhl 
5*ad37bcd9SAlice Ryhl //! Logic for tracepoints.
6*ad37bcd9SAlice Ryhl 
7*ad37bcd9SAlice Ryhl /// Declare the Rust entry point for a tracepoint.
8*ad37bcd9SAlice Ryhl ///
9*ad37bcd9SAlice Ryhl /// This macro generates an unsafe function that calls into C, and its safety requirements will be
10*ad37bcd9SAlice Ryhl /// whatever the relevant C code requires. To document these safety requirements, you may add
11*ad37bcd9SAlice Ryhl /// doc-comments when invoking the macro.
12*ad37bcd9SAlice Ryhl #[macro_export]
13*ad37bcd9SAlice Ryhl macro_rules! declare_trace {
14*ad37bcd9SAlice Ryhl     ($($(#[$attr:meta])* $pub:vis unsafe fn $name:ident($($argname:ident : $argtyp:ty),* $(,)?);)*) => {$(
15*ad37bcd9SAlice Ryhl         $( #[$attr] )*
16*ad37bcd9SAlice Ryhl         #[inline(always)]
17*ad37bcd9SAlice Ryhl         $pub unsafe fn $name($($argname : $argtyp),*) {
18*ad37bcd9SAlice Ryhl             #[cfg(CONFIG_TRACEPOINTS)]
19*ad37bcd9SAlice Ryhl             {
20*ad37bcd9SAlice Ryhl                 // SAFETY: It's always okay to query the static key for a tracepoint.
21*ad37bcd9SAlice Ryhl                 let should_trace = unsafe {
22*ad37bcd9SAlice Ryhl                     $crate::macros::paste! {
23*ad37bcd9SAlice Ryhl                         $crate::jump_label::static_branch_unlikely!(
24*ad37bcd9SAlice Ryhl                             $crate::bindings::[< __tracepoint_ $name >],
25*ad37bcd9SAlice Ryhl                             $crate::bindings::tracepoint,
26*ad37bcd9SAlice Ryhl                             key
27*ad37bcd9SAlice Ryhl                         )
28*ad37bcd9SAlice Ryhl                     }
29*ad37bcd9SAlice Ryhl                 };
30*ad37bcd9SAlice Ryhl 
31*ad37bcd9SAlice Ryhl                 if should_trace {
32*ad37bcd9SAlice Ryhl                     $crate::macros::paste! {
33*ad37bcd9SAlice Ryhl                         // SAFETY: The caller guarantees that it is okay to call this tracepoint.
34*ad37bcd9SAlice Ryhl                         unsafe { $crate::bindings::[< rust_do_trace_ $name >]($($argname),*) };
35*ad37bcd9SAlice Ryhl                     }
36*ad37bcd9SAlice Ryhl                 }
37*ad37bcd9SAlice Ryhl             }
38*ad37bcd9SAlice Ryhl 
39*ad37bcd9SAlice Ryhl             #[cfg(not(CONFIG_TRACEPOINTS))]
40*ad37bcd9SAlice Ryhl             {
41*ad37bcd9SAlice Ryhl                 // If tracepoints are disabled, insert a trivial use of each argument
42*ad37bcd9SAlice Ryhl                 // to avoid unused argument warnings.
43*ad37bcd9SAlice Ryhl                 $( let _unused = $argname; )*
44*ad37bcd9SAlice Ryhl             }
45*ad37bcd9SAlice Ryhl         }
46*ad37bcd9SAlice Ryhl     )*}
47*ad37bcd9SAlice Ryhl }
48*ad37bcd9SAlice Ryhl 
49*ad37bcd9SAlice Ryhl pub use declare_trace;
50