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