#ifndef _KLP_TRACE_H #define _KLP_TRACE_H #include #include /* * Since kernel 5.12, the data_args was removed from __DECLARE_TRACE. * Since kernel 5.10, the __tracepoint_iter_ symbols were renamed to * __traceiter_ in order to have shorter symbol names. * As we currently support kernels from 5.3 and then 5.14, we don't need special * ifdefery for kernel 5.10. */ #if LINUX_VERSION_CODE < KERNEL_VERSION(5, 12, 0) #define KLPR___DECLARE_TRACE(name, proto, args, cond, data_proto, data_args) \ static struct tracepoint (*klpe___tracepoint_##name); \ static inline void klpr_trace_##name(proto) \ { \ if (unlikely(static_key_enabled(&(*klpe___tracepoint_##name).key))) \ __DO_TRACE(&(*klpe___tracepoint_##name), \ TP_PROTO(data_proto), \ TP_ARGS(data_args), \ TP_CONDITION(cond), 0); \ if (IS_ENABLED(CONFIG_LOCKDEP) && (cond)) { \ rcu_read_lock_sched_notrace(); \ rcu_dereference_sched((*klpe___tracepoint_##name).funcs); \ rcu_read_unlock_sched_notrace(); \ } \ } \ #define KLPR_DECLARE_TRACE(name, proto, args) \ KLPR___DECLARE_TRACE(name, PARAMS(proto), PARAMS(args), \ cpu_online(raw_smp_processor_id()), \ PARAMS(void *__data, proto), \ PARAMS(__data, args)) #else /* LINUX_VERSION_CODE < KERNEL_VERSION(5, 12, 0) */ #define KLPR___DO_TRACE_CALL(name, args) (*klpe___traceiter_##name)(NULL, args) #define KLPR___DO_TRACE(name, args, cond, rcuidle) \ do { \ int __maybe_unused __idx = 0; \ \ if (!(cond)) \ return; \ \ /* srcu can't be used from NMI */ \ WARN_ON_ONCE(rcuidle && in_nmi()); \ \ /* keep srcu and sched-rcu usage consistent */ \ preempt_disable_notrace(); \ \ /* \ * For rcuidle callers, use srcu since sched-rcu \ * doesn't work from the idle path. \ */ \ if (rcuidle) { \ __idx = srcu_read_lock_notrace(&tracepoint_srcu);\ rcu_irq_enter_irqson(); \ } \ \ KLPR___DO_TRACE_CALL(name, TP_ARGS(args)); \ \ if (rcuidle) { \ rcu_irq_exit_irqson(); \ srcu_read_unlock_notrace(&tracepoint_srcu, __idx);\ } \ \ preempt_enable_notrace(); \ } while (0) #define KLPR___DECLARE_TRACE(name, proto, args, cond, data_proto) \ static int (*klpe___traceiter_##name)(data_proto); \ static struct tracepoint (*klpe___tracepoint_##name); \ static inline void klpr_trace_##name(proto) \ { \ if (static_key_enabled(&(*klpe___tracepoint_##name).key)) \ KLPR___DO_TRACE(name, \ TP_ARGS(args), \ TP_CONDITION(cond), 0); \ if (IS_ENABLED(CONFIG_LOCKDEP) && (cond)) { \ rcu_read_lock_sched_notrace(); \ rcu_dereference_sched((*klpe___tracepoint_##name).funcs);\ rcu_read_unlock_sched_notrace(); \ } \ } \ #define KLPR_DECLARE_TRACE(name, proto, args) \ KLPR___DECLARE_TRACE(name, PARAMS(proto), PARAMS(args), \ cpu_online(raw_smp_processor_id()), \ PARAMS(void *__data, proto)) #endif /* LINUX_VERSION_CODE < KERNEL_VERSION(5, 12, 0) */ #define KLPR_TRACE_EVENT(name, proto, args) \ KLPR_DECLARE_TRACE(name, PARAMS(proto), PARAMS(args)) #endif /* _KLP_TRACE_H */