diff options
Diffstat (limited to 'include/linux/tracepoint.h')
| -rw-r--r-- | include/linux/tracepoint.h | 28 | 
1 files changed, 21 insertions, 7 deletions
| diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h index df0a779c1bbd..bd96ecd0e05c 100644 --- a/include/linux/tracepoint.h +++ b/include/linux/tracepoint.h @@ -17,7 +17,7 @@  #include <linux/errno.h>  #include <linux/types.h>  #include <linux/rcupdate.h> -#include <linux/jump_label.h> +#include <linux/static_key.h>  struct module;  struct tracepoint; @@ -29,7 +29,7 @@ struct tracepoint_func {  struct tracepoint {  	const char *name;		/* Tracepoint name */ -	struct jump_label_key key; +	struct static_key key;  	void (*regfunc)(void);  	void (*unregfunc)(void);  	struct tracepoint_func __rcu *funcs; @@ -114,7 +114,7 @@ static inline void tracepoint_synchronize_unregister(void)   * as "(void *, void)". The DECLARE_TRACE_NOARGS() will pass in just   * "void *data", where as the DECLARE_TRACE() will pass in "void *data, proto".   */ -#define __DO_TRACE(tp, proto, args, cond)				\ +#define __DO_TRACE(tp, proto, args, cond, prercu, postrcu)		\  	do {								\  		struct tracepoint_func *it_func_ptr;			\  		void *it_func;						\ @@ -122,6 +122,7 @@ static inline void tracepoint_synchronize_unregister(void)  									\  		if (!(cond))						\  			return;						\ +		prercu;							\  		rcu_read_lock_sched_notrace();				\  		it_func_ptr = rcu_dereference_sched((tp)->funcs);	\  		if (it_func_ptr) {					\ @@ -132,6 +133,7 @@ static inline void tracepoint_synchronize_unregister(void)  			} while ((++it_func_ptr)->func);		\  		}							\  		rcu_read_unlock_sched_notrace();			\ +		postrcu;						\  	} while (0)  /* @@ -139,15 +141,25 @@ static inline void tracepoint_synchronize_unregister(void)   * not add unwanted padding between the beginning of the section and the   * structure. Force alignment to the same alignment as the section start.   */ -#define __DECLARE_TRACE(name, proto, args, cond, data_proto, data_args)	\ +#define __DECLARE_TRACE(name, proto, args, cond, data_proto, data_args) \  	extern struct tracepoint __tracepoint_##name;			\  	static inline void trace_##name(proto)				\  	{								\ +		if (static_key_false(&__tracepoint_##name.key))		\ +			__DO_TRACE(&__tracepoint_##name,		\ +				TP_PROTO(data_proto),			\ +				TP_ARGS(data_args),			\ +				TP_CONDITION(cond),,);			\ +	}								\ +	static inline void trace_##name##_rcuidle(proto)		\ +	{								\  		if (static_branch(&__tracepoint_##name.key))		\  			__DO_TRACE(&__tracepoint_##name,		\  				TP_PROTO(data_proto),			\  				TP_ARGS(data_args),			\ -				TP_CONDITION(cond));			\ +				TP_CONDITION(cond),			\ +				rcu_idle_exit(),			\ +				rcu_idle_enter());			\  	}								\  	static inline int						\  	register_trace_##name(void (*probe)(data_proto), void *data)	\ @@ -176,7 +188,7 @@ static inline void tracepoint_synchronize_unregister(void)  	__attribute__((section("__tracepoints_strings"))) = #name;	 \  	struct tracepoint __tracepoint_##name				 \  	__attribute__((section("__tracepoints"))) =			 \ -		{ __tpstrtab_##name, JUMP_LABEL_INIT, reg, unreg, NULL };\ +		{ __tpstrtab_##name, STATIC_KEY_INIT_FALSE, reg, unreg, NULL };\  	static struct tracepoint * const __tracepoint_ptr_##name __used	 \  	__attribute__((section("__tracepoints_ptrs"))) =		 \  		&__tracepoint_##name; @@ -190,9 +202,11 @@ static inline void tracepoint_synchronize_unregister(void)  	EXPORT_SYMBOL(__tracepoint_##name)  #else /* !CONFIG_TRACEPOINTS */ -#define __DECLARE_TRACE(name, proto, args, cond, data_proto, data_args)	\ +#define __DECLARE_TRACE(name, proto, args, cond, data_proto, data_args) \  	static inline void trace_##name(proto)				\  	{ }								\ +	static inline void trace_##name##_rcuidle(proto)		\ +	{ }								\  	static inline int						\  	register_trace_##name(void (*probe)(data_proto),		\  			      void *data)				\ | 
