diff options
| -rw-r--r-- | arch/s390/Kconfig | 2 | ||||
| -rw-r--r-- | arch/s390/defconfig | 2 | ||||
| -rw-r--r-- | arch/s390/include/asm/thread_info.h | 4 | ||||
| -rw-r--r-- | arch/s390/kernel/entry.S | 2 | ||||
| -rw-r--r-- | arch/s390/kernel/entry64.S | 2 | ||||
| -rw-r--r-- | arch/s390/kernel/ptrace.c | 12 | ||||
| -rw-r--r-- | arch/x86/Kconfig | 2 | ||||
| -rw-r--r-- | arch/x86/configs/i386_defconfig | 2 | ||||
| -rw-r--r-- | arch/x86/configs/x86_64_defconfig | 2 | ||||
| -rw-r--r-- | arch/x86/include/asm/thread_info.h | 13 | ||||
| -rw-r--r-- | arch/x86/kernel/ptrace.c | 16 | ||||
| -rw-r--r-- | include/linux/tracepoint.h | 46 | ||||
| -rw-r--r-- | include/trace/define_trace.h | 5 | ||||
| -rw-r--r-- | include/trace/events/syscalls.h | 70 | ||||
| -rw-r--r-- | include/trace/ftrace.h | 9 | ||||
| -rw-r--r-- | include/trace/syscall.h | 17 | ||||
| -rw-r--r-- | kernel/trace/Kconfig | 4 | ||||
| -rw-r--r-- | kernel/trace/trace_syscalls.c | 17 | ||||
| -rw-r--r-- | kernel/tracepoint.c | 20 | 
19 files changed, 154 insertions, 93 deletions
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index 2ae5d72f47e..7238ef4c7a6 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -84,7 +84,7 @@ config S390  	select HAVE_FUNCTION_TRACER  	select HAVE_FUNCTION_TRACE_MCOUNT_TEST  	select HAVE_FTRACE_MCOUNT_RECORD -	select HAVE_FTRACE_SYSCALLS +	select HAVE_SYSCALL_TRACEPOINTS  	select HAVE_DYNAMIC_FTRACE  	select HAVE_FUNCTION_GRAPH_TRACER  	select HAVE_DEFAULT_NO_SPIN_MUTEXES diff --git a/arch/s390/defconfig b/arch/s390/defconfig index fcba206529f..4e91a2573cc 100644 --- a/arch/s390/defconfig +++ b/arch/s390/defconfig @@ -900,7 +900,7 @@ CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y  CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y  CONFIG_HAVE_DYNAMIC_FTRACE=y  CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y -CONFIG_HAVE_FTRACE_SYSCALLS=y +CONFIG_HAVE_SYSCALL_TRACEPOINTS=y  CONFIG_TRACING_SUPPORT=y  CONFIG_FTRACE=y  # CONFIG_FUNCTION_TRACER is not set diff --git a/arch/s390/include/asm/thread_info.h b/arch/s390/include/asm/thread_info.h index ba1cab9fc1f..07eb61b2fb3 100644 --- a/arch/s390/include/asm/thread_info.h +++ b/arch/s390/include/asm/thread_info.h @@ -92,7 +92,7 @@ static inline struct thread_info *current_thread_info(void)  #define TIF_SYSCALL_TRACE	8	/* syscall trace active */  #define TIF_SYSCALL_AUDIT	9	/* syscall auditing active */  #define TIF_SECCOMP		10	/* secure computing */ -#define TIF_SYSCALL_FTRACE	11	/* ftrace syscall instrumentation */ +#define TIF_SYSCALL_TRACEPOINT	11	/* syscall tracepoint instrumentation */  #define TIF_USEDFPU		16	/* FPU was used by this task this quantum (SMP) */  #define TIF_POLLING_NRFLAG	17	/* true if poll_idle() is polling   					   TIF_NEED_RESCHED */ @@ -111,7 +111,7 @@ static inline struct thread_info *current_thread_info(void)  #define _TIF_SYSCALL_TRACE	(1<<TIF_SYSCALL_TRACE)  #define _TIF_SYSCALL_AUDIT	(1<<TIF_SYSCALL_AUDIT)  #define _TIF_SECCOMP		(1<<TIF_SECCOMP) -#define _TIF_SYSCALL_FTRACE	(1<<TIF_SYSCALL_FTRACE) +#define _TIF_SYSCALL_TRACEPOINT	(1<<TIF_SYSCALL_TRACEPOINT)  #define _TIF_USEDFPU		(1<<TIF_USEDFPU)  #define _TIF_POLLING_NRFLAG	(1<<TIF_POLLING_NRFLAG)  #define _TIF_31BIT		(1<<TIF_31BIT) diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S index c4c80a22bc1..5d40fce878a 100644 --- a/arch/s390/kernel/entry.S +++ b/arch/s390/kernel/entry.S @@ -54,7 +54,7 @@ _TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \  _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \  		 _TIF_MCCK_PENDING)  _TIF_SYSCALL = (_TIF_SYSCALL_TRACE>>8 | _TIF_SYSCALL_AUDIT>>8 | \ -		_TIF_SECCOMP>>8 | _TIF_SYSCALL_FTRACE>>8) +		_TIF_SECCOMP>>8 | _TIF_SYSCALL_TRACEPOINT>>8)  STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER  STACK_SIZE  = 1 << STACK_SHIFT diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S index f6618e9e15e..3ceb53c9c49 100644 --- a/arch/s390/kernel/entry64.S +++ b/arch/s390/kernel/entry64.S @@ -57,7 +57,7 @@ _TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \  _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \  		 _TIF_MCCK_PENDING)  _TIF_SYSCALL = (_TIF_SYSCALL_TRACE>>8 | _TIF_SYSCALL_AUDIT>>8 | \ -		_TIF_SECCOMP>>8 | _TIF_SYSCALL_FTRACE>>8) +		_TIF_SECCOMP>>8 | _TIF_SYSCALL_TRACEPOINT>>8)  #define BASED(name) name-system_call(%r13) diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c index c5e87d891ca..f3ddd7ac06c 100644 --- a/arch/s390/kernel/ptrace.c +++ b/arch/s390/kernel/ptrace.c @@ -51,8 +51,8 @@  #include "compat_ptrace.h"  #endif -DEFINE_TRACE(syscall_enter); -DEFINE_TRACE(syscall_exit); +#define CREATE_TRACE_POINTS +#include <trace/events/syscalls.h>  enum s390_regset {  	REGSET_GENERAL, @@ -664,8 +664,8 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)  		ret = -1;  	} -	if (unlikely(test_thread_flag(TIF_SYSCALL_FTRACE))) -		trace_syscall_enter(regs, regs->gprs[2]); +	if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT))) +		trace_sys_enter(regs, regs->gprs[2]);  	if (unlikely(current->audit_context))  		audit_syscall_entry(is_compat_task() ? @@ -682,8 +682,8 @@ asmlinkage void do_syscall_trace_exit(struct pt_regs *regs)  		audit_syscall_exit(AUDITSC_RESULT(regs->gprs[2]),  				   regs->gprs[2]); -	if (unlikely(test_thread_flag(TIF_SYSCALL_FTRACE))) -		trace_syscall_exit(regs, regs->gprs[2]); +	if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT))) +		trace_sys_exit(regs, regs->gprs[2]);  	if (test_thread_flag(TIF_SYSCALL_TRACE))  		tracehook_report_syscall_exit(regs, 0); diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 738bdc6b0f8..d59cbf758f3 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -37,7 +37,7 @@ config X86  	select HAVE_FUNCTION_GRAPH_FP_TEST  	select HAVE_FUNCTION_TRACE_MCOUNT_TEST  	select HAVE_FTRACE_NMI_ENTER if DYNAMIC_FTRACE -	select HAVE_FTRACE_SYSCALLS +	select HAVE_SYSCALL_TRACEPOINTS  	select HAVE_KVM  	select HAVE_ARCH_KGDB  	select HAVE_ARCH_TRACEHOOK diff --git a/arch/x86/configs/i386_defconfig b/arch/x86/configs/i386_defconfig index edb992ebef9..d28fad19654 100644 --- a/arch/x86/configs/i386_defconfig +++ b/arch/x86/configs/i386_defconfig @@ -2355,7 +2355,7 @@ CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y  CONFIG_HAVE_DYNAMIC_FTRACE=y  CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y  CONFIG_HAVE_HW_BRANCH_TRACER=y -CONFIG_HAVE_FTRACE_SYSCALLS=y +CONFIG_HAVE_SYSCALL_TRACEPOINTS=y  CONFIG_RING_BUFFER=y  CONFIG_TRACING=y  CONFIG_TRACING_SUPPORT=y diff --git a/arch/x86/configs/x86_64_defconfig b/arch/x86/configs/x86_64_defconfig index cee1dd2e69b..6c86acd847a 100644 --- a/arch/x86/configs/x86_64_defconfig +++ b/arch/x86/configs/x86_64_defconfig @@ -2329,7 +2329,7 @@ CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y  CONFIG_HAVE_DYNAMIC_FTRACE=y  CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y  CONFIG_HAVE_HW_BRANCH_TRACER=y -CONFIG_HAVE_FTRACE_SYSCALLS=y +CONFIG_HAVE_SYSCALL_TRACEPOINTS=y  CONFIG_RING_BUFFER=y  CONFIG_TRACING=y  CONFIG_TRACING_SUPPORT=y diff --git a/arch/x86/include/asm/thread_info.h b/arch/x86/include/asm/thread_info.h index fad7d40b75f..6f7786aea4f 100644 --- a/arch/x86/include/asm/thread_info.h +++ b/arch/x86/include/asm/thread_info.h @@ -95,7 +95,7 @@ struct thread_info {  #define TIF_DEBUGCTLMSR		25	/* uses thread_struct.debugctlmsr */  #define TIF_DS_AREA_MSR		26      /* uses thread_struct.ds_area_msr */  #define TIF_LAZY_MMU_UPDATES	27	/* task is updating the mmu lazily */ -#define TIF_SYSCALL_FTRACE	28	/* for ftrace syscall instrumentation */ +#define TIF_SYSCALL_TRACEPOINT	28	/* syscall tracepoint instrumentation */  #define _TIF_SYSCALL_TRACE	(1 << TIF_SYSCALL_TRACE)  #define _TIF_NOTIFY_RESUME	(1 << TIF_NOTIFY_RESUME) @@ -118,17 +118,17 @@ struct thread_info {  #define _TIF_DEBUGCTLMSR	(1 << TIF_DEBUGCTLMSR)  #define _TIF_DS_AREA_MSR	(1 << TIF_DS_AREA_MSR)  #define _TIF_LAZY_MMU_UPDATES	(1 << TIF_LAZY_MMU_UPDATES) -#define _TIF_SYSCALL_FTRACE	(1 << TIF_SYSCALL_FTRACE) +#define _TIF_SYSCALL_TRACEPOINT	(1 << TIF_SYSCALL_TRACEPOINT)  /* work to do in syscall_trace_enter() */  #define _TIF_WORK_SYSCALL_ENTRY	\ -	(_TIF_SYSCALL_TRACE | _TIF_SYSCALL_EMU | _TIF_SYSCALL_FTRACE |	\ -	 _TIF_SYSCALL_AUDIT | _TIF_SECCOMP | _TIF_SINGLESTEP) +	(_TIF_SYSCALL_TRACE | _TIF_SYSCALL_EMU | _TIF_SYSCALL_AUDIT |	\ +	 _TIF_SECCOMP | _TIF_SINGLESTEP | _TIF_SYSCALL_TRACEPOINT)  /* work to do in syscall_trace_leave() */  #define _TIF_WORK_SYSCALL_EXIT	\  	(_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | _TIF_SINGLESTEP |	\ -	 _TIF_SYSCALL_FTRACE) +	 _TIF_SYSCALL_TRACEPOINT)  /* work to do on interrupt/exception return */  #define _TIF_WORK_MASK							\ @@ -137,7 +137,8 @@ struct thread_info {  	   _TIF_SINGLESTEP|_TIF_SECCOMP|_TIF_SYSCALL_EMU))  /* work to do on any return to user space */ -#define _TIF_ALLWORK_MASK ((0x0000FFFF & ~_TIF_SECCOMP) | _TIF_SYSCALL_FTRACE) +#define _TIF_ALLWORK_MASK						\ +	((0x0000FFFF & ~_TIF_SECCOMP) | _TIF_SYSCALL_TRACEPOINT)  /* Only used for 64 bit */  #define _TIF_DO_NOTIFY_MASK						\ diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c index 34dd6f15185..8d7d5c9c1be 100644 --- a/arch/x86/kernel/ptrace.c +++ b/arch/x86/kernel/ptrace.c @@ -35,13 +35,11 @@  #include <asm/proto.h>  #include <asm/ds.h> -#include <trace/syscall.h> - -DEFINE_TRACE(syscall_enter); -DEFINE_TRACE(syscall_exit); -  #include "tls.h" +#define CREATE_TRACE_POINTS +#include <trace/events/syscalls.h> +  enum x86_regset {  	REGSET_GENERAL,  	REGSET_FP, @@ -1500,8 +1498,8 @@ asmregparm long syscall_trace_enter(struct pt_regs *regs)  	    tracehook_report_syscall_entry(regs))  		ret = -1L; -	if (unlikely(test_thread_flag(TIF_SYSCALL_FTRACE))) -		trace_syscall_enter(regs, regs->orig_ax); +	if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT))) +		trace_sys_enter(regs, regs->orig_ax);  	if (unlikely(current->audit_context)) {  		if (IS_IA32) @@ -1526,8 +1524,8 @@ asmregparm void syscall_trace_leave(struct pt_regs *regs)  	if (unlikely(current->audit_context))  		audit_syscall_exit(AUDITSC_RESULT(regs->ax), regs->ax); -	if (unlikely(test_thread_flag(TIF_SYSCALL_FTRACE))) -		trace_syscall_exit(regs, regs->ax); +	if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT))) +		trace_sys_exit(regs, regs->ax);  	if (test_thread_flag(TIF_SYSCALL_TRACE))  		tracehook_report_syscall_exit(regs, 0); diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h index 0341f2e2698..63a3f7a8058 100644 --- a/include/linux/tracepoint.h +++ b/include/linux/tracepoint.h @@ -23,6 +23,8 @@ struct tracepoint;  struct tracepoint {  	const char *name;		/* Tracepoint name */  	int state;			/* State. */ +	void (*regfunc)(void); +	void (*unregfunc)(void);  	void **funcs;  } __attribute__((aligned(32)));		/*  					 * Aligned on 32 bytes because it is @@ -60,10 +62,8 @@ struct tracepoint {   * 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. - * An optional set of (un)registration functions can be passed to perform any - * additional (un)registration work.   */ -#define DECLARE_TRACE_WITH_CALLBACK(name, proto, args, reg, unreg)	\ +#define DECLARE_TRACE(name, proto, args)				\  	extern struct tracepoint __tracepoint_##name;			\  	static inline void trace_##name(proto)				\  	{								\ @@ -73,36 +73,23 @@ struct tracepoint {  	}								\  	static inline int register_trace_##name(void (*probe)(proto))	\  	{								\ -		int ret;						\ -		void (*func)(void) = reg;				\ -									\ -		ret = tracepoint_probe_register(#name, (void *)probe);	\ -		if (func && !ret)					\ -			func();						\ -		return ret;						\ +		return tracepoint_probe_register(#name, (void *)probe);	\  	}								\  	static inline int unregister_trace_##name(void (*probe)(proto))	\  	{								\ -		int ret;						\ -		void (*func)(void) = unreg;				\ -									\ -		ret = tracepoint_probe_unregister(#name, (void *)probe);\ -		if (func && !ret)					\ -			func();						\ -		return ret;						\ +		return tracepoint_probe_unregister(#name, (void *)probe);\  	} -#define DECLARE_TRACE(name, proto, args)				 \ -	DECLARE_TRACE_WITH_CALLBACK(name, TP_PROTO(proto), TP_ARGS(args),\ -					NULL, NULL); - -#define DEFINE_TRACE(name)						\ +#define DEFINE_TRACE_FN(name, reg, unreg)				\  	static const char __tpstrtab_##name[]				\  	__attribute__((section("__tracepoints_strings"))) = #name;	\  	struct tracepoint __tracepoint_##name				\  	__attribute__((section("__tracepoints"), aligned(32))) =	\ -		{ __tpstrtab_##name, 0, NULL } +		{ __tpstrtab_##name, 0, reg, unreg, NULL } + +#define DEFINE_TRACE(name)						\ +	DEFINE_TRACE_FN(name, NULL, NULL);  #define EXPORT_TRACEPOINT_SYMBOL_GPL(name)				\  	EXPORT_SYMBOL_GPL(__tracepoint_##name) @@ -113,7 +100,7 @@ extern void tracepoint_update_probe_range(struct tracepoint *begin,  	struct tracepoint *end);  #else /* !CONFIG_TRACEPOINTS */ -#define DECLARE_TRACE_WITH_CALLBACK(name, proto, args, reg, unreg)	\ +#define DECLARE_TRACE(name, proto, args)				\  	static inline void _do_trace_##name(struct tracepoint *tp, proto) \  	{ }								\  	static inline void trace_##name(proto)				\ @@ -127,10 +114,7 @@ extern void tracepoint_update_probe_range(struct tracepoint *begin,  		return -ENOSYS;						\  	} -#define DECLARE_TRACE(name, proto, args)				 \ -	DECLARE_TRACE_WITH_CALLBACK(name, TP_PROTO(proto), TP_ARGS(args),\ -					NULL, NULL); - +#define DEFINE_TRACE_FN(name, reg, unreg)  #define DEFINE_TRACE(name)  #define EXPORT_TRACEPOINT_SYMBOL_GPL(name)  #define EXPORT_TRACEPOINT_SYMBOL(name) @@ -291,9 +275,15 @@ static inline void tracepoint_synchronize_unregister(void)   * can also by used by generic instrumentation like SystemTap), and   * it is also used to expose a structured trace record in   * /sys/kernel/debug/tracing/events/. + * + * A set of (un)registration functions can be passed to the variant + * TRACE_EVENT_FN to perform any (un)registration work.   */  #define TRACE_EVENT(name, proto, args, struct, assign, print)	\  	DECLARE_TRACE(name, PARAMS(proto), PARAMS(args)) +#define TRACE_EVENT_FN(name, proto, args, struct,		\ +		assign, print, reg, unreg)			\ +	DECLARE_TRACE(name, PARAMS(proto), PARAMS(args))  #endif /* ifdef TRACE_EVENT (see note above) */ diff --git a/include/trace/define_trace.h b/include/trace/define_trace.h index cd150b9d8e3..a89ed590597 100644 --- a/include/trace/define_trace.h +++ b/include/trace/define_trace.h @@ -26,6 +26,11 @@  #define TRACE_EVENT(name, proto, args, tstruct, assign, print)	\  	DEFINE_TRACE(name) +#undef TRACE_EVENT_FN +#define TRACE_EVENT_FN(name, proto, args, tstruct,		\ +		assign, print, reg, unreg)			\ +	DEFINE_TRACE_FN(name, reg, unreg) +  #undef DECLARE_TRACE  #define DECLARE_TRACE(name, proto, args)	\  	DEFINE_TRACE(name) diff --git a/include/trace/events/syscalls.h b/include/trace/events/syscalls.h new file mode 100644 index 00000000000..397dff2dbd5 --- /dev/null +++ b/include/trace/events/syscalls.h @@ -0,0 +1,70 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM syscalls + +#if !defined(_TRACE_EVENTS_SYSCALLS_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_EVENTS_SYSCALLS_H + +#include <linux/tracepoint.h> + +#include <asm/ptrace.h> +#include <asm/syscall.h> + + +#ifdef CONFIG_HAVE_SYSCALL_TRACEPOINTS + +extern void syscall_regfunc(void); +extern void syscall_unregfunc(void); + +TRACE_EVENT_FN(sys_enter, + +	TP_PROTO(struct pt_regs *regs, long id), + +	TP_ARGS(regs, id), + +	TP_STRUCT__entry( +		__field(	long,		id		) +		__array(	unsigned long,	args,	6	) +	), + +	TP_fast_assign( +		__entry->id	= id; +		syscall_get_arguments(current, regs, 0, 6, __entry->args); +	), + +	TP_printk("NR %ld (%lx, %lx, %lx, %lx, %lx, %lx)", +		  __entry->id, +		  __entry->args[0], __entry->args[1], __entry->args[2], +		  __entry->args[3], __entry->args[4], __entry->args[5]), + +	syscall_regfunc, syscall_unregfunc +); + +TRACE_EVENT_FN(sys_exit, + +	TP_PROTO(struct pt_regs *regs, long ret), + +	TP_ARGS(regs, ret), + +	TP_STRUCT__entry( +		__field(	long,	id	) +		__field(	long,	ret	) +	), + +	TP_fast_assign( +		__entry->id	= syscall_get_nr(current, regs); +		__entry->ret	= ret; +	), + +	TP_printk("NR %ld = %ld", +		  __entry->id, __entry->ret), + +	syscall_regfunc, syscall_unregfunc +); + +#endif /* CONFIG_HAVE_SYSCALL_TRACEPOINTS */ + +#endif /* _TRACE_EVENTS_SYSCALLS_H */ + +/* This part must be outside protection */ +#include <trace/define_trace.h> + diff --git a/include/trace/ftrace.h b/include/trace/ftrace.h index 1b1f742a604..360a77ad79e 100644 --- a/include/trace/ftrace.h +++ b/include/trace/ftrace.h @@ -45,6 +45,15 @@  	};							\  	static struct ftrace_event_call event_##name +/* Callbacks are meaningless to ftrace. */ +#undef TRACE_EVENT_FN +#define TRACE_EVENT_FN(name, proto, args, tstruct,		\ +		assign, print, reg, unreg)			\ +	TRACE_EVENT(name, TP_PROTO(proto), TP_ARGS(args),	\ +		TP_STRUCT__entry(tstruct),			\ +		TP_fast_assign(assign),				\ +		TP_printk(print)) +  #include TRACE_INCLUDE(TRACE_INCLUDE_FILE) diff --git a/include/trace/syscall.h b/include/trace/syscall.h index 9661dd406b9..5dc283ba5ae 100644 --- a/include/trace/syscall.h +++ b/include/trace/syscall.h @@ -8,23 +8,6 @@  #include <asm/ptrace.h> -extern void syscall_regfunc(void); -extern void syscall_unregfunc(void); - -DECLARE_TRACE_WITH_CALLBACK(syscall_enter, -	TP_PROTO(struct pt_regs *regs, long id), -	TP_ARGS(regs, id), -	syscall_regfunc, -	syscall_unregfunc -); - -DECLARE_TRACE_WITH_CALLBACK(syscall_exit, -	TP_PROTO(struct pt_regs *regs, long ret), -	TP_ARGS(regs, ret), -	syscall_regfunc, -	syscall_unregfunc -); -  /*   * A syscall entry in the ftrace syscalls array.   * diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig index 019f380fd76..06be85a7ef8 100644 --- a/kernel/trace/Kconfig +++ b/kernel/trace/Kconfig @@ -41,7 +41,7 @@ config HAVE_FTRACE_MCOUNT_RECORD  config HAVE_HW_BRANCH_TRACER  	bool -config HAVE_FTRACE_SYSCALLS +config HAVE_SYSCALL_TRACEPOINTS  	bool  config TRACER_MAX_TRACE @@ -211,7 +211,7 @@ config ENABLE_DEFAULT_TRACERS  config FTRACE_SYSCALLS  	bool "Trace syscalls" -	depends on HAVE_FTRACE_SYSCALLS +	depends on HAVE_SYSCALL_TRACEPOINTS  	select GENERIC_TRACER  	select KALLSYMS  	help diff --git a/kernel/trace/trace_syscalls.c b/kernel/trace/trace_syscalls.c index 97a2454760b..85291c4de40 100644 --- a/kernel/trace/trace_syscalls.c +++ b/kernel/trace/trace_syscalls.c @@ -1,4 +1,5 @@  #include <trace/syscall.h> +#include <trace/events/syscalls.h>  #include <linux/kernel.h>  #include <linux/ftrace.h>  #include <linux/perf_counter.h> @@ -288,7 +289,7 @@ int reg_event_syscall_enter(void *ptr)  		return -ENOSYS;  	mutex_lock(&syscall_trace_lock);  	if (!sys_refcount_enter) -		ret = register_trace_syscall_enter(ftrace_syscall_enter); +		ret = register_trace_sys_enter(ftrace_syscall_enter);  	if (ret) {  		pr_info("event trace: Could not activate"  				"syscall entry trace point"); @@ -313,7 +314,7 @@ void unreg_event_syscall_enter(void *ptr)  	sys_refcount_enter--;  	clear_bit(num, enabled_enter_syscalls);  	if (!sys_refcount_enter) -		unregister_trace_syscall_enter(ftrace_syscall_enter); +		unregister_trace_sys_enter(ftrace_syscall_enter);  	mutex_unlock(&syscall_trace_lock);  } @@ -329,7 +330,7 @@ int reg_event_syscall_exit(void *ptr)  		return -ENOSYS;  	mutex_lock(&syscall_trace_lock);  	if (!sys_refcount_exit) -		ret = register_trace_syscall_exit(ftrace_syscall_exit); +		ret = register_trace_sys_exit(ftrace_syscall_exit);  	if (ret) {  		pr_info("event trace: Could not activate"  				"syscall exit trace point"); @@ -354,7 +355,7 @@ void unreg_event_syscall_exit(void *ptr)  	sys_refcount_exit--;  	clear_bit(num, enabled_exit_syscalls);  	if (!sys_refcount_exit) -		unregister_trace_syscall_exit(ftrace_syscall_exit); +		unregister_trace_sys_exit(ftrace_syscall_exit);  	mutex_unlock(&syscall_trace_lock);  } @@ -420,7 +421,7 @@ int reg_prof_syscall_enter(char *name)  	mutex_lock(&syscall_trace_lock);  	if (!sys_prof_refcount_enter) -		ret = register_trace_syscall_enter(prof_syscall_enter); +		ret = register_trace_sys_enter(prof_syscall_enter);  	if (ret) {  		pr_info("event trace: Could not activate"  				"syscall entry trace point"); @@ -444,7 +445,7 @@ void unreg_prof_syscall_enter(char *name)  	sys_prof_refcount_enter--;  	clear_bit(num, enabled_prof_enter_syscalls);  	if (!sys_prof_refcount_enter) -		unregister_trace_syscall_enter(prof_syscall_enter); +		unregister_trace_sys_enter(prof_syscall_enter);  	mutex_unlock(&syscall_trace_lock);  } @@ -481,7 +482,7 @@ int reg_prof_syscall_exit(char *name)  	mutex_lock(&syscall_trace_lock);  	if (!sys_prof_refcount_exit) -		ret = register_trace_syscall_exit(prof_syscall_exit); +		ret = register_trace_sys_exit(prof_syscall_exit);  	if (ret) {  		pr_info("event trace: Could not activate"  				"syscall entry trace point"); @@ -505,7 +506,7 @@ void unreg_prof_syscall_exit(char *name)  	sys_prof_refcount_exit--;  	clear_bit(num, enabled_prof_exit_syscalls);  	if (!sys_prof_refcount_exit) -		unregister_trace_syscall_exit(prof_syscall_exit); +		unregister_trace_sys_exit(prof_syscall_exit);  	mutex_unlock(&syscall_trace_lock);  } diff --git a/kernel/tracepoint.c b/kernel/tracepoint.c index 06f165a4408..1a6a453b7ef 100644 --- a/kernel/tracepoint.c +++ b/kernel/tracepoint.c @@ -243,6 +243,11 @@ static void set_tracepoint(struct tracepoint_entry **entry,  {  	WARN_ON(strcmp((*entry)->name, elem->name) != 0); +	if (elem->regfunc && !elem->state && active) +		elem->regfunc(); +	else if (elem->unregfunc && elem->state && !active) +		elem->unregfunc(); +  	/*  	 * rcu_assign_pointer has a smp_wmb() which makes sure that the new  	 * probe callbacks array is consistent before setting a pointer to it. @@ -262,6 +267,9 @@ static void set_tracepoint(struct tracepoint_entry **entry,   */  static void disable_tracepoint(struct tracepoint *elem)  { +	if (elem->unregfunc && elem->state) +		elem->unregfunc(); +  	elem->state = 0;  	rcu_assign_pointer(elem->funcs, NULL);  } @@ -576,9 +584,9 @@ __initcall(init_tracepoints);  #endif /* CONFIG_MODULES */ -#ifdef CONFIG_FTRACE_SYSCALLS +#ifdef CONFIG_HAVE_SYSCALL_TRACEPOINTS -static DEFINE_MUTEX(regfunc_mutex); +/* NB: reg/unreg are called while guarded with the tracepoints_mutex */  static int sys_tracepoint_refcount;  void syscall_regfunc(void) @@ -586,16 +594,14 @@ void syscall_regfunc(void)  	unsigned long flags;  	struct task_struct *g, *t; -	mutex_lock(®func_mutex);  	if (!sys_tracepoint_refcount) {  		read_lock_irqsave(&tasklist_lock, flags);  		do_each_thread(g, t) { -			set_tsk_thread_flag(t, TIF_SYSCALL_FTRACE); +			set_tsk_thread_flag(t, TIF_SYSCALL_TRACEPOINT);  		} while_each_thread(g, t);  		read_unlock_irqrestore(&tasklist_lock, flags);  	}  	sys_tracepoint_refcount++; -	mutex_unlock(®func_mutex);  }  void syscall_unregfunc(void) @@ -603,15 +609,13 @@ void syscall_unregfunc(void)  	unsigned long flags;  	struct task_struct *g, *t; -	mutex_lock(®func_mutex);  	sys_tracepoint_refcount--;  	if (!sys_tracepoint_refcount) {  		read_lock_irqsave(&tasklist_lock, flags);  		do_each_thread(g, t) { -			clear_tsk_thread_flag(t, TIF_SYSCALL_FTRACE); +			clear_tsk_thread_flag(t, TIF_SYSCALL_TRACEPOINT);  		} while_each_thread(g, t);  		read_unlock_irqrestore(&tasklist_lock, flags);  	} -	mutex_unlock(®func_mutex);  }  #endif  |