diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2019-04-01 01:42:04 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2019-04-01 01:42:04 -0400 |
commit | 8cdfd068c1ea54cca7d7ad6ad31335cc5d0d9905 (patch) | |
tree | 26a36ec23067a9e26baf3d46c65f70619ca4d808 /tools/perf/builtin-script.c | |
parent | 4d537f37e0d39f64687be71087dca607ee507f5a (diff) | |
parent | 79a3aaa7b82e3106be97842dedfd8429248896e6 (diff) |
Merge 5.1-rc3 into usb-next
We want the USB fixes in here as well.
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'tools/perf/builtin-script.c')
-rw-r--r-- | tools/perf/builtin-script.c | 129 |
1 files changed, 94 insertions, 35 deletions
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 53f78cf3113f..61cfd8f70989 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c | |||
@@ -29,10 +29,12 @@ | |||
29 | #include "util/time-utils.h" | 29 | #include "util/time-utils.h" |
30 | #include "util/path.h" | 30 | #include "util/path.h" |
31 | #include "print_binary.h" | 31 | #include "print_binary.h" |
32 | #include "archinsn.h" | ||
32 | #include <linux/bitmap.h> | 33 | #include <linux/bitmap.h> |
33 | #include <linux/kernel.h> | 34 | #include <linux/kernel.h> |
34 | #include <linux/stringify.h> | 35 | #include <linux/stringify.h> |
35 | #include <linux/time64.h> | 36 | #include <linux/time64.h> |
37 | #include <sys/utsname.h> | ||
36 | #include "asm/bug.h" | 38 | #include "asm/bug.h" |
37 | #include "util/mem-events.h" | 39 | #include "util/mem-events.h" |
38 | #include "util/dump-insn.h" | 40 | #include "util/dump-insn.h" |
@@ -51,6 +53,8 @@ | |||
51 | 53 | ||
52 | static char const *script_name; | 54 | static char const *script_name; |
53 | static char const *generate_script_lang; | 55 | static char const *generate_script_lang; |
56 | static bool reltime; | ||
57 | static u64 initial_time; | ||
54 | static bool debug_mode; | 58 | static bool debug_mode; |
55 | static u64 last_timestamp; | 59 | static u64 last_timestamp; |
56 | static u64 nr_unordered; | 60 | static u64 nr_unordered; |
@@ -58,11 +62,11 @@ static bool no_callchain; | |||
58 | static bool latency_format; | 62 | static bool latency_format; |
59 | static bool system_wide; | 63 | static bool system_wide; |
60 | static bool print_flags; | 64 | static bool print_flags; |
61 | static bool nanosecs; | ||
62 | static const char *cpu_list; | 65 | static const char *cpu_list; |
63 | static DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS); | 66 | static DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS); |
64 | static struct perf_stat_config stat_config; | 67 | static struct perf_stat_config stat_config; |
65 | static int max_blocks; | 68 | static int max_blocks; |
69 | static bool native_arch; | ||
66 | 70 | ||
67 | unsigned int scripting_max_stack = PERF_MAX_STACK_DEPTH; | 71 | unsigned int scripting_max_stack = PERF_MAX_STACK_DEPTH; |
68 | 72 | ||
@@ -684,15 +688,21 @@ static int perf_sample__fprintf_start(struct perf_sample *sample, | |||
684 | } | 688 | } |
685 | 689 | ||
686 | if (PRINT_FIELD(TIME)) { | 690 | if (PRINT_FIELD(TIME)) { |
687 | nsecs = sample->time; | 691 | u64 t = sample->time; |
692 | if (reltime) { | ||
693 | if (!initial_time) | ||
694 | initial_time = sample->time; | ||
695 | t = sample->time - initial_time; | ||
696 | } | ||
697 | nsecs = t; | ||
688 | secs = nsecs / NSEC_PER_SEC; | 698 | secs = nsecs / NSEC_PER_SEC; |
689 | nsecs -= secs * NSEC_PER_SEC; | 699 | nsecs -= secs * NSEC_PER_SEC; |
690 | 700 | ||
691 | if (nanosecs) | 701 | if (symbol_conf.nanosecs) |
692 | printed += fprintf(fp, "%5lu.%09llu: ", secs, nsecs); | 702 | printed += fprintf(fp, "%5lu.%09llu: ", secs, nsecs); |
693 | else { | 703 | else { |
694 | char sample_time[32]; | 704 | char sample_time[32]; |
695 | timestamp__scnprintf_usec(sample->time, sample_time, sizeof(sample_time)); | 705 | timestamp__scnprintf_usec(t, sample_time, sizeof(sample_time)); |
696 | printed += fprintf(fp, "%12s: ", sample_time); | 706 | printed += fprintf(fp, "%12s: ", sample_time); |
697 | } | 707 | } |
698 | } | 708 | } |
@@ -1227,6 +1237,12 @@ static int perf_sample__fprintf_callindent(struct perf_sample *sample, | |||
1227 | return len + dlen; | 1237 | return len + dlen; |
1228 | } | 1238 | } |
1229 | 1239 | ||
1240 | __weak void arch_fetch_insn(struct perf_sample *sample __maybe_unused, | ||
1241 | struct thread *thread __maybe_unused, | ||
1242 | struct machine *machine __maybe_unused) | ||
1243 | { | ||
1244 | } | ||
1245 | |||
1230 | static int perf_sample__fprintf_insn(struct perf_sample *sample, | 1246 | static int perf_sample__fprintf_insn(struct perf_sample *sample, |
1231 | struct perf_event_attr *attr, | 1247 | struct perf_event_attr *attr, |
1232 | struct thread *thread, | 1248 | struct thread *thread, |
@@ -1234,9 +1250,12 @@ static int perf_sample__fprintf_insn(struct perf_sample *sample, | |||
1234 | { | 1250 | { |
1235 | int printed = 0; | 1251 | int printed = 0; |
1236 | 1252 | ||
1253 | if (sample->insn_len == 0 && native_arch) | ||
1254 | arch_fetch_insn(sample, thread, machine); | ||
1255 | |||
1237 | if (PRINT_FIELD(INSNLEN)) | 1256 | if (PRINT_FIELD(INSNLEN)) |
1238 | printed += fprintf(fp, " ilen: %d", sample->insn_len); | 1257 | printed += fprintf(fp, " ilen: %d", sample->insn_len); |
1239 | if (PRINT_FIELD(INSN)) { | 1258 | if (PRINT_FIELD(INSN) && sample->insn_len) { |
1240 | int i; | 1259 | int i; |
1241 | 1260 | ||
1242 | printed += fprintf(fp, " insn:"); | 1261 | printed += fprintf(fp, " insn:"); |
@@ -1922,6 +1941,13 @@ static int cleanup_scripting(void) | |||
1922 | return scripting_ops ? scripting_ops->stop_script() : 0; | 1941 | return scripting_ops ? scripting_ops->stop_script() : 0; |
1923 | } | 1942 | } |
1924 | 1943 | ||
1944 | static bool filter_cpu(struct perf_sample *sample) | ||
1945 | { | ||
1946 | if (cpu_list) | ||
1947 | return !test_bit(sample->cpu, cpu_bitmap); | ||
1948 | return false; | ||
1949 | } | ||
1950 | |||
1925 | static int process_sample_event(struct perf_tool *tool, | 1951 | static int process_sample_event(struct perf_tool *tool, |
1926 | union perf_event *event, | 1952 | union perf_event *event, |
1927 | struct perf_sample *sample, | 1953 | struct perf_sample *sample, |
@@ -1956,7 +1982,7 @@ static int process_sample_event(struct perf_tool *tool, | |||
1956 | if (al.filtered) | 1982 | if (al.filtered) |
1957 | goto out_put; | 1983 | goto out_put; |
1958 | 1984 | ||
1959 | if (cpu_list && !test_bit(sample->cpu, cpu_bitmap)) | 1985 | if (filter_cpu(sample)) |
1960 | goto out_put; | 1986 | goto out_put; |
1961 | 1987 | ||
1962 | if (scripting_ops) | 1988 | if (scripting_ops) |
@@ -2041,9 +2067,11 @@ static int process_comm_event(struct perf_tool *tool, | |||
2041 | sample->tid = event->comm.tid; | 2067 | sample->tid = event->comm.tid; |
2042 | sample->pid = event->comm.pid; | 2068 | sample->pid = event->comm.pid; |
2043 | } | 2069 | } |
2044 | perf_sample__fprintf_start(sample, thread, evsel, | 2070 | if (!filter_cpu(sample)) { |
2071 | perf_sample__fprintf_start(sample, thread, evsel, | ||
2045 | PERF_RECORD_COMM, stdout); | 2072 | PERF_RECORD_COMM, stdout); |
2046 | perf_event__fprintf(event, stdout); | 2073 | perf_event__fprintf(event, stdout); |
2074 | } | ||
2047 | ret = 0; | 2075 | ret = 0; |
2048 | out: | 2076 | out: |
2049 | thread__put(thread); | 2077 | thread__put(thread); |
@@ -2077,9 +2105,11 @@ static int process_namespaces_event(struct perf_tool *tool, | |||
2077 | sample->tid = event->namespaces.tid; | 2105 | sample->tid = event->namespaces.tid; |
2078 | sample->pid = event->namespaces.pid; | 2106 | sample->pid = event->namespaces.pid; |
2079 | } | 2107 | } |
2080 | perf_sample__fprintf_start(sample, thread, evsel, | 2108 | if (!filter_cpu(sample)) { |
2081 | PERF_RECORD_NAMESPACES, stdout); | 2109 | perf_sample__fprintf_start(sample, thread, evsel, |
2082 | perf_event__fprintf(event, stdout); | 2110 | PERF_RECORD_NAMESPACES, stdout); |
2111 | perf_event__fprintf(event, stdout); | ||
2112 | } | ||
2083 | ret = 0; | 2113 | ret = 0; |
2084 | out: | 2114 | out: |
2085 | thread__put(thread); | 2115 | thread__put(thread); |
@@ -2111,9 +2141,11 @@ static int process_fork_event(struct perf_tool *tool, | |||
2111 | sample->tid = event->fork.tid; | 2141 | sample->tid = event->fork.tid; |
2112 | sample->pid = event->fork.pid; | 2142 | sample->pid = event->fork.pid; |
2113 | } | 2143 | } |
2114 | perf_sample__fprintf_start(sample, thread, evsel, | 2144 | if (!filter_cpu(sample)) { |
2115 | PERF_RECORD_FORK, stdout); | 2145 | perf_sample__fprintf_start(sample, thread, evsel, |
2116 | perf_event__fprintf(event, stdout); | 2146 | PERF_RECORD_FORK, stdout); |
2147 | perf_event__fprintf(event, stdout); | ||
2148 | } | ||
2117 | thread__put(thread); | 2149 | thread__put(thread); |
2118 | 2150 | ||
2119 | return 0; | 2151 | return 0; |
@@ -2141,9 +2173,11 @@ static int process_exit_event(struct perf_tool *tool, | |||
2141 | sample->tid = event->fork.tid; | 2173 | sample->tid = event->fork.tid; |
2142 | sample->pid = event->fork.pid; | 2174 | sample->pid = event->fork.pid; |
2143 | } | 2175 | } |
2144 | perf_sample__fprintf_start(sample, thread, evsel, | 2176 | if (!filter_cpu(sample)) { |
2145 | PERF_RECORD_EXIT, stdout); | 2177 | perf_sample__fprintf_start(sample, thread, evsel, |
2146 | perf_event__fprintf(event, stdout); | 2178 | PERF_RECORD_EXIT, stdout); |
2179 | perf_event__fprintf(event, stdout); | ||
2180 | } | ||
2147 | 2181 | ||
2148 | if (perf_event__process_exit(tool, event, sample, machine) < 0) | 2182 | if (perf_event__process_exit(tool, event, sample, machine) < 0) |
2149 | err = -1; | 2183 | err = -1; |
@@ -2177,9 +2211,11 @@ static int process_mmap_event(struct perf_tool *tool, | |||
2177 | sample->tid = event->mmap.tid; | 2211 | sample->tid = event->mmap.tid; |
2178 | sample->pid = event->mmap.pid; | 2212 | sample->pid = event->mmap.pid; |
2179 | } | 2213 | } |
2180 | perf_sample__fprintf_start(sample, thread, evsel, | 2214 | if (!filter_cpu(sample)) { |
2181 | PERF_RECORD_MMAP, stdout); | 2215 | perf_sample__fprintf_start(sample, thread, evsel, |
2182 | perf_event__fprintf(event, stdout); | 2216 | PERF_RECORD_MMAP, stdout); |
2217 | perf_event__fprintf(event, stdout); | ||
2218 | } | ||
2183 | thread__put(thread); | 2219 | thread__put(thread); |
2184 | return 0; | 2220 | return 0; |
2185 | } | 2221 | } |
@@ -2209,9 +2245,11 @@ static int process_mmap2_event(struct perf_tool *tool, | |||
2209 | sample->tid = event->mmap2.tid; | 2245 | sample->tid = event->mmap2.tid; |
2210 | sample->pid = event->mmap2.pid; | 2246 | sample->pid = event->mmap2.pid; |
2211 | } | 2247 | } |
2212 | perf_sample__fprintf_start(sample, thread, evsel, | 2248 | if (!filter_cpu(sample)) { |
2213 | PERF_RECORD_MMAP2, stdout); | 2249 | perf_sample__fprintf_start(sample, thread, evsel, |
2214 | perf_event__fprintf(event, stdout); | 2250 | PERF_RECORD_MMAP2, stdout); |
2251 | perf_event__fprintf(event, stdout); | ||
2252 | } | ||
2215 | thread__put(thread); | 2253 | thread__put(thread); |
2216 | return 0; | 2254 | return 0; |
2217 | } | 2255 | } |
@@ -2236,9 +2274,11 @@ static int process_switch_event(struct perf_tool *tool, | |||
2236 | return -1; | 2274 | return -1; |
2237 | } | 2275 | } |
2238 | 2276 | ||
2239 | perf_sample__fprintf_start(sample, thread, evsel, | 2277 | if (!filter_cpu(sample)) { |
2240 | PERF_RECORD_SWITCH, stdout); | 2278 | perf_sample__fprintf_start(sample, thread, evsel, |
2241 | perf_event__fprintf(event, stdout); | 2279 | PERF_RECORD_SWITCH, stdout); |
2280 | perf_event__fprintf(event, stdout); | ||
2281 | } | ||
2242 | thread__put(thread); | 2282 | thread__put(thread); |
2243 | return 0; | 2283 | return 0; |
2244 | } | 2284 | } |
@@ -2259,9 +2299,11 @@ process_lost_event(struct perf_tool *tool, | |||
2259 | if (thread == NULL) | 2299 | if (thread == NULL) |
2260 | return -1; | 2300 | return -1; |
2261 | 2301 | ||
2262 | perf_sample__fprintf_start(sample, thread, evsel, | 2302 | if (!filter_cpu(sample)) { |
2263 | PERF_RECORD_LOST, stdout); | 2303 | perf_sample__fprintf_start(sample, thread, evsel, |
2264 | perf_event__fprintf(event, stdout); | 2304 | PERF_RECORD_LOST, stdout); |
2305 | perf_event__fprintf(event, stdout); | ||
2306 | } | ||
2265 | thread__put(thread); | 2307 | thread__put(thread); |
2266 | return 0; | 2308 | return 0; |
2267 | } | 2309 | } |
@@ -2948,7 +2990,8 @@ static int check_ev_match(char *dir_name, char *scriptname, | |||
2948 | * will list all statically runnable scripts, select one, execute it and | 2990 | * will list all statically runnable scripts, select one, execute it and |
2949 | * show the output in a perf browser. | 2991 | * show the output in a perf browser. |
2950 | */ | 2992 | */ |
2951 | int find_scripts(char **scripts_array, char **scripts_path_array) | 2993 | int find_scripts(char **scripts_array, char **scripts_path_array, int num, |
2994 | int pathlen) | ||
2952 | { | 2995 | { |
2953 | struct dirent *script_dirent, *lang_dirent; | 2996 | struct dirent *script_dirent, *lang_dirent; |
2954 | char scripts_path[MAXPATHLEN], lang_path[MAXPATHLEN]; | 2997 | char scripts_path[MAXPATHLEN], lang_path[MAXPATHLEN]; |
@@ -2993,7 +3036,10 @@ int find_scripts(char **scripts_array, char **scripts_path_array) | |||
2993 | /* Skip those real time scripts: xxxtop.p[yl] */ | 3036 | /* Skip those real time scripts: xxxtop.p[yl] */ |
2994 | if (strstr(script_dirent->d_name, "top.")) | 3037 | if (strstr(script_dirent->d_name, "top.")) |
2995 | continue; | 3038 | continue; |
2996 | sprintf(scripts_path_array[i], "%s/%s", lang_path, | 3039 | if (i >= num) |
3040 | break; | ||
3041 | snprintf(scripts_path_array[i], pathlen, "%s/%s", | ||
3042 | lang_path, | ||
2997 | script_dirent->d_name); | 3043 | script_dirent->d_name); |
2998 | temp = strchr(script_dirent->d_name, '.'); | 3044 | temp = strchr(script_dirent->d_name, '.'); |
2999 | snprintf(scripts_array[i], | 3045 | snprintf(scripts_array[i], |
@@ -3232,7 +3278,7 @@ static int parse_insn_trace(const struct option *opt __maybe_unused, | |||
3232 | { | 3278 | { |
3233 | parse_output_fields(NULL, "+insn,-event,-period", 0); | 3279 | parse_output_fields(NULL, "+insn,-event,-period", 0); |
3234 | itrace_parse_synth_opts(opt, "i0ns", 0); | 3280 | itrace_parse_synth_opts(opt, "i0ns", 0); |
3235 | nanosecs = true; | 3281 | symbol_conf.nanosecs = true; |
3236 | return 0; | 3282 | return 0; |
3237 | } | 3283 | } |
3238 | 3284 | ||
@@ -3250,7 +3296,7 @@ static int parse_call_trace(const struct option *opt __maybe_unused, | |||
3250 | { | 3296 | { |
3251 | parse_output_fields(NULL, "-ip,-addr,-event,-period,+callindent", 0); | 3297 | parse_output_fields(NULL, "-ip,-addr,-event,-period,+callindent", 0); |
3252 | itrace_parse_synth_opts(opt, "cewp", 0); | 3298 | itrace_parse_synth_opts(opt, "cewp", 0); |
3253 | nanosecs = true; | 3299 | symbol_conf.nanosecs = true; |
3254 | return 0; | 3300 | return 0; |
3255 | } | 3301 | } |
3256 | 3302 | ||
@@ -3260,7 +3306,7 @@ static int parse_callret_trace(const struct option *opt __maybe_unused, | |||
3260 | { | 3306 | { |
3261 | parse_output_fields(NULL, "-ip,-addr,-event,-period,+callindent,+flags", 0); | 3307 | parse_output_fields(NULL, "-ip,-addr,-event,-period,+callindent,+flags", 0); |
3262 | itrace_parse_synth_opts(opt, "crewp", 0); | 3308 | itrace_parse_synth_opts(opt, "crewp", 0); |
3263 | nanosecs = true; | 3309 | symbol_conf.nanosecs = true; |
3264 | return 0; | 3310 | return 0; |
3265 | } | 3311 | } |
3266 | 3312 | ||
@@ -3277,6 +3323,7 @@ int cmd_script(int argc, const char **argv) | |||
3277 | .set = false, | 3323 | .set = false, |
3278 | .default_no_sample = true, | 3324 | .default_no_sample = true, |
3279 | }; | 3325 | }; |
3326 | struct utsname uts; | ||
3280 | char *script_path = NULL; | 3327 | char *script_path = NULL; |
3281 | const char **__argv; | 3328 | const char **__argv; |
3282 | int i, j, err = 0; | 3329 | int i, j, err = 0; |
@@ -3374,6 +3421,7 @@ int cmd_script(int argc, const char **argv) | |||
3374 | "Set the maximum stack depth when parsing the callchain, " | 3421 | "Set the maximum stack depth when parsing the callchain, " |
3375 | "anything beyond the specified depth will be ignored. " | 3422 | "anything beyond the specified depth will be ignored. " |
3376 | "Default: kernel.perf_event_max_stack or " __stringify(PERF_MAX_STACK_DEPTH)), | 3423 | "Default: kernel.perf_event_max_stack or " __stringify(PERF_MAX_STACK_DEPTH)), |
3424 | OPT_BOOLEAN(0, "reltime", &reltime, "Show time stamps relative to start"), | ||
3377 | OPT_BOOLEAN('I', "show-info", &show_full_info, | 3425 | OPT_BOOLEAN('I', "show-info", &show_full_info, |
3378 | "display extended information from perf.data file"), | 3426 | "display extended information from perf.data file"), |
3379 | OPT_BOOLEAN('\0', "show-kernel-path", &symbol_conf.show_kernel_path, | 3427 | OPT_BOOLEAN('\0', "show-kernel-path", &symbol_conf.show_kernel_path, |
@@ -3395,7 +3443,7 @@ int cmd_script(int argc, const char **argv) | |||
3395 | OPT_BOOLEAN('f', "force", &symbol_conf.force, "don't complain, do it"), | 3443 | OPT_BOOLEAN('f', "force", &symbol_conf.force, "don't complain, do it"), |
3396 | OPT_INTEGER(0, "max-blocks", &max_blocks, | 3444 | OPT_INTEGER(0, "max-blocks", &max_blocks, |
3397 | "Maximum number of code blocks to dump with brstackinsn"), | 3445 | "Maximum number of code blocks to dump with brstackinsn"), |
3398 | OPT_BOOLEAN(0, "ns", &nanosecs, | 3446 | OPT_BOOLEAN(0, "ns", &symbol_conf.nanosecs, |
3399 | "Use 9 decimal places when displaying time"), | 3447 | "Use 9 decimal places when displaying time"), |
3400 | OPT_CALLBACK_OPTARG(0, "itrace", &itrace_synth_opts, NULL, "opts", | 3448 | OPT_CALLBACK_OPTARG(0, "itrace", &itrace_synth_opts, NULL, "opts", |
3401 | "Instruction Tracing options\n" ITRACE_HELP, | 3449 | "Instruction Tracing options\n" ITRACE_HELP, |
@@ -3448,6 +3496,11 @@ int cmd_script(int argc, const char **argv) | |||
3448 | } | 3496 | } |
3449 | } | 3497 | } |
3450 | 3498 | ||
3499 | if (script.time_str && reltime) { | ||
3500 | fprintf(stderr, "Don't combine --reltime with --time\n"); | ||
3501 | return -1; | ||
3502 | } | ||
3503 | |||
3451 | if (itrace_synth_opts.callchain && | 3504 | if (itrace_synth_opts.callchain && |
3452 | itrace_synth_opts.callchain_sz > scripting_max_stack) | 3505 | itrace_synth_opts.callchain_sz > scripting_max_stack) |
3453 | scripting_max_stack = itrace_synth_opts.callchain_sz; | 3506 | scripting_max_stack = itrace_synth_opts.callchain_sz; |
@@ -3615,6 +3668,12 @@ int cmd_script(int argc, const char **argv) | |||
3615 | if (symbol__init(&session->header.env) < 0) | 3668 | if (symbol__init(&session->header.env) < 0) |
3616 | goto out_delete; | 3669 | goto out_delete; |
3617 | 3670 | ||
3671 | uname(&uts); | ||
3672 | if (!strcmp(uts.machine, session->header.env.arch) || | ||
3673 | (!strcmp(uts.machine, "x86_64") && | ||
3674 | !strcmp(session->header.env.arch, "i386"))) | ||
3675 | native_arch = true; | ||
3676 | |||
3618 | script.session = session; | 3677 | script.session = session; |
3619 | script__setup_sample_type(&script); | 3678 | script__setup_sample_type(&script); |
3620 | 3679 | ||