Skip to content

Commit 9806f68

Browse files
committed
add retained flag to notes, allowing us to inline and monomorphise again
1 parent 21df298 commit 9806f68

File tree

2 files changed

+44
-98
lines changed

2 files changed

+44
-98
lines changed

tokio/src/util/usdt/macos.rs

Lines changed: 3 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -83,61 +83,31 @@ pub(super) fn task_start(task_id: u64, spawned: u8, size: usize, original_size:
8383
#[inline(always)]
8484
pub(super) fn task_poll_start(task_id: u64) {
8585
extern "C" {
86-
#[link_name = "__dtrace_isenabled$tokio$task__poll__start$v1"]
87-
fn task_poll_start_enabled() -> i32;
88-
8986
#[link_name = "__dtrace_probe$tokio$task__poll__start$v1$75696e7436345f74"]
9087
fn __task_poll_start(task_id: core::ffi::c_ulonglong);
9188
}
9289

93-
#[inline(never)]
94-
fn probe_inner(task_id: u64) {
95-
unsafe { __task_poll_start(task_id) }
96-
}
97-
98-
if unsafe { task_poll_start_enabled() } != 0 {
99-
probe_inner(task_id);
100-
}
90+
unsafe { __task_poll_start(task_id) }
10191
}
10292

10393
#[inline(always)]
10494
pub(super) fn task_poll_end(task_id: u64) {
10595
extern "C" {
106-
#[link_name = "__dtrace_isenabled$tokio$task__poll__end$v1"]
107-
fn task_poll_end_enabled() -> i32;
108-
10996
#[link_name = "__dtrace_probe$tokio$task__poll__end$v1$75696e7436345f74"]
11097
fn __task_poll_end(task_id: core::ffi::c_ulonglong);
11198
}
11299

113-
#[inline(never)]
114-
fn probe_inner(task_id: u64) {
115-
unsafe { __task_poll_end(task_id) }
116-
}
117-
118-
if unsafe { task_poll_end_enabled() } != 0 {
119-
probe_inner(task_id);
120-
}
100+
unsafe { __task_poll_end(task_id) }
121101
}
122102

123103
#[inline(always)]
124104
pub(crate) fn task_terminate(task_id: u64, reason: u8) {
125105
extern "C" {
126-
#[link_name = "__dtrace_isenabled$tokio$task__terminate$v1"]
127-
fn task_terminate_enabled() -> i32;
128-
129106
#[link_name = "__dtrace_probe$tokio$task__terminate$v1$75696e7436345f74$75696e74385f74"]
130107
fn __task_terminate(task_id: core::ffi::c_ulonglong, reason: core::ffi::c_uchar);
131108
}
132109

133-
#[inline(never)]
134-
fn probe_inner(task_id: u64, reason: u8) {
135-
unsafe { __task_terminate(task_id, reason) }
136-
}
137-
138-
if unsafe { task_terminate_enabled() } != 0 {
139-
probe_inner(task_id, reason);
140-
}
110+
unsafe { __task_terminate(task_id, reason) }
141111
}
142112

143113
#[inline(always)]

tokio/src/util/usdt/stapsdt.rs

Lines changed: 41 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,6 @@
2424
//! into a seperate function and marking it as `#[cold]` or `#[inline(never)]`.
2525
//! This ensures the hot path (probe is disabled) doesn't need to skip over a large
2626
//! number of instructions, and the branch predictor can make better predictions.
27-
//!
28-
//! ## Avoid monomorphisation
29-
//!
30-
//! We also use semaphores to ensure that probe callsites are **NOT** monomorphised.
31-
//! When a probe is monomorphised in many callsites, it has been observed to
32-
//! produce weird results after linking where the probe addresses are not correct.
33-
//!
34-
//! Be very mindful of the above when you add a probe.
3527
3628
#[cfg(target_arch = "x86_64")]
3729
macro_rules! call_probe {
@@ -42,9 +34,16 @@ macro_rules! call_probe {
4234
$($args:tt)*
4335
) => {
4436
// <https://sourceware.org/systemtap/wiki/UserSpaceProbeImplementation>
37+
// <https://github.com/cdkey/systemtap/blob/cbb34b7244ba60cb0904d61dc9167290855106aa/includes/sys/sdt.h#L240-L254>
38+
//
39+
// The `R` here means "retained". It prevents the linker from GC the note.
40+
// This additionally means that the function containing the `nop` is also not GCd.
41+
//
42+
// This is not great, but without this we get notes that are not GCd but the functions
43+
// they reference are GCd. This causes notes to have incorrect addresses.
4544
std::arch::asm!(
4645
"990: nop
47-
.pushsection .note.stapsdt, \"\", \"note\"
46+
.pushsection .note.stapsdt, \"R\", \"note\"
4847
.balign 4
4948
.4byte 992f-991f, 994f-993f, 3
5049
991:
@@ -76,9 +75,16 @@ macro_rules! call_probe {
7675
$($args:tt)*
7776
) => {
7877
// <https://sourceware.org/systemtap/wiki/UserSpaceProbeImplementation>
78+
// <https://github.com/cdkey/systemtap/blob/cbb34b7244ba60cb0904d61dc9167290855106aa/includes/sys/sdt.h#L240-L254>
79+
//
80+
// The `R` here means "retained". It prevents the linker from GC the note.
81+
// This additionally means that the function containing the `nop` is also not GCd.
82+
//
83+
// This is not great, but without this we get notes that are not GCd but the functions
84+
// they reference are GCd. This causes notes to have incorrect addresses.
7985
std::arch::asm!(
8086
"990: nop
81-
.pushsection .note.stapsdt, \"\", \"note\"
87+
.pushsection .note.stapsdt, \"R\", \"note\"
8288
.balign 4
8389
.4byte 992f-991f, 994f-993f, 3
8490
991:
@@ -171,73 +177,43 @@ pub(super) fn task_start(task_id: u64, kind: u8, size: usize, original_size: usi
171177
}
172178
}
173179

174-
declare_semaphore!(__usdt_sema_tokio_task__poll__start);
175-
176180
#[inline(always)]
177181
pub(super) fn task_poll_start(task_id: u64) {
178-
// `inline(never)` since poll_start probes are monomorphised otherwise
179-
#[inline(never)]
180-
fn probe_inner(task_id: u64) {
181-
unsafe {
182-
call_probe!(
183-
"task-poll-start",
184-
x86_64: "8@{task_id:r}",
185-
aarch64: "8@{task_id}",
186-
semaphore = sym __usdt_sema_tokio_task__poll__start,
187-
task_id = in(reg) task_id,
188-
);
189-
}
190-
}
191-
192-
if unsafe { __usdt_sema_tokio_task__poll__start } != 0 {
193-
probe_inner(task_id);
182+
unsafe {
183+
call_probe!(
184+
"task-poll-start",
185+
x86_64: "8@{task_id:r}",
186+
aarch64: "8@{task_id}",
187+
semaphore = const 0,
188+
task_id = in(reg) task_id,
189+
);
194190
}
195191
}
196192

197-
declare_semaphore!(__usdt_sema_tokio_task__poll__end);
198-
199193
#[inline(always)]
200194
pub(super) fn task_poll_end(task_id: u64) {
201-
// `inline(never)` since poll_end probes are monomorphised otherwise
202-
#[inline(never)]
203-
fn probe_inner(task_id: u64) {
204-
unsafe {
205-
call_probe!(
206-
"task-poll-end",
207-
x86_64: "8@{task_id:r}",
208-
aarch64: "8@{task_id}",
209-
semaphore = sym __usdt_sema_tokio_task__poll__end,
210-
task_id = in(reg) task_id,
211-
);
212-
}
213-
}
214-
215-
if unsafe { __usdt_sema_tokio_task__poll__end } != 0 {
216-
probe_inner(task_id);
195+
unsafe {
196+
call_probe!(
197+
"task-poll-end",
198+
x86_64: "8@{task_id:r}",
199+
aarch64: "8@{task_id}",
200+
semaphore = const 0,
201+
task_id = in(reg) task_id,
202+
);
217203
}
218204
}
219205

220-
declare_semaphore!(__usdt_sema_tokio_task__terminate);
221-
222206
#[inline(always)]
223207
pub(super) fn task_terminate(task_id: u64, reason: u8) {
224-
// `inline(never)` since terminate probes are monomorphised otherwise
225-
#[inline(never)]
226-
fn probe_inner(task_id: u64, reason: u8) {
227-
unsafe {
228-
call_probe!(
229-
"task-terminate",
230-
x86_64: "8@{task_id:r} 1@{reason:l}",
231-
aarch64: "8@{task_id} 1@{reason:w}",
232-
semaphore = sym __usdt_sema_tokio_task__terminate,
233-
task_id = in(reg) task_id,
234-
reason = in(reg) reason as u32,
235-
);
236-
}
237-
}
238-
239-
if unsafe { __usdt_sema_tokio_task__terminate } != 0 {
240-
probe_inner(task_id, reason);
208+
unsafe {
209+
call_probe!(
210+
"task-terminate",
211+
x86_64: "8@{task_id:r} 1@{reason:l}",
212+
aarch64: "8@{task_id} 1@{reason:w}",
213+
semaphore = const 0,
214+
task_id = in(reg) task_id,
215+
reason = in(reg) reason as u32,
216+
);
241217
}
242218
}
243219

0 commit comments

Comments
 (0)