Merge branch 'tip/perf/core' of git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-2.6-trace into perf/core
This commit is contained in:
@@ -247,6 +247,13 @@ You need very few things to get the syscalls tracing in an arch.
|
|||||||
- Support the TIF_SYSCALL_TRACEPOINT thread flags.
|
- Support the TIF_SYSCALL_TRACEPOINT thread flags.
|
||||||
- Put the trace_sys_enter() and trace_sys_exit() tracepoints calls from ptrace
|
- Put the trace_sys_enter() and trace_sys_exit() tracepoints calls from ptrace
|
||||||
in the ptrace syscalls tracing path.
|
in the ptrace syscalls tracing path.
|
||||||
|
- If the system call table on this arch is more complicated than a simple array
|
||||||
|
of addresses of the system calls, implement an arch_syscall_addr to return
|
||||||
|
the address of a given system call.
|
||||||
|
- If the symbol names of the system calls do not match the function names on
|
||||||
|
this arch, define ARCH_HAS_SYSCALL_MATCH_SYM_NAME in asm/ftrace.h and
|
||||||
|
implement arch_syscall_match_sym_name with the appropriate logic to return
|
||||||
|
true if the function name corresponds with the symbol name.
|
||||||
- Tag this arch as HAVE_SYSCALL_TRACEPOINTS.
|
- Tag this arch as HAVE_SYSCALL_TRACEPOINTS.
|
||||||
|
|
||||||
|
|
||||||
|
@@ -80,11 +80,11 @@ of ftrace. Here is a list of some of the key files:
|
|||||||
tracers listed here can be configured by
|
tracers listed here can be configured by
|
||||||
echoing their name into current_tracer.
|
echoing their name into current_tracer.
|
||||||
|
|
||||||
tracing_enabled:
|
tracing_on:
|
||||||
|
|
||||||
This sets or displays whether the current_tracer
|
This sets or displays whether writing to the trace
|
||||||
is activated and tracing or not. Echo 0 into this
|
ring buffer is enabled. Echo 0 into this file to disable
|
||||||
file to disable the tracer or 1 to enable it.
|
the tracer or 1 to enable it.
|
||||||
|
|
||||||
trace:
|
trace:
|
||||||
|
|
||||||
@@ -202,10 +202,6 @@ Here is the list of current tracers that may be configured.
|
|||||||
to draw a graph of function calls similar to C code
|
to draw a graph of function calls similar to C code
|
||||||
source.
|
source.
|
||||||
|
|
||||||
"sched_switch"
|
|
||||||
|
|
||||||
Traces the context switches and wakeups between tasks.
|
|
||||||
|
|
||||||
"irqsoff"
|
"irqsoff"
|
||||||
|
|
||||||
Traces the areas that disable interrupts and saves
|
Traces the areas that disable interrupts and saves
|
||||||
@@ -273,39 +269,6 @@ format, the function name that was traced "path_put" and the
|
|||||||
parent function that called this function "path_walk". The
|
parent function that called this function "path_walk". The
|
||||||
timestamp is the time at which the function was entered.
|
timestamp is the time at which the function was entered.
|
||||||
|
|
||||||
The sched_switch tracer also includes tracing of task wakeups
|
|
||||||
and context switches.
|
|
||||||
|
|
||||||
ksoftirqd/1-7 [01] 1453.070013: 7:115:R + 2916:115:S
|
|
||||||
ksoftirqd/1-7 [01] 1453.070013: 7:115:R + 10:115:S
|
|
||||||
ksoftirqd/1-7 [01] 1453.070013: 7:115:R ==> 10:115:R
|
|
||||||
events/1-10 [01] 1453.070013: 10:115:S ==> 2916:115:R
|
|
||||||
kondemand/1-2916 [01] 1453.070013: 2916:115:S ==> 7:115:R
|
|
||||||
ksoftirqd/1-7 [01] 1453.070013: 7:115:S ==> 0:140:R
|
|
||||||
|
|
||||||
Wake ups are represented by a "+" and the context switches are
|
|
||||||
shown as "==>". The format is:
|
|
||||||
|
|
||||||
Context switches:
|
|
||||||
|
|
||||||
Previous task Next Task
|
|
||||||
|
|
||||||
<pid>:<prio>:<state> ==> <pid>:<prio>:<state>
|
|
||||||
|
|
||||||
Wake ups:
|
|
||||||
|
|
||||||
Current task Task waking up
|
|
||||||
|
|
||||||
<pid>:<prio>:<state> + <pid>:<prio>:<state>
|
|
||||||
|
|
||||||
The prio is the internal kernel priority, which is the inverse
|
|
||||||
of the priority that is usually displayed by user-space tools.
|
|
||||||
Zero represents the highest priority (99). Prio 100 starts the
|
|
||||||
"nice" priorities with 100 being equal to nice -20 and 139 being
|
|
||||||
nice 19. The prio "140" is reserved for the idle task which is
|
|
||||||
the lowest priority thread (pid 0).
|
|
||||||
|
|
||||||
|
|
||||||
Latency trace format
|
Latency trace format
|
||||||
--------------------
|
--------------------
|
||||||
|
|
||||||
@@ -491,79 +454,6 @@ x494] <- /root/a.out[+0x4a8] <- /lib/libc-2.7.so[+0x1e1a6]
|
|||||||
latencies, as described in "Latency
|
latencies, as described in "Latency
|
||||||
trace format".
|
trace format".
|
||||||
|
|
||||||
sched_switch
|
|
||||||
------------
|
|
||||||
|
|
||||||
This tracer simply records schedule switches. Here is an example
|
|
||||||
of how to use it.
|
|
||||||
|
|
||||||
# echo sched_switch > current_tracer
|
|
||||||
# echo 1 > tracing_enabled
|
|
||||||
# sleep 1
|
|
||||||
# echo 0 > tracing_enabled
|
|
||||||
# cat trace
|
|
||||||
|
|
||||||
# tracer: sched_switch
|
|
||||||
#
|
|
||||||
# TASK-PID CPU# TIMESTAMP FUNCTION
|
|
||||||
# | | | | |
|
|
||||||
bash-3997 [01] 240.132281: 3997:120:R + 4055:120:R
|
|
||||||
bash-3997 [01] 240.132284: 3997:120:R ==> 4055:120:R
|
|
||||||
sleep-4055 [01] 240.132371: 4055:120:S ==> 3997:120:R
|
|
||||||
bash-3997 [01] 240.132454: 3997:120:R + 4055:120:S
|
|
||||||
bash-3997 [01] 240.132457: 3997:120:R ==> 4055:120:R
|
|
||||||
sleep-4055 [01] 240.132460: 4055:120:D ==> 3997:120:R
|
|
||||||
bash-3997 [01] 240.132463: 3997:120:R + 4055:120:D
|
|
||||||
bash-3997 [01] 240.132465: 3997:120:R ==> 4055:120:R
|
|
||||||
<idle>-0 [00] 240.132589: 0:140:R + 4:115:S
|
|
||||||
<idle>-0 [00] 240.132591: 0:140:R ==> 4:115:R
|
|
||||||
ksoftirqd/0-4 [00] 240.132595: 4:115:S ==> 0:140:R
|
|
||||||
<idle>-0 [00] 240.132598: 0:140:R + 4:115:S
|
|
||||||
<idle>-0 [00] 240.132599: 0:140:R ==> 4:115:R
|
|
||||||
ksoftirqd/0-4 [00] 240.132603: 4:115:S ==> 0:140:R
|
|
||||||
sleep-4055 [01] 240.133058: 4055:120:S ==> 3997:120:R
|
|
||||||
[...]
|
|
||||||
|
|
||||||
|
|
||||||
As we have discussed previously about this format, the header
|
|
||||||
shows the name of the trace and points to the options. The
|
|
||||||
"FUNCTION" is a misnomer since here it represents the wake ups
|
|
||||||
and context switches.
|
|
||||||
|
|
||||||
The sched_switch file only lists the wake ups (represented with
|
|
||||||
'+') and context switches ('==>') with the previous task or
|
|
||||||
current task first followed by the next task or task waking up.
|
|
||||||
The format for both of these is PID:KERNEL-PRIO:TASK-STATE.
|
|
||||||
Remember that the KERNEL-PRIO is the inverse of the actual
|
|
||||||
priority with zero (0) being the highest priority and the nice
|
|
||||||
values starting at 100 (nice -20). Below is a quick chart to map
|
|
||||||
the kernel priority to user land priorities.
|
|
||||||
|
|
||||||
Kernel Space User Space
|
|
||||||
===============================================================
|
|
||||||
0(high) to 98(low) user RT priority 99(high) to 1(low)
|
|
||||||
with SCHED_RR or SCHED_FIFO
|
|
||||||
---------------------------------------------------------------
|
|
||||||
99 sched_priority is not used in scheduling
|
|
||||||
decisions(it must be specified as 0)
|
|
||||||
---------------------------------------------------------------
|
|
||||||
100(high) to 139(low) user nice -20(high) to 19(low)
|
|
||||||
---------------------------------------------------------------
|
|
||||||
140 idle task priority
|
|
||||||
---------------------------------------------------------------
|
|
||||||
|
|
||||||
The task states are:
|
|
||||||
|
|
||||||
R - running : wants to run, may not actually be running
|
|
||||||
S - sleep : process is waiting to be woken up (handles signals)
|
|
||||||
D - disk sleep (uninterruptible sleep) : process must be woken up
|
|
||||||
(ignores signals)
|
|
||||||
T - stopped : process suspended
|
|
||||||
t - traced : process is being traced (with something like gdb)
|
|
||||||
Z - zombie : process waiting to be cleaned up
|
|
||||||
X - unknown
|
|
||||||
|
|
||||||
|
|
||||||
ftrace_enabled
|
ftrace_enabled
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
@@ -607,10 +497,10 @@ an example:
|
|||||||
# echo irqsoff > current_tracer
|
# echo irqsoff > current_tracer
|
||||||
# echo latency-format > trace_options
|
# echo latency-format > trace_options
|
||||||
# echo 0 > tracing_max_latency
|
# echo 0 > tracing_max_latency
|
||||||
# echo 1 > tracing_enabled
|
# echo 1 > tracing_on
|
||||||
# ls -ltr
|
# ls -ltr
|
||||||
[...]
|
[...]
|
||||||
# echo 0 > tracing_enabled
|
# echo 0 > tracing_on
|
||||||
# cat trace
|
# cat trace
|
||||||
# tracer: irqsoff
|
# tracer: irqsoff
|
||||||
#
|
#
|
||||||
@@ -715,10 +605,10 @@ is much like the irqsoff tracer.
|
|||||||
# echo preemptoff > current_tracer
|
# echo preemptoff > current_tracer
|
||||||
# echo latency-format > trace_options
|
# echo latency-format > trace_options
|
||||||
# echo 0 > tracing_max_latency
|
# echo 0 > tracing_max_latency
|
||||||
# echo 1 > tracing_enabled
|
# echo 1 > tracing_on
|
||||||
# ls -ltr
|
# ls -ltr
|
||||||
[...]
|
[...]
|
||||||
# echo 0 > tracing_enabled
|
# echo 0 > tracing_on
|
||||||
# cat trace
|
# cat trace
|
||||||
# tracer: preemptoff
|
# tracer: preemptoff
|
||||||
#
|
#
|
||||||
@@ -863,10 +753,10 @@ tracers.
|
|||||||
# echo preemptirqsoff > current_tracer
|
# echo preemptirqsoff > current_tracer
|
||||||
# echo latency-format > trace_options
|
# echo latency-format > trace_options
|
||||||
# echo 0 > tracing_max_latency
|
# echo 0 > tracing_max_latency
|
||||||
# echo 1 > tracing_enabled
|
# echo 1 > tracing_on
|
||||||
# ls -ltr
|
# ls -ltr
|
||||||
[...]
|
[...]
|
||||||
# echo 0 > tracing_enabled
|
# echo 0 > tracing_on
|
||||||
# cat trace
|
# cat trace
|
||||||
# tracer: preemptirqsoff
|
# tracer: preemptirqsoff
|
||||||
#
|
#
|
||||||
@@ -1026,9 +916,9 @@ Instead of performing an 'ls', we will run 'sleep 1' under
|
|||||||
# echo wakeup > current_tracer
|
# echo wakeup > current_tracer
|
||||||
# echo latency-format > trace_options
|
# echo latency-format > trace_options
|
||||||
# echo 0 > tracing_max_latency
|
# echo 0 > tracing_max_latency
|
||||||
# echo 1 > tracing_enabled
|
# echo 1 > tracing_on
|
||||||
# chrt -f 5 sleep 1
|
# chrt -f 5 sleep 1
|
||||||
# echo 0 > tracing_enabled
|
# echo 0 > tracing_on
|
||||||
# cat trace
|
# cat trace
|
||||||
# tracer: wakeup
|
# tracer: wakeup
|
||||||
#
|
#
|
||||||
@@ -1140,9 +1030,9 @@ ftrace_enabled is set; otherwise this tracer is a nop.
|
|||||||
|
|
||||||
# sysctl kernel.ftrace_enabled=1
|
# sysctl kernel.ftrace_enabled=1
|
||||||
# echo function > current_tracer
|
# echo function > current_tracer
|
||||||
# echo 1 > tracing_enabled
|
# echo 1 > tracing_on
|
||||||
# usleep 1
|
# usleep 1
|
||||||
# echo 0 > tracing_enabled
|
# echo 0 > tracing_on
|
||||||
# cat trace
|
# cat trace
|
||||||
# tracer: function
|
# tracer: function
|
||||||
#
|
#
|
||||||
@@ -1180,7 +1070,7 @@ int trace_fd;
|
|||||||
[...]
|
[...]
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
[...]
|
[...]
|
||||||
trace_fd = open(tracing_file("tracing_enabled"), O_WRONLY);
|
trace_fd = open(tracing_file("tracing_on"), O_WRONLY);
|
||||||
[...]
|
[...]
|
||||||
if (condition_hit()) {
|
if (condition_hit()) {
|
||||||
write(trace_fd, "0", 1);
|
write(trace_fd, "0", 1);
|
||||||
@@ -1631,9 +1521,9 @@ If I am only interested in sys_nanosleep and hrtimer_interrupt:
|
|||||||
# echo sys_nanosleep hrtimer_interrupt \
|
# echo sys_nanosleep hrtimer_interrupt \
|
||||||
> set_ftrace_filter
|
> set_ftrace_filter
|
||||||
# echo function > current_tracer
|
# echo function > current_tracer
|
||||||
# echo 1 > tracing_enabled
|
# echo 1 > tracing_on
|
||||||
# usleep 1
|
# usleep 1
|
||||||
# echo 0 > tracing_enabled
|
# echo 0 > tracing_on
|
||||||
# cat trace
|
# cat trace
|
||||||
# tracer: ftrace
|
# tracer: ftrace
|
||||||
#
|
#
|
||||||
@@ -1879,9 +1769,9 @@ different. The trace is live.
|
|||||||
# echo function > current_tracer
|
# echo function > current_tracer
|
||||||
# cat trace_pipe > /tmp/trace.out &
|
# cat trace_pipe > /tmp/trace.out &
|
||||||
[1] 4153
|
[1] 4153
|
||||||
# echo 1 > tracing_enabled
|
# echo 1 > tracing_on
|
||||||
# usleep 1
|
# usleep 1
|
||||||
# echo 0 > tracing_enabled
|
# echo 0 > tracing_on
|
||||||
# cat trace
|
# cat trace
|
||||||
# tracer: function
|
# tracer: function
|
||||||
#
|
#
|
||||||
|
@@ -132,11 +132,11 @@ extern struct trace_event_functions exit_syscall_print_funcs;
|
|||||||
.class = &event_class_syscall_enter, \
|
.class = &event_class_syscall_enter, \
|
||||||
.event.funcs = &enter_syscall_print_funcs, \
|
.event.funcs = &enter_syscall_print_funcs, \
|
||||||
.data = (void *)&__syscall_meta_##sname,\
|
.data = (void *)&__syscall_meta_##sname,\
|
||||||
|
.flags = TRACE_EVENT_FL_CAP_ANY, \
|
||||||
}; \
|
}; \
|
||||||
static struct ftrace_event_call __used \
|
static struct ftrace_event_call __used \
|
||||||
__attribute__((section("_ftrace_events"))) \
|
__attribute__((section("_ftrace_events"))) \
|
||||||
*__event_enter_##sname = &event_enter_##sname; \
|
*__event_enter_##sname = &event_enter_##sname;
|
||||||
__TRACE_EVENT_FLAGS(enter_##sname, TRACE_EVENT_FL_CAP_ANY)
|
|
||||||
|
|
||||||
#define SYSCALL_TRACE_EXIT_EVENT(sname) \
|
#define SYSCALL_TRACE_EXIT_EVENT(sname) \
|
||||||
static struct syscall_metadata __syscall_meta_##sname; \
|
static struct syscall_metadata __syscall_meta_##sname; \
|
||||||
@@ -146,11 +146,11 @@ extern struct trace_event_functions exit_syscall_print_funcs;
|
|||||||
.class = &event_class_syscall_exit, \
|
.class = &event_class_syscall_exit, \
|
||||||
.event.funcs = &exit_syscall_print_funcs, \
|
.event.funcs = &exit_syscall_print_funcs, \
|
||||||
.data = (void *)&__syscall_meta_##sname,\
|
.data = (void *)&__syscall_meta_##sname,\
|
||||||
|
.flags = TRACE_EVENT_FL_CAP_ANY, \
|
||||||
}; \
|
}; \
|
||||||
static struct ftrace_event_call __used \
|
static struct ftrace_event_call __used \
|
||||||
__attribute__((section("_ftrace_events"))) \
|
__attribute__((section("_ftrace_events"))) \
|
||||||
*__event_exit_##sname = &event_exit_##sname; \
|
*__event_exit_##sname = &event_exit_##sname;
|
||||||
__TRACE_EVENT_FLAGS(exit_##sname, TRACE_EVENT_FL_CAP_ANY)
|
|
||||||
|
|
||||||
#define SYSCALL_METADATA(sname, nb) \
|
#define SYSCALL_METADATA(sname, nb) \
|
||||||
SYSCALL_TRACE_ENTER_EVENT(sname); \
|
SYSCALL_TRACE_ENTER_EVENT(sname); \
|
||||||
@@ -158,6 +158,7 @@ extern struct trace_event_functions exit_syscall_print_funcs;
|
|||||||
static struct syscall_metadata __used \
|
static struct syscall_metadata __used \
|
||||||
__syscall_meta_##sname = { \
|
__syscall_meta_##sname = { \
|
||||||
.name = "sys"#sname, \
|
.name = "sys"#sname, \
|
||||||
|
.syscall_nr = -1, /* Filled in at boot */ \
|
||||||
.nb_args = nb, \
|
.nb_args = nb, \
|
||||||
.types = types_##sname, \
|
.types = types_##sname, \
|
||||||
.args = args_##sname, \
|
.args = args_##sname, \
|
||||||
@@ -175,6 +176,7 @@ extern struct trace_event_functions exit_syscall_print_funcs;
|
|||||||
static struct syscall_metadata __used \
|
static struct syscall_metadata __used \
|
||||||
__syscall_meta__##sname = { \
|
__syscall_meta__##sname = { \
|
||||||
.name = "sys_"#sname, \
|
.name = "sys_"#sname, \
|
||||||
|
.syscall_nr = -1, /* Filled in at boot */ \
|
||||||
.nb_args = 0, \
|
.nb_args = 0, \
|
||||||
.enter_event = &event_enter__##sname, \
|
.enter_event = &event_enter__##sname, \
|
||||||
.exit_event = &event_exit__##sname, \
|
.exit_event = &event_exit__##sname, \
|
||||||
|
@@ -2163,10 +2163,14 @@ rb_reserve_next_event(struct ring_buffer *buffer,
|
|||||||
delta = diff;
|
delta = diff;
|
||||||
if (unlikely(test_time_stamp(delta))) {
|
if (unlikely(test_time_stamp(delta))) {
|
||||||
WARN_ONCE(delta > (1ULL << 59),
|
WARN_ONCE(delta > (1ULL << 59),
|
||||||
KERN_WARNING "Delta way too big! %llu ts=%llu write stamp = %llu\n",
|
KERN_WARNING "Delta way too big! %llu ts=%llu write stamp = %llu\n%s",
|
||||||
(unsigned long long)delta,
|
(unsigned long long)delta,
|
||||||
(unsigned long long)ts,
|
(unsigned long long)ts,
|
||||||
(unsigned long long)cpu_buffer->write_stamp);
|
(unsigned long long)cpu_buffer->write_stamp,
|
||||||
|
sched_clock_stable ? "" :
|
||||||
|
"If you just came from a suspend/resume,\n"
|
||||||
|
"please switch to the trace global clock:\n"
|
||||||
|
" echo global > /sys/kernel/debug/tracing/trace_clock\n");
|
||||||
add_timestamp = 1;
|
add_timestamp = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -2710,6 +2710,10 @@ tracing_ctrl_write(struct file *filp, const char __user *ubuf,
|
|||||||
|
|
||||||
mutex_lock(&trace_types_lock);
|
mutex_lock(&trace_types_lock);
|
||||||
if (tracer_enabled ^ val) {
|
if (tracer_enabled ^ val) {
|
||||||
|
|
||||||
|
/* Only need to warn if this is used to change the state */
|
||||||
|
WARN_ONCE(1, "tracing_enabled is deprecated. Use tracing_on");
|
||||||
|
|
||||||
if (val) {
|
if (val) {
|
||||||
tracer_enabled = 1;
|
tracer_enabled = 1;
|
||||||
if (current_trace->start)
|
if (current_trace->start)
|
||||||
|
@@ -247,51 +247,3 @@ void tracing_sched_switch_assign_trace(struct trace_array *tr)
|
|||||||
ctx_trace = tr;
|
ctx_trace = tr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void stop_sched_trace(struct trace_array *tr)
|
|
||||||
{
|
|
||||||
tracing_stop_sched_switch_record();
|
|
||||||
}
|
|
||||||
|
|
||||||
static int sched_switch_trace_init(struct trace_array *tr)
|
|
||||||
{
|
|
||||||
ctx_trace = tr;
|
|
||||||
tracing_reset_online_cpus(tr);
|
|
||||||
tracing_start_sched_switch_record();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void sched_switch_trace_reset(struct trace_array *tr)
|
|
||||||
{
|
|
||||||
if (sched_ref)
|
|
||||||
stop_sched_trace(tr);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void sched_switch_trace_start(struct trace_array *tr)
|
|
||||||
{
|
|
||||||
sched_stopped = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void sched_switch_trace_stop(struct trace_array *tr)
|
|
||||||
{
|
|
||||||
sched_stopped = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct tracer sched_switch_trace __read_mostly =
|
|
||||||
{
|
|
||||||
.name = "sched_switch",
|
|
||||||
.init = sched_switch_trace_init,
|
|
||||||
.reset = sched_switch_trace_reset,
|
|
||||||
.start = sched_switch_trace_start,
|
|
||||||
.stop = sched_switch_trace_stop,
|
|
||||||
.wait_pipe = poll_wait_pipe,
|
|
||||||
#ifdef CONFIG_FTRACE_SELFTEST
|
|
||||||
.selftest = trace_selftest_startup_sched_switch,
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
__init static int init_sched_switch_trace(void)
|
|
||||||
{
|
|
||||||
return register_tracer(&sched_switch_trace);
|
|
||||||
}
|
|
||||||
device_initcall(init_sched_switch_trace);
|
|
||||||
|
|
||||||
|
@@ -60,6 +60,19 @@ extern struct syscall_metadata *__stop_syscalls_metadata[];
|
|||||||
|
|
||||||
static struct syscall_metadata **syscalls_metadata;
|
static struct syscall_metadata **syscalls_metadata;
|
||||||
|
|
||||||
|
#ifndef ARCH_HAS_SYSCALL_MATCH_SYM_NAME
|
||||||
|
static inline bool arch_syscall_match_sym_name(const char *sym, const char *name)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Only compare after the "sys" prefix. Archs that use
|
||||||
|
* syscall wrappers may have syscalls symbols aliases prefixed
|
||||||
|
* with "SyS" instead of "sys", leading to an unwanted
|
||||||
|
* mismatch.
|
||||||
|
*/
|
||||||
|
return !strcmp(sym + 3, name + 3);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static __init struct syscall_metadata *
|
static __init struct syscall_metadata *
|
||||||
find_syscall_meta(unsigned long syscall)
|
find_syscall_meta(unsigned long syscall)
|
||||||
{
|
{
|
||||||
@@ -72,14 +85,11 @@ find_syscall_meta(unsigned long syscall)
|
|||||||
stop = __stop_syscalls_metadata;
|
stop = __stop_syscalls_metadata;
|
||||||
kallsyms_lookup(syscall, NULL, NULL, NULL, str);
|
kallsyms_lookup(syscall, NULL, NULL, NULL, str);
|
||||||
|
|
||||||
|
if (arch_syscall_match_sym_name(str, "sys_ni_syscall"))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
for ( ; start < stop; start++) {
|
for ( ; start < stop; start++) {
|
||||||
/*
|
if ((*start)->name && arch_syscall_match_sym_name(str, (*start)->name))
|
||||||
* Only compare after the "sys" prefix. Archs that use
|
|
||||||
* syscall wrappers may have syscalls symbols aliases prefixed
|
|
||||||
* with "SyS" instead of "sys", leading to an unwanted
|
|
||||||
* mismatch.
|
|
||||||
*/
|
|
||||||
if ((*start)->name && !strcmp((*start)->name + 3, str + 3))
|
|
||||||
return *start;
|
return *start;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -359,7 +369,7 @@ int reg_event_syscall_enter(struct ftrace_event_call *call)
|
|||||||
int num;
|
int num;
|
||||||
|
|
||||||
num = ((struct syscall_metadata *)call->data)->syscall_nr;
|
num = ((struct syscall_metadata *)call->data)->syscall_nr;
|
||||||
if (num < 0 || num >= NR_syscalls)
|
if (WARN_ON_ONCE(num < 0 || num >= NR_syscalls))
|
||||||
return -ENOSYS;
|
return -ENOSYS;
|
||||||
mutex_lock(&syscall_trace_lock);
|
mutex_lock(&syscall_trace_lock);
|
||||||
if (!sys_refcount_enter)
|
if (!sys_refcount_enter)
|
||||||
@@ -377,7 +387,7 @@ void unreg_event_syscall_enter(struct ftrace_event_call *call)
|
|||||||
int num;
|
int num;
|
||||||
|
|
||||||
num = ((struct syscall_metadata *)call->data)->syscall_nr;
|
num = ((struct syscall_metadata *)call->data)->syscall_nr;
|
||||||
if (num < 0 || num >= NR_syscalls)
|
if (WARN_ON_ONCE(num < 0 || num >= NR_syscalls))
|
||||||
return;
|
return;
|
||||||
mutex_lock(&syscall_trace_lock);
|
mutex_lock(&syscall_trace_lock);
|
||||||
sys_refcount_enter--;
|
sys_refcount_enter--;
|
||||||
@@ -393,7 +403,7 @@ int reg_event_syscall_exit(struct ftrace_event_call *call)
|
|||||||
int num;
|
int num;
|
||||||
|
|
||||||
num = ((struct syscall_metadata *)call->data)->syscall_nr;
|
num = ((struct syscall_metadata *)call->data)->syscall_nr;
|
||||||
if (num < 0 || num >= NR_syscalls)
|
if (WARN_ON_ONCE(num < 0 || num >= NR_syscalls))
|
||||||
return -ENOSYS;
|
return -ENOSYS;
|
||||||
mutex_lock(&syscall_trace_lock);
|
mutex_lock(&syscall_trace_lock);
|
||||||
if (!sys_refcount_exit)
|
if (!sys_refcount_exit)
|
||||||
@@ -411,7 +421,7 @@ void unreg_event_syscall_exit(struct ftrace_event_call *call)
|
|||||||
int num;
|
int num;
|
||||||
|
|
||||||
num = ((struct syscall_metadata *)call->data)->syscall_nr;
|
num = ((struct syscall_metadata *)call->data)->syscall_nr;
|
||||||
if (num < 0 || num >= NR_syscalls)
|
if (WARN_ON_ONCE(num < 0 || num >= NR_syscalls))
|
||||||
return;
|
return;
|
||||||
mutex_lock(&syscall_trace_lock);
|
mutex_lock(&syscall_trace_lock);
|
||||||
sys_refcount_exit--;
|
sys_refcount_exit--;
|
||||||
@@ -424,6 +434,14 @@ void unreg_event_syscall_exit(struct ftrace_event_call *call)
|
|||||||
int init_syscall_trace(struct ftrace_event_call *call)
|
int init_syscall_trace(struct ftrace_event_call *call)
|
||||||
{
|
{
|
||||||
int id;
|
int id;
|
||||||
|
int num;
|
||||||
|
|
||||||
|
num = ((struct syscall_metadata *)call->data)->syscall_nr;
|
||||||
|
if (num < 0 || num >= NR_syscalls) {
|
||||||
|
pr_debug("syscall %s metadata not mapped, disabling ftrace event\n",
|
||||||
|
((struct syscall_metadata *)call->data)->name);
|
||||||
|
return -ENOSYS;
|
||||||
|
}
|
||||||
|
|
||||||
if (set_syscall_print_fmt(call) < 0)
|
if (set_syscall_print_fmt(call) < 0)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
@@ -438,7 +456,7 @@ int init_syscall_trace(struct ftrace_event_call *call)
|
|||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned long __init arch_syscall_addr(int nr)
|
unsigned long __init __weak arch_syscall_addr(int nr)
|
||||||
{
|
{
|
||||||
return (unsigned long)sys_call_table[nr];
|
return (unsigned long)sys_call_table[nr];
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
#!/usr/bin/perl -w
|
#!/usr/bin/perl -w
|
||||||
#
|
#
|
||||||
# Copywrite 2005-2009 - Steven Rostedt
|
# Copyright 2005-2009 - Steven Rostedt
|
||||||
# Licensed under the terms of the GNU GPL License version 2
|
# Licensed under the terms of the GNU GPL License version 2
|
||||||
#
|
#
|
||||||
# It's simple enough to figure out how this works.
|
# It's simple enough to figure out how this works.
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
#!/usr/bin/perl -w
|
#!/usr/bin/perl -w
|
||||||
#
|
#
|
||||||
# Copywrite 2010 - Steven Rostedt <srostedt@redhat.com>, Red Hat Inc.
|
# Copyright 2010 - Steven Rostedt <srostedt@redhat.com>, Red Hat Inc.
|
||||||
# Licensed under the terms of the GNU GPL License version 2
|
# Licensed under the terms of the GNU GPL License version 2
|
||||||
#
|
#
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user