| // SPDX-License-Identifier: GPL-2.0 |
| |
| // Copyright (C) 2024 Google LLC. |
| |
| //! Logic for tracepoints. |
| |
| /// Declare the Rust entry point for a tracepoint. |
| /// |
| /// This macro generates an unsafe function that calls into C, and its safety requirements will be |
| /// whatever the relevant C code requires. To document these safety requirements, you may add |
| /// doc-comments when invoking the macro. |
| #[macro_export] |
| macro_rules! declare_trace { |
| ($($(#[$attr:meta])* $pub:vis unsafe fn $name:ident($($argname:ident : $argtyp:ty),* $(,)?);)*) => {$( |
| $( #[$attr] )* |
| #[inline(always)] |
| $pub unsafe fn $name($($argname : $argtyp),*) { |
| #[cfg(CONFIG_TRACEPOINTS)] |
| { |
| // SAFETY: It's always okay to query the static key for a tracepoint. |
| let should_trace = unsafe { |
| $crate::macros::paste! { |
| $crate::jump_label::static_branch_unlikely!( |
| $crate::bindings::[< __tracepoint_ $name >], |
| $crate::bindings::tracepoint, |
| key |
| ) |
| } |
| }; |
| |
| if should_trace { |
| $crate::macros::paste! { |
| // SAFETY: The caller guarantees that it is okay to call this tracepoint. |
| unsafe { $crate::bindings::[< rust_do_trace_ $name >]($($argname),*) }; |
| } |
| } |
| } |
| |
| #[cfg(not(CONFIG_TRACEPOINTS))] |
| { |
| // If tracepoints are disabled, insert a trivial use of each argument |
| // to avoid unused argument warnings. |
| $( let _unused = $argname; )* |
| } |
| } |
| )*} |
| } |
| |
| pub use declare_trace; |