On Fri, Jun 21, 2024 at 12:35 PM Alice Ryhl <alicer...@google.com> wrote: > > 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 <alicer...@google.com> > --- > include/linux/tracepoint.h | 18 +++++++++++++++- > include/trace/define_trace.h | 7 ++++++ > rust/bindings/bindings_helper.h | 1 + > rust/kernel/lib.rs | 1 + > rust/kernel/tracepoint.rs | 47 > +++++++++++++++++++++++++++++++++++++++++ > 5 files changed, 73 insertions(+), 1 deletion(-) > > diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h > index 689b6d71590e..d82af4d77c9f 100644 > --- a/include/linux/tracepoint.h > +++ b/include/linux/tracepoint.h > @@ -238,6 +238,20 @@ static inline struct tracepoint > *tracepoint_ptr_deref(tracepoint_ptr_t *p) > #define __DECLARE_TRACE_RCU(name, proto, args, cond) > #endif > > +/* > + * Declare an exported function that Rust code can call to trigger this > + * tracepoint. This function does not include the static branch; that is done > + * in Rust to avoid a function call when the tracepoint is disabled. > + */ > +#define DEFINE_RUST_DO_TRACE(name, proto, args) > +#define DEFINE_RUST_DO_TRACE_REAL(name, proto, args) \ > + notrace void rust_do_trace_##name(proto) \ > + { \ > + __DO_TRACE(name, \ > + TP_ARGS(args), \ > + cpu_online(raw_smp_processor_id()), 0); \ > + } > + > /* > * Make sure the alignment of the structure in the __tracepoints section will > * not add unwanted padding between the beginning of the section and the > @@ -253,6 +267,7 @@ static inline struct tracepoint > *tracepoint_ptr_deref(tracepoint_ptr_t *p) > extern int __traceiter_##name(data_proto); \ > DECLARE_STATIC_CALL(tp_func_##name, __traceiter_##name); \ > extern struct tracepoint __tracepoint_##name; \ > + extern void rust_do_trace_##name(proto); \ > static inline void trace_##name(proto) \ > { \ > if (static_key_false(&__tracepoint_##name.key)) \ > @@ -337,7 +352,8 @@ static inline struct tracepoint > *tracepoint_ptr_deref(tracepoint_ptr_t *p) > void __probestub_##_name(void *__data, proto) \ > { \ > } \ > - DEFINE_STATIC_CALL(tp_func_##_name, __traceiter_##_name); > + DEFINE_STATIC_CALL(tp_func_##_name, __traceiter_##_name); \ > + DEFINE_RUST_DO_TRACE(_name, TP_PROTO(proto), TP_ARGS(args)) > > #define DEFINE_TRACE(name, proto, args) \ > DEFINE_TRACE_FN(name, NULL, NULL, PARAMS(proto), PARAMS(args)); > diff --git a/include/trace/define_trace.h b/include/trace/define_trace.h > index 00723935dcc7..b47cc036acba 100644 > --- a/include/trace/define_trace.h > +++ b/include/trace/define_trace.h > @@ -72,6 +72,13 @@ > #define DECLARE_TRACE(name, proto, args) \ > DEFINE_TRACE(name, PARAMS(proto), PARAMS(args)) > > +/* If requested, create helpers for calling these tracepoints from Rust. */ > +#ifdef CREATE_RUST_TRACE_POINTS > +#undef DEFINE_RUST_DO_TRACE > +#define DEFINE_RUST_DO_TRACE(name, proto, args) \ > + DEFINE_RUST_DO_TRACE_REAL(name, PARAMS(proto), PARAMS(args)) > +#endif > + > #undef TRACE_INCLUDE > #undef __TRACE_INCLUDE > > diff --git a/rust/bindings/bindings_helper.h b/rust/bindings/bindings_helper.h
Hmm, I tried using the support where I have both events and hooks: #define CREATE_TRACE_POINTS #define CREATE_RUST_TRACE_POINTS #include <trace/hooks/rust_binder.h> #include <trace/events/rust_binder.h> But it's not really working. Initially I thought that it's because I need to undef DEFINE_RUST_DO_TRACE at the end of this file, but even when I added that, I still get this error: error: redefinition of 'str__rust_binder__trace_system_name' Is the Rust support missing something, or is the answer just that you can't have two files of the same name like this? Or am I doing something else wrong? Alice