Merge branch 'tracing/core' of git://git.kernel.org/pub/scm/linux/kernel/git/frederic/random-tracing into tracing/core
Conflicts: include/linux/tracepoint.h Signed-off-by: Ingo Molnar <mingo@elte.hu>
This commit is contained in:
commit
35dce1a99d
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) */
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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>
|
||||
|
|
@ -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)
|
||||
|
||||
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue