mirror of
				https://git.kernel.org/pub/scm/linux/kernel/git/chenhuacai/linux-loongson
				synced 2025-10-31 20:42:39 +00:00 
			
		
		
		
	 629928041c
			
		
	
	
		629928041c
		
	
	
	
	
		
			
			This patch utilizes the TRACE_EVENT_FORMAT macro to enable the C style faster tracing for the sched subsystem trace points. Signed-off-by: Steven Rostedt <srostedt@redhat.com>
		
			
				
	
	
		
			164 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			164 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| #ifndef _LINUX_TRACEPOINT_H
 | |
| #define _LINUX_TRACEPOINT_H
 | |
| 
 | |
| /*
 | |
|  * Kernel Tracepoint API.
 | |
|  *
 | |
|  * See Documentation/tracepoint.txt.
 | |
|  *
 | |
|  * (C) Copyright 2008 Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
 | |
|  *
 | |
|  * Heavily inspired from the Linux Kernel Markers.
 | |
|  *
 | |
|  * This file is released under the GPLv2.
 | |
|  * See the file COPYING for more details.
 | |
|  */
 | |
| 
 | |
| #include <linux/types.h>
 | |
| #include <linux/rcupdate.h>
 | |
| 
 | |
| struct module;
 | |
| struct tracepoint;
 | |
| 
 | |
| struct tracepoint {
 | |
| 	const char *name;		/* Tracepoint name */
 | |
| 	int state;			/* State. */
 | |
| 	void **funcs;
 | |
| } __attribute__((aligned(32)));		/*
 | |
| 					 * Aligned on 32 bytes because it is
 | |
| 					 * globally visible and gcc happily
 | |
| 					 * align these on the structure size.
 | |
| 					 * Keep in sync with vmlinux.lds.h.
 | |
| 					 */
 | |
| 
 | |
| #define TPPROTO(args...)	args
 | |
| #define TPARGS(args...)		args
 | |
| 
 | |
| #ifdef CONFIG_TRACEPOINTS
 | |
| 
 | |
| /*
 | |
|  * it_func[0] is never NULL because there is at least one element in the array
 | |
|  * when the array itself is non NULL.
 | |
|  */
 | |
| #define __DO_TRACE(tp, proto, args)					\
 | |
| 	do {								\
 | |
| 		void **it_func;						\
 | |
| 									\
 | |
| 		rcu_read_lock_sched_notrace();				\
 | |
| 		it_func = rcu_dereference((tp)->funcs);			\
 | |
| 		if (it_func) {						\
 | |
| 			do {						\
 | |
| 				((void(*)(proto))(*it_func))(args);	\
 | |
| 			} while (*(++it_func));				\
 | |
| 		}							\
 | |
| 		rcu_read_unlock_sched_notrace();			\
 | |
| 	} while (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
 | |
|  * structure. Force alignment to the same alignment as the section start.
 | |
|  */
 | |
| #define DECLARE_TRACE(name, proto, args)				\
 | |
| 	extern struct tracepoint __tracepoint_##name;			\
 | |
| 	static inline void trace_##name(proto)				\
 | |
| 	{								\
 | |
| 		if (unlikely(__tracepoint_##name.state))		\
 | |
| 			__DO_TRACE(&__tracepoint_##name,		\
 | |
| 				TPPROTO(proto), TPARGS(args));		\
 | |
| 	}								\
 | |
| 	static inline int register_trace_##name(void (*probe)(proto))	\
 | |
| 	{								\
 | |
| 		return tracepoint_probe_register(#name, (void *)probe);	\
 | |
| 	}								\
 | |
| 	static inline int unregister_trace_##name(void (*probe)(proto))	\
 | |
| 	{								\
 | |
| 		return tracepoint_probe_unregister(#name, (void *)probe);\
 | |
| 	}
 | |
| 
 | |
| #define DEFINE_TRACE(name)						\
 | |
| 	static const char __tpstrtab_##name[]				\
 | |
| 	__attribute__((section("__tracepoints_strings"))) = #name;	\
 | |
| 	struct tracepoint __tracepoint_##name				\
 | |
| 	__attribute__((section("__tracepoints"), aligned(32))) =	\
 | |
| 		{ __tpstrtab_##name, 0, NULL }
 | |
| 
 | |
| #define EXPORT_TRACEPOINT_SYMBOL_GPL(name)				\
 | |
| 	EXPORT_SYMBOL_GPL(__tracepoint_##name)
 | |
| #define EXPORT_TRACEPOINT_SYMBOL(name)					\
 | |
| 	EXPORT_SYMBOL(__tracepoint_##name)
 | |
| 
 | |
| extern void tracepoint_update_probe_range(struct tracepoint *begin,
 | |
| 	struct tracepoint *end);
 | |
| 
 | |
| #else /* !CONFIG_TRACEPOINTS */
 | |
| #define DECLARE_TRACE(name, proto, args)				\
 | |
| 	static inline void _do_trace_##name(struct tracepoint *tp, proto) \
 | |
| 	{ }								\
 | |
| 	static inline void trace_##name(proto)				\
 | |
| 	{ }								\
 | |
| 	static inline int register_trace_##name(void (*probe)(proto))	\
 | |
| 	{								\
 | |
| 		return -ENOSYS;						\
 | |
| 	}								\
 | |
| 	static inline int unregister_trace_##name(void (*probe)(proto))	\
 | |
| 	{								\
 | |
| 		return -ENOSYS;						\
 | |
| 	}
 | |
| 
 | |
| #define DEFINE_TRACE(name)
 | |
| #define EXPORT_TRACEPOINT_SYMBOL_GPL(name)
 | |
| #define EXPORT_TRACEPOINT_SYMBOL(name)
 | |
| 
 | |
| static inline void tracepoint_update_probe_range(struct tracepoint *begin,
 | |
| 	struct tracepoint *end)
 | |
| { }
 | |
| #endif /* CONFIG_TRACEPOINTS */
 | |
| 
 | |
| /*
 | |
|  * Connect a probe to a tracepoint.
 | |
|  * Internal API, should not be used directly.
 | |
|  */
 | |
| extern int tracepoint_probe_register(const char *name, void *probe);
 | |
| 
 | |
| /*
 | |
|  * Disconnect a probe from a tracepoint.
 | |
|  * Internal API, should not be used directly.
 | |
|  */
 | |
| extern int tracepoint_probe_unregister(const char *name, void *probe);
 | |
| 
 | |
| extern int tracepoint_probe_register_noupdate(const char *name, void *probe);
 | |
| extern int tracepoint_probe_unregister_noupdate(const char *name, void *probe);
 | |
| extern void tracepoint_probe_update_all(void);
 | |
| 
 | |
| struct tracepoint_iter {
 | |
| 	struct module *module;
 | |
| 	struct tracepoint *tracepoint;
 | |
| };
 | |
| 
 | |
| extern void tracepoint_iter_start(struct tracepoint_iter *iter);
 | |
| extern void tracepoint_iter_next(struct tracepoint_iter *iter);
 | |
| extern void tracepoint_iter_stop(struct tracepoint_iter *iter);
 | |
| extern void tracepoint_iter_reset(struct tracepoint_iter *iter);
 | |
| extern int tracepoint_get_iter_range(struct tracepoint **tracepoint,
 | |
| 	struct tracepoint *begin, struct tracepoint *end);
 | |
| 
 | |
| /*
 | |
|  * tracepoint_synchronize_unregister must be called between the last tracepoint
 | |
|  * probe unregistration and the end of module exit to make sure there is no
 | |
|  * caller executing a probe when it is freed.
 | |
|  */
 | |
| static inline void tracepoint_synchronize_unregister(void)
 | |
| {
 | |
| 	synchronize_sched();
 | |
| }
 | |
| 
 | |
| #define PARAMS(args...) args
 | |
| #define TRACE_FORMAT(name, proto, args, fmt)		\
 | |
| 	DECLARE_TRACE(name, PARAMS(proto), PARAMS(args))
 | |
| 
 | |
| #define TRACE_EVENT_FORMAT(name, proto, args, fmt, struct, tpfmt)	\
 | |
| 	TRACE_FORMAT(name, PARAMS(proto), PARAMS(args), PARAMS(fmt))
 | |
| 
 | |
| #endif
 |