Commit e4106133 authored by Ingo Molnar's avatar Ingo Molnar

Merge branch 'tracing/syscalls' into tracing/core

parents 7243f214 2fc1dfbe
...@@ -182,6 +182,7 @@ config FTRACE_SYSCALLS ...@@ -182,6 +182,7 @@ config FTRACE_SYSCALLS
bool "Trace syscalls" bool "Trace syscalls"
depends on HAVE_FTRACE_SYSCALLS depends on HAVE_FTRACE_SYSCALLS
select TRACING select TRACING
select KALLSYMS
help help
Basic tracer to catch the syscall entry and exit events. Basic tracer to catch the syscall entry and exit events.
......
...@@ -2494,7 +2494,7 @@ static int tracing_set_tracer(const char *buf) ...@@ -2494,7 +2494,7 @@ static int tracing_set_tracer(const char *buf)
if (!ring_buffer_expanded) { if (!ring_buffer_expanded) {
ret = tracing_resize_ring_buffer(trace_buf_size); ret = tracing_resize_ring_buffer(trace_buf_size);
if (ret < 0) if (ret < 0)
return ret; goto out;
ret = 0; ret = 0;
} }
...@@ -4125,7 +4125,8 @@ __init static int tracer_alloc_buffers(void) ...@@ -4125,7 +4125,8 @@ __init static int tracer_alloc_buffers(void)
&trace_panic_notifier); &trace_panic_notifier);
register_die_notifier(&trace_die_notifier); register_die_notifier(&trace_die_notifier);
ret = 0;
return 0;
out_free_cpumask: out_free_cpumask:
free_cpumask_var(tracing_reader_cpumask); free_cpumask_var(tracing_reader_cpumask);
......
...@@ -414,7 +414,7 @@ trace_selftest_startup_preemptirqsoff(struct tracer *trace, struct trace_array * ...@@ -414,7 +414,7 @@ trace_selftest_startup_preemptirqsoff(struct tracer *trace, struct trace_array *
ret = tracer_init(trace, tr); ret = tracer_init(trace, tr);
if (ret) { if (ret) {
warn_failed_init_tracer(trace, ret); warn_failed_init_tracer(trace, ret);
goto out; goto out_no_start;
} }
/* reset the max latency */ /* reset the max latency */
...@@ -432,21 +432,16 @@ trace_selftest_startup_preemptirqsoff(struct tracer *trace, struct trace_array * ...@@ -432,21 +432,16 @@ trace_selftest_startup_preemptirqsoff(struct tracer *trace, struct trace_array *
tracing_stop(); tracing_stop();
/* check both trace buffers */ /* check both trace buffers */
ret = trace_test_buffer(tr, NULL); ret = trace_test_buffer(tr, NULL);
if (ret) { if (ret)
tracing_start();
goto out; goto out;
}
ret = trace_test_buffer(&max_tr, &count); ret = trace_test_buffer(&max_tr, &count);
if (ret) { if (ret)
tracing_start();
goto out; goto out;
}
if (!ret && !count) { if (!ret && !count) {
printk(KERN_CONT ".. no entries found .."); printk(KERN_CONT ".. no entries found ..");
ret = -1; ret = -1;
tracing_start();
goto out; goto out;
} }
...@@ -475,9 +470,10 @@ trace_selftest_startup_preemptirqsoff(struct tracer *trace, struct trace_array * ...@@ -475,9 +470,10 @@ trace_selftest_startup_preemptirqsoff(struct tracer *trace, struct trace_array *
goto out; goto out;
} }
out: out:
trace->reset(tr);
tracing_start(); tracing_start();
out_no_start:
trace->reset(tr);
tracing_max_latency = save_max; tracing_max_latency = save_max;
return ret; return ret;
......
...@@ -5,9 +5,13 @@ ...@@ -5,9 +5,13 @@
#include "trace_output.h" #include "trace_output.h"
#include "trace.h" #include "trace.h"
static atomic_t refcount; /* Keep a counter of the syscall tracing users */
static int refcount;
/* Our two options */ /* Prevent from races on thread flags toggling */
static DEFINE_MUTEX(syscall_trace_lock);
/* Option to display the parameters types */
enum { enum {
TRACE_SYSCALLS_OPT_TYPES = 0x1, TRACE_SYSCALLS_OPT_TYPES = 0x1,
}; };
...@@ -18,7 +22,7 @@ static struct tracer_opt syscalls_opts[] = { ...@@ -18,7 +22,7 @@ static struct tracer_opt syscalls_opts[] = {
}; };
static struct tracer_flags syscalls_flags = { static struct tracer_flags syscalls_flags = {
.val = 0, /* By default: no args types */ .val = 0, /* By default: no parameters types */
.opts = syscalls_opts .opts = syscalls_opts
}; };
...@@ -96,8 +100,11 @@ void start_ftrace_syscalls(void) ...@@ -96,8 +100,11 @@ void start_ftrace_syscalls(void)
unsigned long flags; unsigned long flags;
struct task_struct *g, *t; struct task_struct *g, *t;
if (atomic_inc_return(&refcount) != 1) mutex_lock(&syscall_trace_lock);
goto out;
/* Don't enable the flag on the tasks twice */
if (++refcount != 1)
goto unlock;
arch_init_ftrace_syscalls(); arch_init_ftrace_syscalls();
read_lock_irqsave(&tasklist_lock, flags); read_lock_irqsave(&tasklist_lock, flags);
...@@ -107,8 +114,9 @@ void start_ftrace_syscalls(void) ...@@ -107,8 +114,9 @@ void start_ftrace_syscalls(void)
} while_each_thread(g, t); } while_each_thread(g, t);
read_unlock_irqrestore(&tasklist_lock, flags); read_unlock_irqrestore(&tasklist_lock, flags);
out:
atomic_dec(&refcount); unlock:
mutex_unlock(&syscall_trace_lock);
} }
void stop_ftrace_syscalls(void) void stop_ftrace_syscalls(void)
...@@ -116,8 +124,11 @@ void stop_ftrace_syscalls(void) ...@@ -116,8 +124,11 @@ void stop_ftrace_syscalls(void)
unsigned long flags; unsigned long flags;
struct task_struct *g, *t; struct task_struct *g, *t;
if (atomic_dec_return(&refcount)) mutex_lock(&syscall_trace_lock);
goto out;
/* There are perhaps still some users */
if (--refcount)
goto unlock;
read_lock_irqsave(&tasklist_lock, flags); read_lock_irqsave(&tasklist_lock, flags);
...@@ -126,8 +137,9 @@ void stop_ftrace_syscalls(void) ...@@ -126,8 +137,9 @@ void stop_ftrace_syscalls(void)
} while_each_thread(g, t); } while_each_thread(g, t);
read_unlock_irqrestore(&tasklist_lock, flags); read_unlock_irqrestore(&tasklist_lock, flags);
out:
atomic_inc(&refcount); unlock:
mutex_unlock(&syscall_trace_lock);
} }
void ftrace_syscall_enter(struct pt_regs *regs) void ftrace_syscall_enter(struct pt_regs *regs)
...@@ -137,12 +149,9 @@ void ftrace_syscall_enter(struct pt_regs *regs) ...@@ -137,12 +149,9 @@ void ftrace_syscall_enter(struct pt_regs *regs)
struct ring_buffer_event *event; struct ring_buffer_event *event;
int size; int size;
int syscall_nr; int syscall_nr;
int cpu;
syscall_nr = syscall_get_nr(current, regs); syscall_nr = syscall_get_nr(current, regs);
cpu = raw_smp_processor_id();
sys_data = syscall_nr_to_meta(syscall_nr); sys_data = syscall_nr_to_meta(syscall_nr);
if (!sys_data) if (!sys_data)
return; return;
...@@ -168,12 +177,9 @@ void ftrace_syscall_exit(struct pt_regs *regs) ...@@ -168,12 +177,9 @@ void ftrace_syscall_exit(struct pt_regs *regs)
struct syscall_metadata *sys_data; struct syscall_metadata *sys_data;
struct ring_buffer_event *event; struct ring_buffer_event *event;
int syscall_nr; int syscall_nr;
int cpu;
syscall_nr = syscall_get_nr(current, regs); syscall_nr = syscall_get_nr(current, regs);
cpu = raw_smp_processor_id();
sys_data = syscall_nr_to_meta(syscall_nr); sys_data = syscall_nr_to_meta(syscall_nr);
if (!sys_data) if (!sys_data)
return; return;
...@@ -201,6 +207,7 @@ static int init_syscall_tracer(struct trace_array *tr) ...@@ -201,6 +207,7 @@ static int init_syscall_tracer(struct trace_array *tr)
static void reset_syscall_tracer(struct trace_array *tr) static void reset_syscall_tracer(struct trace_array *tr)
{ {
stop_ftrace_syscalls(); stop_ftrace_syscalls();
tracing_reset_online_cpus(tr);
} }
static struct trace_event syscall_enter_event = { static struct trace_event syscall_enter_event = {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment