| 
 | 1 | +// SPDX-License-Identifier: GPL-2.0  | 
 | 2 | + | 
 | 3 | +// Copyright (C) 2024 Google LLC.  | 
 | 4 | + | 
 | 5 | +//! Logic for tracepoints.  | 
 | 6 | +
  | 
 | 7 | +/// Declare the Rust entry point for a tracepoint.  | 
 | 8 | +#[macro_export]  | 
 | 9 | +macro_rules! declare_trace {  | 
 | 10 | +    ($($(#[$attr:meta])* $pub:vis fn $name:ident($($argname:ident : $argtyp:ty),* $(,)?);)*) => {$(  | 
 | 11 | +        $( #[$attr] )*  | 
 | 12 | +        #[inline(always)]  | 
 | 13 | +        $pub unsafe fn $name($($argname : $argtyp),*) {  | 
 | 14 | +            #[cfg(CONFIG_TRACEPOINTS)]  | 
 | 15 | +            {  | 
 | 16 | +                use $crate::bindings::*;  | 
 | 17 | + | 
 | 18 | +                // SAFETY: This macro only compiles if $name is a real tracepoint, and if it is a  | 
 | 19 | +                // real tracepoint, then it is okay to query the static key.  | 
 | 20 | +                let should_trace = unsafe {  | 
 | 21 | +                    $crate::macros::paste! {  | 
 | 22 | +                        $crate::static_key::static_key_false!(  | 
 | 23 | +                            [< __tracepoint_ $name >],  | 
 | 24 | +                            $crate::bindings::tracepoint,  | 
 | 25 | +                            key  | 
 | 26 | +                        )  | 
 | 27 | +                    }  | 
 | 28 | +                };  | 
 | 29 | + | 
 | 30 | +                if should_trace {  | 
 | 31 | +                    // TODO: cpu_online(raw_smp_processor_id())  | 
 | 32 | +                    let cond = true;  | 
 | 33 | +                    $crate::tracepoint::do_trace!($name($($argname : $argtyp),*), cond);  | 
 | 34 | +                }  | 
 | 35 | +            }  | 
 | 36 | + | 
 | 37 | +            #[cfg(not(CONFIG_TRACEPOINTS))]  | 
 | 38 | +            {  | 
 | 39 | +                // If tracepoints are disabled, insert a trivial use of each argument  | 
 | 40 | +                // to avoid unused argument warnings.  | 
 | 41 | +                $( let _unused = $argname; )*  | 
 | 42 | +            }  | 
 | 43 | +        }  | 
 | 44 | +    )*}  | 
 | 45 | +}  | 
 | 46 | + | 
 | 47 | +#[doc(hidden)]  | 
 | 48 | +#[macro_export]  | 
 | 49 | +macro_rules! do_trace {  | 
 | 50 | +    ($name:ident($($argname:ident : $argtyp:ty),* $(,)?), $cond:expr) => {{  | 
 | 51 | +        if !$cond {  | 
 | 52 | +            return;  | 
 | 53 | +        }  | 
 | 54 | + | 
 | 55 | +        // SAFETY: This call is balanced with the call below.  | 
 | 56 | +        unsafe { $crate::bindings::preempt_disable_notrace() };  | 
 | 57 | + | 
 | 58 | +        // SAFETY: This calls the tracepoint with the provided arguments. The caller of the Rust  | 
 | 59 | +        // wrapper guarantees that this is okay.  | 
 | 60 | +        #[cfg(CONFIG_HAVE_STATIC_CALL)]  | 
 | 61 | +        unsafe {  | 
 | 62 | +            let it_func_ptr: *mut $crate::bindings::tracepoint_func =  | 
 | 63 | +                $crate::bindings::rcu_dereference_raw(  | 
 | 64 | +                    ::core::ptr::addr_of!(  | 
 | 65 | +                        $crate::macros::concat_idents!(__tracepoint_, $name).funcs  | 
 | 66 | +                    )  | 
 | 67 | +                );  | 
 | 68 | + | 
 | 69 | +            if !it_func_ptr.is_null() {  | 
 | 70 | +                let __data = (*it_func_ptr).data;  | 
 | 71 | +                $crate::macros::paste! {  | 
 | 72 | +                    $crate::static_call::static_call! {  | 
 | 73 | +                        [< tp_func_ $name >] (__data, $($argname),*)  | 
 | 74 | +                    };  | 
 | 75 | +                }  | 
 | 76 | +            }  | 
 | 77 | +        }  | 
 | 78 | + | 
 | 79 | +        // SAFETY: This calls the tracepoint with the provided arguments. The caller of the Rust  | 
 | 80 | +        // wrapper guarantees that this is okay.  | 
 | 81 | +        #[cfg(not(CONFIG_HAVE_STATIC_CALL))]  | 
 | 82 | +        unsafe {  | 
 | 83 | +            $crate::macros::concat_idents!(__traceiter_, $name)(  | 
 | 84 | +                ::core::ptr::null_mut(),  | 
 | 85 | +                $($argname),*  | 
 | 86 | +            );  | 
 | 87 | +        }  | 
 | 88 | + | 
 | 89 | +        // SAFETY: This call is balanced with the call above.  | 
 | 90 | +        unsafe { $crate::bindings::preempt_enable_notrace() };  | 
 | 91 | +    }}  | 
 | 92 | +}  | 
 | 93 | + | 
 | 94 | +pub use {declare_trace, do_trace};  | 
0 commit comments