Skip to content

Commit a528226

Browse files
committed
rust: add tracepoint support
Make it possible to have Rust code call into tracepoints defined by C code. It is still required that the tracepoint is declared in a C header, and that this header is included in the input to bindgen. Signed-off-by: Alice Ryhl <[email protected]>
1 parent c3ded95 commit a528226

File tree

3 files changed

+82
-0
lines changed

3 files changed

+82
-0
lines changed

Diff for: rust/bindings/bindings_helper.h

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include <linux/refcount.h>
1616
#include <linux/sched.h>
1717
#include <linux/slab.h>
18+
#include <linux/tracepoint.h>
1819
#include <linux/wait.h>
1920
#include <linux/workqueue.h>
2021

Diff for: rust/kernel/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ pub mod str;
4848
pub mod sync;
4949
pub mod task;
5050
pub mod time;
51+
pub mod tracepoint;
5152
pub mod types;
5253
pub mod workqueue;
5354

Diff for: rust/kernel/tracepoint.rs

+80
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
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+
$crate::macros::paste! {
12+
$( #[$attr] )*
13+
#[inline(always)]
14+
$pub fn [< trace_ $name >]($($argname : $argtyp),*) {
15+
#[cfg(CONFIG_TRACEPOINTS)]
16+
{
17+
use $crate::bindings::*;
18+
19+
let should_trace = unsafe {
20+
$crate::static_key::static_key_false!(
21+
[< __tracepoint_ $name >],
22+
$crate::bindings::tracepoint,
23+
key
24+
)
25+
};
26+
27+
if should_trace {
28+
// TODO: cpu_online(raw_smp_processor_id())
29+
let cond = true;
30+
$crate::tracepoint::do_trace!($name($($argname : $argtyp),*), cond);
31+
}
32+
}
33+
}
34+
}
35+
}
36+
}
37+
38+
#[doc(hidden)]
39+
#[macro_export]
40+
macro_rules! do_trace {
41+
($name:ident($($argname:ident : $argtyp:ty),* $(,)?), $cond:expr) => {{
42+
if !$cond {
43+
return;
44+
}
45+
46+
// SAFETY: This call is balanced with the call below.
47+
unsafe { $crate::bindings::preempt_disable_notrace() };
48+
49+
#[cfg(CONFIG_HAVE_STATIC_CALL)]
50+
unsafe {
51+
let it_func_ptr: *mut $crate::bindings::tracepoint_func =
52+
$crate::bindings::rcu_dereference_raw(
53+
::core::ptr::addr_of!(
54+
$crate::macros::concat_idents!(__tracepoint_, $name).funcs
55+
)
56+
);
57+
58+
if !it_func_ptr.is_null() {
59+
let __data = (*it_func_ptr).data;
60+
$crate::macros::paste! {
61+
$crate::static_call::static_call! {
62+
[< tp_func_ $name >] (__data, $($argname),*)
63+
};
64+
}
65+
}
66+
}
67+
68+
#[cfg(not(CONFIG_HAVE_STATIC_CALL))]
69+
unsafe {
70+
$crate::macros::concat_idents!(__traceiter_, $name)(
71+
::core::ptr::null_mut(),
72+
$($argname),*
73+
);
74+
}
75+
76+
unsafe { $crate::bindings::preempt_enable_notrace() };
77+
}}
78+
}
79+
80+
pub use {declare_trace, do_trace};

0 commit comments

Comments
 (0)