aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorStanislav Fomichev <stfomichev@yandex-team.ru>2014-06-26 12:14:28 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2014-06-26 16:48:07 -0400
commite281a9606d7073c517f2571e83faaff029ddc1cf (patch)
tree98e5e31514d4573cb03dfc469610613afc38b3f1 /tools
parent1e28fe0a4ff8680d5a0fb84995fd2444dac19cc4 (diff)
perf trace: Add possibility to switch off syscall events
Currently, we may either trace syscalls or syscalls+pagefaults. We'd like to be able to trace *only* pagefaults and this commit implements this feature. Example: [root@zoo /]# echo 1 > /proc/sys/vm/drop_caches ; trace --no-syscalls -F -p `pidof xchat` 0.000 ( 0.000 ms): xchat/4574 majfault [g_unichar_get_script+0x11] => /usr/lib64/libglib-2.0.so.0.3800.2@0xc403b (x.) 0.202 ( 0.000 ms): xchat/4574 majfault [_cairo_hash_table_lookup+0x53] => 0x2280ff0 (?.) 20.854 ( 0.000 ms): xchat/4574 majfault [gdk_cairo_set_source_pixbuf+0x110] => /usr/bin/xchat@0x6da1f (x.) 1022.000 ( 0.000 ms): xchat/4574 majfault [__memcpy_sse2_unaligned+0x29] => 0x7ff5a8ca0400 (?.) ^C[root@zoo /]# Below we can see malloc calls, 'trace' reading symbol tables in libraries to resolve symbols, etc. [root@zoo /]# echo 1 > /proc/sys/vm/drop_caches ; trace --no-syscalls -F all --cpu 1 sleep 10 0.000 ( 0.000 ms): chrome/26589 minfault [0x1b53129] => /tmp/perf-26589.map@0x33cbcbf7f000 (x.) 96.477 ( 0.000 ms): libvirtd/947 minfault [copy_user_enhanced_fast_string+0x5] => 0x7f7685bba000 (?k) 113.164 ( 0.000 ms): Xorg/1063 minfault [0x786da] => 0x7fce52882a3c (?.) 7162.801 ( 0.000 ms): chrome/3747 minfault [0x8e1a89] => 0xfcaefed0008 (?.) <SNIP> 7773.138 ( 0.000 ms): chrome/3886 minfault [0x8e1a89] => 0xfcb0ce28008 (?.) 7992.022 ( 0.000 ms): chrome/26574 minfault [0x1b5a708] => 0x3de7b5fc5000 (?.) 8108.949 ( 0.000 ms): qemu-system-x8/4537 majfault [_int_malloc+0xee] => 0x7faffc466d60 (?.) 8108.975 ( 0.000 ms): qemu-system-x8/4537 minfault [_int_malloc+0x102] => 0x7faffc466d60 (?.) <SNIP> 8148.174 ( 0.000 ms): qemu-system-x8/4537 minfault [_int_malloc+0x102] => 0x7faffc4eb500 (?.) 8270.855 ( 0.000 ms): chrome/26245 minfault [do_bo_emit_reloc+0xdb] => 0x45d092bc004 (?.) 8270.869 ( 0.000 ms): chrome/26245 minfault [do_bo_emit_reloc+0x108] => 0x45d09150000 (?.) no symbols found in /usr/lib64/libspice-server.so.1.9.0, maybe install a debug package? 8273.831 ( 0.000 ms): trace/20198 majfault [__memcmp_sse4_1+0xbc6] => /usr/lib64/libspice-server.so.1.9.0@0xdf000 (d.) <SNIP> 8275.121 ( 0.000 ms): trace/20198 minfault [dso__load+0x38] => 0x14fe756 (?.) no symbols found in /usr/lib64/libelf-0.158.so, maybe install a debug package? 8275.142 ( 0.000 ms): trace/20198 minfault [__memcmp_sse4_1+0xbc6] => /usr/lib64/libelf-0.158.so@0x0 (d.) <SNIP> [root@zoo /]# Signed-off-by: Stanislav Fomichev <stfomichev@yandex-team.ru> Cc: David Ahern <dsahern@gmail.com> Cc: Ingo Molnar <mingo@redhat.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Link: http://lkml.kernel.org/r/1403799268-1367-6-git-send-email-stfomichev@yandex-team.ru Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools')
-rw-r--r--tools/perf/Documentation/perf-trace.txt7
-rw-r--r--tools/perf/builtin-trace.c58
2 files changed, 39 insertions, 26 deletions
diff --git a/tools/perf/Documentation/perf-trace.txt b/tools/perf/Documentation/perf-trace.txt
index 72397d9aa2ec..02aac831bdd9 100644
--- a/tools/perf/Documentation/perf-trace.txt
+++ b/tools/perf/Documentation/perf-trace.txt
@@ -112,6 +112,9 @@ the thread executes on the designated CPUs. Default is to monitor all CPUs.
112 Trace pagefaults. Optionally, you can specify whether you want minor, 112 Trace pagefaults. Optionally, you can specify whether you want minor,
113 major or all pagefaults. Default value is maj. 113 major or all pagefaults. Default value is maj.
114 114
115--syscalls::
116 Trace system calls. This options is enabled by default.
117
115PAGEFAULTS 118PAGEFAULTS
116---------- 119----------
117 120
@@ -137,6 +140,10 @@ for both IP and fault address in the form of dso@symbol+offset.
137EXAMPLES 140EXAMPLES
138-------- 141--------
139 142
143Trace only major pagefaults:
144
145 $ perf trace --no-syscalls -F
146
140Trace syscalls, major and minor pagefaults: 147Trace syscalls, major and minor pagefaults:
141 148
142 $ perf trace -F all 149 $ perf trace -F all
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 0b58e24c7ccb..dc7a694b61fe 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -1215,6 +1215,7 @@ struct trace {
1215 bool summary_only; 1215 bool summary_only;
1216 bool show_comm; 1216 bool show_comm;
1217 bool show_tool_stats; 1217 bool show_tool_stats;
1218 bool trace_syscalls;
1218 int trace_pgfaults; 1219 int trace_pgfaults;
1219}; 1220};
1220 1221
@@ -1927,17 +1928,19 @@ static int trace__record(struct trace *trace, int argc, const char **argv)
1927 for (i = 0; i < ARRAY_SIZE(record_args); i++) 1928 for (i = 0; i < ARRAY_SIZE(record_args); i++)
1928 rec_argv[j++] = record_args[i]; 1929 rec_argv[j++] = record_args[i];
1929 1930
1930 for (i = 0; i < sc_args_nr; i++) 1931 if (trace->trace_syscalls) {
1931 rec_argv[j++] = sc_args[i]; 1932 for (i = 0; i < sc_args_nr; i++)
1932 1933 rec_argv[j++] = sc_args[i];
1933 /* event string may be different for older kernels - e.g., RHEL6 */ 1934
1934 if (is_valid_tracepoint("raw_syscalls:sys_enter")) 1935 /* event string may be different for older kernels - e.g., RHEL6 */
1935 rec_argv[j++] = "raw_syscalls:sys_enter,raw_syscalls:sys_exit"; 1936 if (is_valid_tracepoint("raw_syscalls:sys_enter"))
1936 else if (is_valid_tracepoint("syscalls:sys_enter")) 1937 rec_argv[j++] = "raw_syscalls:sys_enter,raw_syscalls:sys_exit";
1937 rec_argv[j++] = "syscalls:sys_enter,syscalls:sys_exit"; 1938 else if (is_valid_tracepoint("syscalls:sys_enter"))
1938 else { 1939 rec_argv[j++] = "syscalls:sys_enter,syscalls:sys_exit";
1939 pr_err("Neither raw_syscalls nor syscalls events exist.\n"); 1940 else {
1940 return -1; 1941 pr_err("Neither raw_syscalls nor syscalls events exist.\n");
1942 return -1;
1943 }
1941 } 1944 }
1942 1945
1943 if (trace->trace_pgfaults & TRACE_PFMAJ) 1946 if (trace->trace_pgfaults & TRACE_PFMAJ)
@@ -2010,10 +2013,13 @@ static int trace__run(struct trace *trace, int argc, const char **argv)
2010 goto out; 2013 goto out;
2011 } 2014 }
2012 2015
2013 if (perf_evlist__add_syscall_newtp(evlist, trace__sys_enter, trace__sys_exit)) 2016 if (trace->trace_syscalls &&
2017 perf_evlist__add_syscall_newtp(evlist, trace__sys_enter,
2018 trace__sys_exit))
2014 goto out_error_tp; 2019 goto out_error_tp;
2015 2020
2016 perf_evlist__add_vfs_getname(evlist); 2021 if (trace->trace_syscalls)
2022 perf_evlist__add_vfs_getname(evlist);
2017 2023
2018 if ((trace->trace_pgfaults & TRACE_PFMAJ) && 2024 if ((trace->trace_pgfaults & TRACE_PFMAJ) &&
2019 perf_evlist__add_pgfault(evlist, PERF_COUNT_SW_PAGE_FAULTS_MAJ)) 2025 perf_evlist__add_pgfault(evlist, PERF_COUNT_SW_PAGE_FAULTS_MAJ))
@@ -2215,13 +2221,10 @@ static int trace__replay(struct trace *trace)
2215 if (evsel == NULL) 2221 if (evsel == NULL)
2216 evsel = perf_evlist__find_tracepoint_by_name(session->evlist, 2222 evsel = perf_evlist__find_tracepoint_by_name(session->evlist,
2217 "syscalls:sys_enter"); 2223 "syscalls:sys_enter");
2218 if (evsel == NULL) {
2219 pr_err("Data file does not have raw_syscalls:sys_enter event\n");
2220 goto out;
2221 }
2222 2224
2223 if (perf_evsel__init_syscall_tp(evsel, trace__sys_enter) < 0 || 2225 if (evsel &&
2224 perf_evsel__init_sc_tp_ptr_field(evsel, args)) { 2226 (perf_evsel__init_syscall_tp(evsel, trace__sys_enter) < 0 ||
2227 perf_evsel__init_sc_tp_ptr_field(evsel, args))) {
2225 pr_err("Error during initialize raw_syscalls:sys_enter event\n"); 2228 pr_err("Error during initialize raw_syscalls:sys_enter event\n");
2226 goto out; 2229 goto out;
2227 } 2230 }
@@ -2231,13 +2234,9 @@ static int trace__replay(struct trace *trace)
2231 if (evsel == NULL) 2234 if (evsel == NULL)
2232 evsel = perf_evlist__find_tracepoint_by_name(session->evlist, 2235 evsel = perf_evlist__find_tracepoint_by_name(session->evlist,
2233 "syscalls:sys_exit"); 2236 "syscalls:sys_exit");
2234 if (evsel == NULL) { 2237 if (evsel &&
2235 pr_err("Data file does not have raw_syscalls:sys_exit event\n"); 2238 (perf_evsel__init_syscall_tp(evsel, trace__sys_exit) < 0 ||
2236 goto out; 2239 perf_evsel__init_sc_tp_uint_field(evsel, ret))) {
2237 }
2238
2239 if (perf_evsel__init_syscall_tp(evsel, trace__sys_exit) < 0 ||
2240 perf_evsel__init_sc_tp_uint_field(evsel, ret)) {
2241 pr_err("Error during initialize raw_syscalls:sys_exit event\n"); 2240 pr_err("Error during initialize raw_syscalls:sys_exit event\n");
2242 goto out; 2241 goto out;
2243 } 2242 }
@@ -2440,6 +2439,7 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)
2440 }, 2439 },
2441 .output = stdout, 2440 .output = stdout,
2442 .show_comm = true, 2441 .show_comm = true,
2442 .trace_syscalls = true,
2443 }; 2443 };
2444 const char *output_name = NULL; 2444 const char *output_name = NULL;
2445 const char *ev_qualifier_str = NULL; 2445 const char *ev_qualifier_str = NULL;
@@ -2479,6 +2479,7 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)
2479 "Show all syscalls and summary with statistics"), 2479 "Show all syscalls and summary with statistics"),
2480 OPT_CALLBACK_DEFAULT('F', "pf", &trace.trace_pgfaults, "all|maj|min", 2480 OPT_CALLBACK_DEFAULT('F', "pf", &trace.trace_pgfaults, "all|maj|min",
2481 "Trace pagefaults", parse_pagefaults, "maj"), 2481 "Trace pagefaults", parse_pagefaults, "maj"),
2482 OPT_BOOLEAN(0, "syscalls", &trace.trace_syscalls, "Trace syscalls"),
2482 OPT_END() 2483 OPT_END()
2483 }; 2484 };
2484 int err; 2485 int err;
@@ -2499,6 +2500,11 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)
2499 if (trace.summary_only) 2500 if (trace.summary_only)
2500 trace.summary = trace.summary_only; 2501 trace.summary = trace.summary_only;
2501 2502
2503 if (!trace.trace_syscalls && !trace.trace_pgfaults) {
2504 pr_err("Please specify something to trace.\n");
2505 return -1;
2506 }
2507
2502 if (output_name != NULL) { 2508 if (output_name != NULL) {
2503 err = trace__open_output(&trace, output_name); 2509 err = trace__open_output(&trace, output_name);
2504 if (err < 0) { 2510 if (err < 0) {