On Fri, 28 Jun 2024 13:23:32 +0000 Alice Ryhl <aliceryhl@xxxxxxxxxx> 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 <aliceryhl@xxxxxxxxxx> The Rust part LGTM. Some comment about the C part. > --- > include/linux/tracepoint.h | 18 +++++++++++++++- > include/trace/define_trace.h | 12 +++++++++++ > rust/bindings/bindings_helper.h | 1 + > rust/kernel/lib.rs | 1 + > rust/kernel/tracepoint.rs | 47 +++++++++++++++++++++++++++++++++++++++++ > 5 files changed, 78 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); \ I guess this doesn't support conditions. Currently the conditions are specified during declaration and not during definition. Would it make sense to have static inline void do_trace_##name(proto) { __DO_TRACE(name, TP_ARGS(args), TP_CONDITION(cond), 0); } in `__DECLARE_TRACE` and then simply call it in `rust_do_trace_##name`? > + } > + > /* > * 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..08ed5ce63a96 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 > > @@ -129,6 +136,11 @@ > # undef UNDEF_TRACE_INCLUDE_PATH > #endif > > +#ifdef CREATE_RUST_TRACE_POINTS > +# undef DEFINE_RUST_DO_TRACE > +# define DEFINE_RUST_DO_TRACE(name, proto, args) > +#endif > + > /* We may be processing more files */ > #define CREATE_TRACE_POINTS >