Skip to content

Commit 7f4f3b1

Browse files
committed
Merge tag 'trace-rust-v6.13' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace
Pull rust trace event support from Steven Rostedt: "Allow Rust code to have trace events Trace events is a popular way to debug what is happening inside the kernel or just to find out what is happening. Rust code is being added to the Linux kernel but it currently does not support the tracing infrastructure. Add support of trace events inside Rust code" * tag 'trace-rust-v6.13' of git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace: rust: jump_label: skip formatting generated file jump_label: rust: pass a mut ptr to `static_key_count` samples: rust: fix `rust_print` build making it a combined module rust: add arch_static_branch jump_label: adjust inline asm to be consistent rust: samples: add tracepoint to Rust sample rust: add tracepoint support rust: add static_branch_unlikely for static_key_false
2 parents 36843bf + 8af7a50 commit 7f4f3b1

File tree

22 files changed

+375
-64
lines changed

22 files changed

+375
-64
lines changed

MAINTAINERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20348,6 +20348,7 @@ C: zulip://rust-for-linux.zulipchat.com
2034820348
P: https://rust-for-linux.com/contributing
2034920349
T: git https://github.com/Rust-for-Linux/linux.git rust-next
2035020350
F: Documentation/rust/
20351+
F: include/trace/events/rust_sample.h
2035120352
F: rust/
2035220353
F: samples/rust/
2035320354
F: scripts/*rust*

arch/arm/include/asm/jump_label.h

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,17 @@
99

1010
#define JUMP_LABEL_NOP_SIZE 4
1111

12+
/* This macro is also expanded on the Rust side. */
13+
#define ARCH_STATIC_BRANCH_ASM(key, label) \
14+
"1:\n\t" \
15+
WASM(nop) "\n\t" \
16+
".pushsection __jump_table, \"aw\"\n\t" \
17+
".word 1b, " label ", " key "\n\t" \
18+
".popsection\n\t" \
19+
1220
static __always_inline bool arch_static_branch(struct static_key *key, bool branch)
1321
{
14-
asm goto("1:\n\t"
15-
WASM(nop) "\n\t"
16-
".pushsection __jump_table, \"aw\"\n\t"
17-
".word 1b, %l[l_yes], %c0\n\t"
18-
".popsection\n\t"
22+
asm goto(ARCH_STATIC_BRANCH_ASM("%c0", "%l[l_yes]")
1923
: : "i" (&((char *)key)[branch]) : : l_yes);
2024

2125
return false;

arch/arm64/include/asm/jump_label.h

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,19 +19,23 @@
1919
#define JUMP_TABLE_ENTRY(key, label) \
2020
".pushsection __jump_table, \"aw\"\n\t" \
2121
".align 3\n\t" \
22-
".long 1b - ., %l["#label"] - .\n\t" \
23-
".quad %c0 - .\n\t" \
24-
".popsection\n\t" \
25-
: : "i"(key) : : label
22+
".long 1b - ., " label " - .\n\t" \
23+
".quad " key " - .\n\t" \
24+
".popsection\n\t"
25+
26+
/* This macro is also expanded on the Rust side. */
27+
#define ARCH_STATIC_BRANCH_ASM(key, label) \
28+
"1: nop\n\t" \
29+
JUMP_TABLE_ENTRY(key, label)
2630

2731
static __always_inline bool arch_static_branch(struct static_key * const key,
2832
const bool branch)
2933
{
3034
char *k = &((char *)key)[branch];
3135

3236
asm goto(
33-
"1: nop \n\t"
34-
JUMP_TABLE_ENTRY(k, l_yes)
37+
ARCH_STATIC_BRANCH_ASM("%c0", "%l[l_yes]")
38+
: : "i"(k) : : l_yes
3539
);
3640

3741
return false;
@@ -43,9 +47,11 @@ static __always_inline bool arch_static_branch_jump(struct static_key * const ke
4347
const bool branch)
4448
{
4549
char *k = &((char *)key)[branch];
50+
4651
asm goto(
4752
"1: b %l[l_yes] \n\t"
48-
JUMP_TABLE_ENTRY(k, l_yes)
53+
JUMP_TABLE_ENTRY("%c0", "%l[l_yes]")
54+
: : "i"(k) : : l_yes
4955
);
5056
return false;
5157
l_yes:

arch/loongarch/include/asm/jump_label.h

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,22 @@
1313

1414
#define JUMP_LABEL_NOP_SIZE 4
1515

16-
#define JUMP_TABLE_ENTRY \
16+
/* This macro is also expanded on the Rust side. */
17+
#define JUMP_TABLE_ENTRY(key, label) \
1718
".pushsection __jump_table, \"aw\" \n\t" \
1819
".align 3 \n\t" \
19-
".long 1b - ., %l[l_yes] - . \n\t" \
20-
".quad %0 - . \n\t" \
20+
".long 1b - ., " label " - . \n\t" \
21+
".quad " key " - . \n\t" \
2122
".popsection \n\t"
2223

24+
#define ARCH_STATIC_BRANCH_ASM(key, label) \
25+
"1: nop \n\t" \
26+
JUMP_TABLE_ENTRY(key, label)
27+
2328
static __always_inline bool arch_static_branch(struct static_key * const key, const bool branch)
2429
{
2530
asm goto(
26-
"1: nop \n\t"
27-
JUMP_TABLE_ENTRY
31+
ARCH_STATIC_BRANCH_ASM("%0", "%l[l_yes]")
2832
: : "i"(&((char *)key)[branch]) : : l_yes);
2933

3034
return false;
@@ -37,7 +41,7 @@ static __always_inline bool arch_static_branch_jump(struct static_key * const ke
3741
{
3842
asm goto(
3943
"1: b %l[l_yes] \n\t"
40-
JUMP_TABLE_ENTRY
44+
JUMP_TABLE_ENTRY("%0", "%l[l_yes]")
4145
: : "i"(&((char *)key)[branch]) : : l_yes);
4246

4347
return false;

arch/riscv/include/asm/jump_label.h

Lines changed: 28 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -16,43 +16,49 @@
1616

1717
#define JUMP_LABEL_NOP_SIZE 4
1818

19+
#define JUMP_TABLE_ENTRY(key, label) \
20+
".pushsection __jump_table, \"aw\" \n\t" \
21+
".align " RISCV_LGPTR " \n\t" \
22+
".long 1b - ., " label " - . \n\t" \
23+
"" RISCV_PTR " " key " - . \n\t" \
24+
".popsection \n\t"
25+
26+
/* This macro is also expanded on the Rust side. */
27+
#define ARCH_STATIC_BRANCH_ASM(key, label) \
28+
" .align 2 \n\t" \
29+
" .option push \n\t" \
30+
" .option norelax \n\t" \
31+
" .option norvc \n\t" \
32+
"1: nop \n\t" \
33+
" .option pop \n\t" \
34+
JUMP_TABLE_ENTRY(key, label)
35+
1936
static __always_inline bool arch_static_branch(struct static_key * const key,
2037
const bool branch)
2138
{
2239
asm goto(
23-
" .align 2 \n\t"
24-
" .option push \n\t"
25-
" .option norelax \n\t"
26-
" .option norvc \n\t"
27-
"1: nop \n\t"
28-
" .option pop \n\t"
29-
" .pushsection __jump_table, \"aw\" \n\t"
30-
" .align " RISCV_LGPTR " \n\t"
31-
" .long 1b - ., %l[label] - . \n\t"
32-
" " RISCV_PTR " %0 - . \n\t"
33-
" .popsection \n\t"
40+
ARCH_STATIC_BRANCH_ASM("%0", "%l[label]")
3441
: : "i"(&((char *)key)[branch]) : : label);
3542

3643
return false;
3744
label:
3845
return true;
3946
}
4047

48+
#define ARCH_STATIC_BRANCH_JUMP_ASM(key, label) \
49+
" .align 2 \n\t" \
50+
" .option push \n\t" \
51+
" .option norelax \n\t" \
52+
" .option norvc \n\t" \
53+
"1: j " label " \n\t" \
54+
" .option pop \n\t" \
55+
JUMP_TABLE_ENTRY(key, label)
56+
4157
static __always_inline bool arch_static_branch_jump(struct static_key * const key,
4258
const bool branch)
4359
{
4460
asm goto(
45-
" .align 2 \n\t"
46-
" .option push \n\t"
47-
" .option norelax \n\t"
48-
" .option norvc \n\t"
49-
"1: j %l[label] \n\t"
50-
" .option pop \n\t"
51-
" .pushsection __jump_table, \"aw\" \n\t"
52-
" .align " RISCV_LGPTR " \n\t"
53-
" .long 1b - ., %l[label] - . \n\t"
54-
" " RISCV_PTR " %0 - . \n\t"
55-
" .popsection \n\t"
61+
ARCH_STATIC_BRANCH_JUMP_ASM("%0", "%l[label]")
5662
: : "i"(&((char *)key)[branch]) : : label);
5763

5864
return false;

arch/x86/include/asm/jump_label.h

Lines changed: 13 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -12,49 +12,40 @@
1212
#include <linux/stringify.h>
1313
#include <linux/types.h>
1414

15-
#define JUMP_TABLE_ENTRY \
15+
#define JUMP_TABLE_ENTRY(key, label) \
1616
".pushsection __jump_table, \"aw\" \n\t" \
1717
_ASM_ALIGN "\n\t" \
1818
".long 1b - . \n\t" \
19-
".long %l[l_yes] - . \n\t" \
20-
_ASM_PTR "%c0 + %c1 - .\n\t" \
19+
".long " label " - . \n\t" \
20+
_ASM_PTR " " key " - . \n\t" \
2121
".popsection \n\t"
2222

23+
/* This macro is also expanded on the Rust side. */
2324
#ifdef CONFIG_HAVE_JUMP_LABEL_HACK
24-
25-
static __always_inline bool arch_static_branch(struct static_key *key, bool branch)
26-
{
27-
asm goto("1:"
28-
"jmp %l[l_yes] # objtool NOPs this \n\t"
29-
JUMP_TABLE_ENTRY
30-
: : "i" (key), "i" (2 | branch) : : l_yes);
31-
32-
return false;
33-
l_yes:
34-
return true;
35-
}
36-
25+
#define ARCH_STATIC_BRANCH_ASM(key, label) \
26+
"1: jmp " label " # objtool NOPs this \n\t" \
27+
JUMP_TABLE_ENTRY(key " + 2", label)
3728
#else /* !CONFIG_HAVE_JUMP_LABEL_HACK */
29+
#define ARCH_STATIC_BRANCH_ASM(key, label) \
30+
"1: .byte " __stringify(BYTES_NOP5) "\n\t" \
31+
JUMP_TABLE_ENTRY(key, label)
32+
#endif /* CONFIG_HAVE_JUMP_LABEL_HACK */
3833

3934
static __always_inline bool arch_static_branch(struct static_key * const key, const bool branch)
4035
{
41-
asm goto("1:"
42-
".byte " __stringify(BYTES_NOP5) "\n\t"
43-
JUMP_TABLE_ENTRY
36+
asm goto(ARCH_STATIC_BRANCH_ASM("%c0 + %c1", "%l[l_yes]")
4437
: : "i" (key), "i" (branch) : : l_yes);
4538

4639
return false;
4740
l_yes:
4841
return true;
4942
}
5043

51-
#endif /* CONFIG_HAVE_JUMP_LABEL_HACK */
52-
5344
static __always_inline bool arch_static_branch_jump(struct static_key * const key, const bool branch)
5445
{
5546
asm goto("1:"
5647
"jmp %l[l_yes]\n\t"
57-
JUMP_TABLE_ENTRY
48+
JUMP_TABLE_ENTRY("%c0 + %c1", "%l[l_yes]")
5849
: : "i" (key), "i" (branch) : : l_yes);
5950

6051
return false;

include/linux/tracepoint.h

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,18 @@ static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p)
239239
preempt_enable_notrace(); \
240240
} while (0)
241241

242+
/*
243+
* Declare an exported function that Rust code can call to trigger this
244+
* tracepoint. This function does not include the static branch; that is done
245+
* in Rust to avoid a function call when the tracepoint is disabled.
246+
*/
247+
#define DEFINE_RUST_DO_TRACE(name, proto, args)
248+
#define __DEFINE_RUST_DO_TRACE(name, proto, args) \
249+
notrace void rust_do_trace_##name(proto) \
250+
{ \
251+
__rust_do_trace_##name(args); \
252+
}
253+
242254
/*
243255
* Make sure the alignment of the structure in the __tracepoints section will
244256
* not add unwanted padding between the beginning of the section and the
@@ -254,6 +266,7 @@ static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p)
254266
extern int __traceiter_##name(data_proto); \
255267
DECLARE_STATIC_CALL(tp_func_##name, __traceiter_##name); \
256268
extern struct tracepoint __tracepoint_##name; \
269+
extern void rust_do_trace_##name(proto); \
257270
static inline int \
258271
register_trace_##name(void (*probe)(data_proto), void *data) \
259272
{ \
@@ -285,6 +298,12 @@ static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p)
285298

286299
#define __DECLARE_TRACE(name, proto, args, cond, data_proto) \
287300
__DECLARE_TRACE_COMMON(name, PARAMS(proto), PARAMS(args), cond, PARAMS(data_proto)) \
301+
static inline void __rust_do_trace_##name(proto) \
302+
{ \
303+
__DO_TRACE(name, \
304+
TP_ARGS(args), \
305+
TP_CONDITION(cond), 0); \
306+
} \
288307
static inline void trace_##name(proto) \
289308
{ \
290309
if (static_branch_unlikely(&__tracepoint_##name.key)) \
@@ -299,6 +318,12 @@ static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p)
299318

300319
#define __DECLARE_TRACE_SYSCALL(name, proto, args, cond, data_proto) \
301320
__DECLARE_TRACE_COMMON(name, PARAMS(proto), PARAMS(args), cond, PARAMS(data_proto)) \
321+
static inline void __rust_do_trace_##name(proto) \
322+
{ \
323+
__DO_TRACE(name, \
324+
TP_ARGS(args), \
325+
TP_CONDITION(cond), 1); \
326+
} \
302327
static inline void trace_##name(proto) \
303328
{ \
304329
might_fault(); \
@@ -354,7 +379,8 @@ static inline struct tracepoint *tracepoint_ptr_deref(tracepoint_ptr_t *p)
354379
void __probestub_##_name(void *__data, proto) \
355380
{ \
356381
} \
357-
DEFINE_STATIC_CALL(tp_func_##_name, __traceiter_##_name);
382+
DEFINE_STATIC_CALL(tp_func_##_name, __traceiter_##_name); \
383+
DEFINE_RUST_DO_TRACE(_name, TP_PROTO(proto), TP_ARGS(args))
358384

359385
#define DEFINE_TRACE_FN(_name, _reg, _unreg, _proto, _args) \
360386
static struct tracepoint_ext __tracepoint_ext_##_name = { \

include/trace/define_trace.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,13 @@
7676
#define DECLARE_TRACE(name, proto, args) \
7777
DEFINE_TRACE(name, PARAMS(proto), PARAMS(args))
7878

79+
/* If requested, create helpers for calling these tracepoints from Rust. */
80+
#ifdef CREATE_RUST_TRACE_POINTS
81+
#undef DEFINE_RUST_DO_TRACE
82+
#define DEFINE_RUST_DO_TRACE(name, proto, args) \
83+
__DEFINE_RUST_DO_TRACE(name, PARAMS(proto), PARAMS(args))
84+
#endif
85+
7986
#undef TRACE_INCLUDE
8087
#undef __TRACE_INCLUDE
8188

@@ -134,6 +141,11 @@
134141
# undef UNDEF_TRACE_INCLUDE_PATH
135142
#endif
136143

144+
#ifdef CREATE_RUST_TRACE_POINTS
145+
# undef DEFINE_RUST_DO_TRACE
146+
# define DEFINE_RUST_DO_TRACE(name, proto, args)
147+
#endif
148+
137149
/* We may be processing more files */
138150
#define CREATE_TRACE_POINTS
139151

include/trace/events/rust_sample.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/* SPDX-License-Identifier: GPL-2.0-only */
2+
/*
3+
* Tracepoints for `samples/rust/rust_print.rs`.
4+
*
5+
* Copyright (C) 2024 Google, Inc.
6+
*/
7+
8+
#undef TRACE_SYSTEM
9+
#define TRACE_SYSTEM rust_sample
10+
11+
#if !defined(_RUST_SAMPLE_TRACE_H) || defined(TRACE_HEADER_MULTI_READ)
12+
#define _RUST_SAMPLE_TRACE_H
13+
14+
#include <linux/tracepoint.h>
15+
16+
TRACE_EVENT(rust_sample_loaded,
17+
TP_PROTO(int magic_number),
18+
TP_ARGS(magic_number),
19+
TP_STRUCT__entry(
20+
__field(int, magic_number)
21+
),
22+
TP_fast_assign(
23+
__entry->magic_number = magic_number;
24+
),
25+
TP_printk("magic=%d", __entry->magic_number)
26+
);
27+
28+
#endif /* _RUST_SAMPLE_TRACE_H */
29+
30+
/* This part must be outside protection */
31+
#include <trace/define_trace.h>

rust/Makefile

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ always-$(CONFIG_RUST_KERNEL_DOCTESTS) += doctests_kernel_generated_kunit.c
3636
obj-$(CONFIG_RUST_KERNEL_DOCTESTS) += doctests_kernel_generated.o
3737
obj-$(CONFIG_RUST_KERNEL_DOCTESTS) += doctests_kernel_generated_kunit.o
3838

39+
always-$(subst y,$(CONFIG_RUST),$(CONFIG_JUMP_LABEL)) += kernel/generated_arch_static_branch_asm.rs
40+
3941
# Avoids running `$(RUSTC)` for the sysroot when it may not be available.
4042
ifdef CONFIG_RUST
4143

@@ -424,4 +426,8 @@ $(obj)/kernel.o: $(src)/kernel/lib.rs $(obj)/alloc.o $(obj)/build_error.o \
424426
$(obj)/libmacros.so $(obj)/bindings.o $(obj)/uapi.o FORCE
425427
+$(call if_changed_rule,rustc_library)
426428

429+
ifdef CONFIG_JUMP_LABEL
430+
$(obj)/kernel.o: $(obj)/kernel/generated_arch_static_branch_asm.rs
431+
endif
432+
427433
endif # CONFIG_RUST

0 commit comments

Comments
 (0)