diff options
author | Ingo Molnar <mingo@kernel.org> | 2017-04-12 01:29:13 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2017-04-12 03:22:19 -0400 |
commit | ef0eb2e6447f562bae2bcf503afcd85d68e843cc (patch) | |
tree | c6c89a26511e564efe85c1e69132aedd439c932d | |
parent | 1c4f8ad81c7f13314e4357550be9d5be3754fed9 (diff) | |
parent | 986a5bc028a84d487c354a529730b48682d1fb41 (diff) |
Merge tag 'perf-core-for-mingo-4.12-20170411' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core
perf/core improvements and fixes:
User visible changes:
- Support s390 jump instructions in perf annotate (Christian Borntraeger)
- When failing to setup multiple events (e.g. '-e irq_vectors:*'), state
which one caused the failure (Yao Jin)
- Various fixes for pipe mode, where the output of 'perf record' is
written to stdout instead of to a perf.data file, fixing workloads
such as: (David Carrillo-Cisneros)
$ perf record -o - noploop | perf inject -b > perf.data
$ perf record -o - noploop | perf annotate
Infrastructure changes:
- Simplify ltrim() implementation (Arnaldo Carvalho de Melo)
- Use ltrim() and rtrim() in places where ad-hoc equivalents were being
used (Taeung Song)
Conflicts:
tools/perf/util/annotate.c
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r-- | tools/perf/Documentation/perf.data-file-format.txt | 19 | ||||
-rw-r--r-- | tools/perf/arch/s390/annotate/instructions.c | 30 | ||||
-rw-r--r-- | tools/perf/builtin-annotate.c | 2 | ||||
-rw-r--r-- | tools/perf/builtin-inject.c | 2 | ||||
-rw-r--r-- | tools/perf/builtin-script.c | 4 | ||||
-rw-r--r-- | tools/perf/builtin-stat.c | 10 | ||||
-rw-r--r-- | tools/perf/ui/browser.c | 2 | ||||
-rw-r--r-- | tools/perf/util/annotate.c | 48 | ||||
-rw-r--r-- | tools/perf/util/callchain.c | 4 | ||||
-rw-r--r-- | tools/perf/util/event.c | 11 | ||||
-rw-r--r-- | tools/perf/util/evsel.c | 8 | ||||
-rw-r--r-- | tools/perf/util/header.c | 3 | ||||
-rw-r--r-- | tools/perf/util/ordered-events.c | 3 | ||||
-rw-r--r-- | tools/perf/util/pmu.c | 3 | ||||
-rw-r--r-- | tools/perf/util/session.c | 17 | ||||
-rw-r--r-- | tools/perf/util/string.c | 6 |
16 files changed, 99 insertions, 73 deletions
diff --git a/tools/perf/Documentation/perf.data-file-format.txt b/tools/perf/Documentation/perf.data-file-format.txt index b664b18d3991..fa2a9132f0a9 100644 --- a/tools/perf/Documentation/perf.data-file-format.txt +++ b/tools/perf/Documentation/perf.data-file-format.txt | |||
@@ -11,8 +11,8 @@ All fields are in native-endian of the machine that generated the perf.data. | |||
11 | 11 | ||
12 | When perf is writing to a pipe it uses a special version of the file | 12 | When perf is writing to a pipe it uses a special version of the file |
13 | format that does not rely on seeking to adjust data offsets. This | 13 | format that does not rely on seeking to adjust data offsets. This |
14 | format is not described here. The pipe version can be converted to | 14 | format is described in "Pipe-mode data" section. The pipe data version can be |
15 | normal perf.data with perf inject. | 15 | augmented with additional events using perf inject. |
16 | 16 | ||
17 | The file starts with a perf_header: | 17 | The file starts with a perf_header: |
18 | 18 | ||
@@ -411,6 +411,21 @@ An array bound by the perf_file_section size. | |||
411 | 411 | ||
412 | ids points to a array of uint64_t defining the ids for event attr attr. | 412 | ids points to a array of uint64_t defining the ids for event attr attr. |
413 | 413 | ||
414 | Pipe-mode data | ||
415 | |||
416 | Pipe-mode avoid seeks in the file by removing the perf_file_section and flags | ||
417 | from the struct perf_header. The trimmed header is: | ||
418 | |||
419 | struct perf_pipe_file_header { | ||
420 | u64 magic; | ||
421 | u64 size; | ||
422 | }; | ||
423 | |||
424 | The information about attrs, data, and event_types is instead in the | ||
425 | synthesized events PERF_RECORD_ATTR, PERF_RECORD_HEADER_TRACING_DATA and | ||
426 | PERF_RECORD_HEADER_EVENT_TYPE that are generated by perf record in pipe-mode. | ||
427 | |||
428 | |||
414 | References: | 429 | References: |
415 | 430 | ||
416 | include/uapi/linux/perf_event.h | 431 | include/uapi/linux/perf_event.h |
diff --git a/tools/perf/arch/s390/annotate/instructions.c b/tools/perf/arch/s390/annotate/instructions.c new file mode 100644 index 000000000000..745b4b1b8b21 --- /dev/null +++ b/tools/perf/arch/s390/annotate/instructions.c | |||
@@ -0,0 +1,30 @@ | |||
1 | static struct ins_ops *s390__associate_ins_ops(struct arch *arch, const char *name) | ||
2 | { | ||
3 | struct ins_ops *ops = NULL; | ||
4 | |||
5 | /* catch all kind of jumps */ | ||
6 | if (strchr(name, 'j') || | ||
7 | !strncmp(name, "bct", 3) || | ||
8 | !strncmp(name, "br", 2)) | ||
9 | ops = &jump_ops; | ||
10 | /* override call/returns */ | ||
11 | if (!strcmp(name, "bras") || | ||
12 | !strcmp(name, "brasl") || | ||
13 | !strcmp(name, "basr")) | ||
14 | ops = &call_ops; | ||
15 | if (!strcmp(name, "br")) | ||
16 | ops = &ret_ops; | ||
17 | |||
18 | arch__associate_ins_ops(arch, name, ops); | ||
19 | return ops; | ||
20 | } | ||
21 | |||
22 | static int s390__annotate_init(struct arch *arch) | ||
23 | { | ||
24 | if (!arch->initialized) { | ||
25 | arch->initialized = true; | ||
26 | arch->associate_instruction_ops = s390__associate_ins_ops; | ||
27 | } | ||
28 | |||
29 | return 0; | ||
30 | } | ||
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 56a7c8d210b9..b2b2722f6bb7 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c | |||
@@ -394,6 +394,8 @@ int cmd_annotate(int argc, const char **argv) | |||
394 | .exit = perf_event__process_exit, | 394 | .exit = perf_event__process_exit, |
395 | .fork = perf_event__process_fork, | 395 | .fork = perf_event__process_fork, |
396 | .namespaces = perf_event__process_namespaces, | 396 | .namespaces = perf_event__process_namespaces, |
397 | .attr = perf_event__process_attr, | ||
398 | .build_id = perf_event__process_build_id, | ||
397 | .ordered_events = true, | 399 | .ordered_events = true, |
398 | .ordering_requires_timestamps = true, | 400 | .ordering_requires_timestamps = true, |
399 | }, | 401 | }, |
diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c index 42dff0b1375a..65e1c026a2f0 100644 --- a/tools/perf/builtin-inject.c +++ b/tools/perf/builtin-inject.c | |||
@@ -694,6 +694,8 @@ static int __cmd_inject(struct perf_inject *inject) | |||
694 | lseek(fd, output_data_offset, SEEK_SET); | 694 | lseek(fd, output_data_offset, SEEK_SET); |
695 | 695 | ||
696 | ret = perf_session__process_events(session); | 696 | ret = perf_session__process_events(session); |
697 | if (ret) | ||
698 | return ret; | ||
697 | 699 | ||
698 | if (!file_out->is_pipe) { | 700 | if (!file_out->is_pipe) { |
699 | if (inject->build_ids) | 701 | if (inject->build_ids) |
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 46acc8ece41f..2dab70fba2ba 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c | |||
@@ -1708,7 +1708,7 @@ static int parse_scriptname(const struct option *opt __maybe_unused, | |||
1708 | static int parse_output_fields(const struct option *opt __maybe_unused, | 1708 | static int parse_output_fields(const struct option *opt __maybe_unused, |
1709 | const char *arg, int unset __maybe_unused) | 1709 | const char *arg, int unset __maybe_unused) |
1710 | { | 1710 | { |
1711 | char *tok; | 1711 | char *tok, *strtok_saveptr = NULL; |
1712 | int i, imax = ARRAY_SIZE(all_output_options); | 1712 | int i, imax = ARRAY_SIZE(all_output_options); |
1713 | int j; | 1713 | int j; |
1714 | int rc = 0; | 1714 | int rc = 0; |
@@ -1769,7 +1769,7 @@ static int parse_output_fields(const struct option *opt __maybe_unused, | |||
1769 | } | 1769 | } |
1770 | } | 1770 | } |
1771 | 1771 | ||
1772 | for (tok = strtok(tok, ","); tok; tok = strtok(NULL, ",")) { | 1772 | for (tok = strtok_r(tok, ",", &strtok_saveptr); tok; tok = strtok_r(NULL, ",", &strtok_saveptr)) { |
1773 | for (i = 0; i < imax; ++i) { | 1773 | for (i = 0; i < imax; ++i) { |
1774 | if (strcmp(tok, all_output_options[i].str) == 0) | 1774 | if (strcmp(tok, all_output_options[i].str) == 0) |
1775 | break; | 1775 | break; |
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 2158ea14da57..868e086a6b59 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c | |||
@@ -875,10 +875,7 @@ static void print_metric_csv(void *ctx, | |||
875 | return; | 875 | return; |
876 | } | 876 | } |
877 | snprintf(buf, sizeof(buf), fmt, val); | 877 | snprintf(buf, sizeof(buf), fmt, val); |
878 | vals = buf; | 878 | ends = vals = ltrim(buf); |
879 | while (isspace(*vals)) | ||
880 | vals++; | ||
881 | ends = vals; | ||
882 | while (isdigit(*ends) || *ends == '.') | 879 | while (isdigit(*ends) || *ends == '.') |
883 | ends++; | 880 | ends++; |
884 | *ends = 0; | 881 | *ends = 0; |
@@ -950,10 +947,7 @@ static void print_metric_only_csv(void *ctx, const char *color __maybe_unused, | |||
950 | return; | 947 | return; |
951 | unit = fixunit(tbuf, os->evsel, unit); | 948 | unit = fixunit(tbuf, os->evsel, unit); |
952 | snprintf(buf, sizeof buf, fmt, val); | 949 | snprintf(buf, sizeof buf, fmt, val); |
953 | vals = buf; | 950 | ends = vals = ltrim(buf); |
954 | while (isspace(*vals)) | ||
955 | vals++; | ||
956 | ends = vals; | ||
957 | while (isdigit(*ends) || *ends == '.') | 951 | while (isdigit(*ends) || *ends == '.') |
958 | ends++; | 952 | ends++; |
959 | *ends = 0; | 953 | *ends = 0; |
diff --git a/tools/perf/ui/browser.c b/tools/perf/ui/browser.c index 3eb3edb307a4..9e47ccbe07f1 100644 --- a/tools/perf/ui/browser.c +++ b/tools/perf/ui/browser.c | |||
@@ -579,7 +579,7 @@ static int ui_browser__color_config(const char *var, const char *value, | |||
579 | break; | 579 | break; |
580 | 580 | ||
581 | *bg = '\0'; | 581 | *bg = '\0'; |
582 | while (isspace(*++bg)); | 582 | bg = ltrim(++bg); |
583 | ui_browser__colorsets[i].bg = bg; | 583 | ui_browser__colorsets[i].bg = bg; |
584 | ui_browser__colorsets[i].fg = fg; | 584 | ui_browser__colorsets[i].fg = fg; |
585 | return 0; | 585 | return 0; |
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c index bfb2f1d393d5..30498a2d4a6f 100644 --- a/tools/perf/util/annotate.c +++ b/tools/perf/util/annotate.c | |||
@@ -108,6 +108,7 @@ static int arch__associate_ins_ops(struct arch* arch, const char *name, struct i | |||
108 | #include "arch/arm64/annotate/instructions.c" | 108 | #include "arch/arm64/annotate/instructions.c" |
109 | #include "arch/x86/annotate/instructions.c" | 109 | #include "arch/x86/annotate/instructions.c" |
110 | #include "arch/powerpc/annotate/instructions.c" | 110 | #include "arch/powerpc/annotate/instructions.c" |
111 | #include "arch/s390/annotate/instructions.c" | ||
111 | 112 | ||
112 | static struct arch architectures[] = { | 113 | static struct arch architectures[] = { |
113 | { | 114 | { |
@@ -132,6 +133,7 @@ static struct arch architectures[] = { | |||
132 | }, | 133 | }, |
133 | { | 134 | { |
134 | .name = "s390", | 135 | .name = "s390", |
136 | .init = s390__annotate_init, | ||
135 | .objdump = { | 137 | .objdump = { |
136 | .comment_char = '#', | 138 | .comment_char = '#', |
137 | }, | 139 | }, |
@@ -385,9 +387,7 @@ static int mov__parse(struct arch *arch, struct ins_operands *ops, struct map *m | |||
385 | if (comment == NULL) | 387 | if (comment == NULL) |
386 | return 0; | 388 | return 0; |
387 | 389 | ||
388 | while (comment[0] != '\0' && isspace(comment[0])) | 390 | comment = ltrim(comment); |
389 | ++comment; | ||
390 | |||
391 | comment__symbol(ops->source.raw, comment, &ops->source.addr, &ops->source.name); | 391 | comment__symbol(ops->source.raw, comment, &ops->source.addr, &ops->source.name); |
392 | comment__symbol(ops->target.raw, comment, &ops->target.addr, &ops->target.name); | 392 | comment__symbol(ops->target.raw, comment, &ops->target.addr, &ops->target.name); |
393 | 393 | ||
@@ -432,9 +432,7 @@ static int dec__parse(struct arch *arch __maybe_unused, struct ins_operands *ops | |||
432 | if (comment == NULL) | 432 | if (comment == NULL) |
433 | return 0; | 433 | return 0; |
434 | 434 | ||
435 | while (comment[0] != '\0' && isspace(comment[0])) | 435 | comment = ltrim(comment); |
436 | ++comment; | ||
437 | |||
438 | comment__symbol(ops->target.raw, comment, &ops->target.addr, &ops->target.name); | 436 | comment__symbol(ops->target.raw, comment, &ops->target.addr, &ops->target.name); |
439 | 437 | ||
440 | return 0; | 438 | return 0; |
@@ -783,10 +781,7 @@ static void disasm_line__init_ins(struct disasm_line *dl, struct arch *arch, str | |||
783 | 781 | ||
784 | static int disasm_line__parse(char *line, const char **namep, char **rawp) | 782 | static int disasm_line__parse(char *line, const char **namep, char **rawp) |
785 | { | 783 | { |
786 | char *name = line, tmp; | 784 | char tmp, *name = ltrim(line); |
787 | |||
788 | while (isspace(name[0])) | ||
789 | ++name; | ||
790 | 785 | ||
791 | if (name[0] == '\0') | 786 | if (name[0] == '\0') |
792 | return -1; | 787 | return -1; |
@@ -804,12 +799,7 @@ static int disasm_line__parse(char *line, const char **namep, char **rawp) | |||
804 | goto out_free_name; | 799 | goto out_free_name; |
805 | 800 | ||
806 | (*rawp)[0] = tmp; | 801 | (*rawp)[0] = tmp; |
807 | 802 | *rawp = ltrim(*rawp); | |
808 | if ((*rawp)[0] != '\0') { | ||
809 | (*rawp)++; | ||
810 | while (isspace((*rawp)[0])) | ||
811 | ++(*rawp); | ||
812 | } | ||
813 | 803 | ||
814 | return 0; | 804 | return 0; |
815 | 805 | ||
@@ -1154,7 +1144,7 @@ static int symbol__parse_objdump_line(struct symbol *sym, struct map *map, | |||
1154 | { | 1144 | { |
1155 | struct annotation *notes = symbol__annotation(sym); | 1145 | struct annotation *notes = symbol__annotation(sym); |
1156 | struct disasm_line *dl; | 1146 | struct disasm_line *dl; |
1157 | char *line = NULL, *parsed_line, *tmp, *tmp2, *c; | 1147 | char *line = NULL, *parsed_line, *tmp, *tmp2; |
1158 | size_t line_len; | 1148 | size_t line_len; |
1159 | s64 line_ip, offset = -1; | 1149 | s64 line_ip, offset = -1; |
1160 | regmatch_t match[2]; | 1150 | regmatch_t match[2]; |
@@ -1165,32 +1155,16 @@ static int symbol__parse_objdump_line(struct symbol *sym, struct map *map, | |||
1165 | if (!line) | 1155 | if (!line) |
1166 | return -1; | 1156 | return -1; |
1167 | 1157 | ||
1168 | while (line_len != 0 && isspace(line[line_len - 1])) | ||
1169 | line[--line_len] = '\0'; | ||
1170 | |||
1171 | c = strchr(line, '\n'); | ||
1172 | if (c) | ||
1173 | *c = 0; | ||
1174 | |||
1175 | line_ip = -1; | 1158 | line_ip = -1; |
1176 | parsed_line = line; | 1159 | parsed_line = rtrim(line); |
1177 | 1160 | ||
1178 | /* /filename:linenr ? Save line number and ignore. */ | 1161 | /* /filename:linenr ? Save line number and ignore. */ |
1179 | if (regexec(&file_lineno, line, 2, match, 0) == 0) { | 1162 | if (regexec(&file_lineno, parsed_line, 2, match, 0) == 0) { |
1180 | *line_nr = atoi(line + match[1].rm_so); | 1163 | *line_nr = atoi(parsed_line + match[1].rm_so); |
1181 | return 0; | 1164 | return 0; |
1182 | } | 1165 | } |
1183 | 1166 | ||
1184 | /* | 1167 | tmp = ltrim(parsed_line); |
1185 | * Strip leading spaces: | ||
1186 | */ | ||
1187 | tmp = line; | ||
1188 | while (*tmp) { | ||
1189 | if (*tmp != ' ') | ||
1190 | break; | ||
1191 | tmp++; | ||
1192 | } | ||
1193 | |||
1194 | if (*tmp) { | 1168 | if (*tmp) { |
1195 | /* | 1169 | /* |
1196 | * Parse hexa addresses followed by ':' | 1170 | * Parse hexa addresses followed by ':' |
diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c index 3cea1fb5404b..2e5eff5abef0 100644 --- a/tools/perf/util/callchain.c +++ b/tools/perf/util/callchain.c | |||
@@ -116,7 +116,7 @@ static int | |||
116 | __parse_callchain_report_opt(const char *arg, bool allow_record_opt) | 116 | __parse_callchain_report_opt(const char *arg, bool allow_record_opt) |
117 | { | 117 | { |
118 | char *tok; | 118 | char *tok; |
119 | char *endptr; | 119 | char *endptr, *saveptr = NULL; |
120 | bool minpcnt_set = false; | 120 | bool minpcnt_set = false; |
121 | bool record_opt_set = false; | 121 | bool record_opt_set = false; |
122 | bool try_stack_size = false; | 122 | bool try_stack_size = false; |
@@ -127,7 +127,7 @@ __parse_callchain_report_opt(const char *arg, bool allow_record_opt) | |||
127 | if (!arg) | 127 | if (!arg) |
128 | return 0; | 128 | return 0; |
129 | 129 | ||
130 | while ((tok = strtok((char *)arg, ",")) != NULL) { | 130 | while ((tok = strtok_r((char *)arg, ",", &saveptr)) != NULL) { |
131 | if (!strncmp(tok, "none", strlen(tok))) { | 131 | if (!strncmp(tok, "none", strlen(tok))) { |
132 | callchain_param.mode = CHAIN_NONE; | 132 | callchain_param.mode = CHAIN_NONE; |
133 | callchain_param.enabled = false; | 133 | callchain_param.enabled = false; |
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index 76b9c6bc8369..8255a26ac255 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c | |||
@@ -106,7 +106,7 @@ static int perf_event__get_comm_ids(pid_t pid, char *comm, size_t len, | |||
106 | int fd; | 106 | int fd; |
107 | size_t size = 0; | 107 | size_t size = 0; |
108 | ssize_t n; | 108 | ssize_t n; |
109 | char *nl, *name, *tgids, *ppids; | 109 | char *name, *tgids, *ppids; |
110 | 110 | ||
111 | *tgid = -1; | 111 | *tgid = -1; |
112 | *ppid = -1; | 112 | *ppid = -1; |
@@ -134,14 +134,7 @@ static int perf_event__get_comm_ids(pid_t pid, char *comm, size_t len, | |||
134 | 134 | ||
135 | if (name) { | 135 | if (name) { |
136 | name += 5; /* strlen("Name:") */ | 136 | name += 5; /* strlen("Name:") */ |
137 | 137 | name = rtrim(ltrim(name)); | |
138 | while (*name && isspace(*name)) | ||
139 | ++name; | ||
140 | |||
141 | nl = strchr(name, '\n'); | ||
142 | if (nl) | ||
143 | *nl = '\0'; | ||
144 | |||
145 | size = strlen(name); | 138 | size = strlen(name); |
146 | if (size >= len) | 139 | if (size >= len) |
147 | size = len - 1; | 140 | size = len - 1; |
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 9dc7e2d6e48a..8f5d86bd3501 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c | |||
@@ -2457,11 +2457,17 @@ int perf_evsel__open_strerror(struct perf_evsel *evsel, struct target *target, | |||
2457 | int err, char *msg, size_t size) | 2457 | int err, char *msg, size_t size) |
2458 | { | 2458 | { |
2459 | char sbuf[STRERR_BUFSIZE]; | 2459 | char sbuf[STRERR_BUFSIZE]; |
2460 | int printed = 0; | ||
2460 | 2461 | ||
2461 | switch (err) { | 2462 | switch (err) { |
2462 | case EPERM: | 2463 | case EPERM: |
2463 | case EACCES: | 2464 | case EACCES: |
2464 | return scnprintf(msg, size, | 2465 | if (err == EPERM) |
2466 | printed = scnprintf(msg, size, | ||
2467 | "No permission to enable %s event.\n\n", | ||
2468 | perf_evsel__name(evsel)); | ||
2469 | |||
2470 | return scnprintf(msg + printed, size - printed, | ||
2465 | "You may not have permission to collect %sstats.\n\n" | 2471 | "You may not have permission to collect %sstats.\n\n" |
2466 | "Consider tweaking /proc/sys/kernel/perf_event_paranoid,\n" | 2472 | "Consider tweaking /proc/sys/kernel/perf_event_paranoid,\n" |
2467 | "which controls use of the performance events system by\n" | 2473 | "which controls use of the performance events system by\n" |
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index ef09f26e67da..2ccc7f06db79 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c | |||
@@ -2270,6 +2270,9 @@ int perf_header__fprintf_info(struct perf_session *session, FILE *fp, bool full) | |||
2270 | perf_header__process_sections(header, fd, &hd, | 2270 | perf_header__process_sections(header, fd, &hd, |
2271 | perf_file_section__fprintf_info); | 2271 | perf_file_section__fprintf_info); |
2272 | 2272 | ||
2273 | if (session->file->is_pipe) | ||
2274 | return 0; | ||
2275 | |||
2273 | fprintf(fp, "# missing features: "); | 2276 | fprintf(fp, "# missing features: "); |
2274 | for_each_clear_bit(bit, header->adds_features, HEADER_LAST_FEATURE) { | 2277 | for_each_clear_bit(bit, header->adds_features, HEADER_LAST_FEATURE) { |
2275 | if (bit) | 2278 | if (bit) |
diff --git a/tools/perf/util/ordered-events.c b/tools/perf/util/ordered-events.c index fe84df1875aa..e70e935b1841 100644 --- a/tools/perf/util/ordered-events.c +++ b/tools/perf/util/ordered-events.c | |||
@@ -79,7 +79,7 @@ static union perf_event *dup_event(struct ordered_events *oe, | |||
79 | 79 | ||
80 | static void free_dup_event(struct ordered_events *oe, union perf_event *event) | 80 | static void free_dup_event(struct ordered_events *oe, union perf_event *event) |
81 | { | 81 | { |
82 | if (oe->copy_on_queue) { | 82 | if (event && oe->copy_on_queue) { |
83 | oe->cur_alloc_size -= event->header.size; | 83 | oe->cur_alloc_size -= event->header.size; |
84 | free(event); | 84 | free(event); |
85 | } | 85 | } |
@@ -150,6 +150,7 @@ void ordered_events__delete(struct ordered_events *oe, struct ordered_event *eve | |||
150 | list_move(&event->list, &oe->cache); | 150 | list_move(&event->list, &oe->cache); |
151 | oe->nr_events--; | 151 | oe->nr_events--; |
152 | free_dup_event(oe, event->event); | 152 | free_dup_event(oe, event->event); |
153 | event->event = NULL; | ||
153 | } | 154 | } |
154 | 155 | ||
155 | int ordered_events__queue(struct ordered_events *oe, union perf_event *event, | 156 | int ordered_events__queue(struct ordered_events *oe, union perf_event *event, |
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index 362051ea7f3d..11c752561c55 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c | |||
@@ -1148,8 +1148,7 @@ static void wordwrap(char *s, int start, int max, int corr) | |||
1148 | break; | 1148 | break; |
1149 | s += wlen; | 1149 | s += wlen; |
1150 | column += n; | 1150 | column += n; |
1151 | while (isspace(*s)) | 1151 | s = ltrim(s); |
1152 | s++; | ||
1153 | } | 1152 | } |
1154 | } | 1153 | } |
1155 | 1154 | ||
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 24259bc2c598..7b740a73e595 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c | |||
@@ -140,8 +140,14 @@ struct perf_session *perf_session__new(struct perf_data_file *file, | |||
140 | if (perf_session__open(session) < 0) | 140 | if (perf_session__open(session) < 0) |
141 | goto out_close; | 141 | goto out_close; |
142 | 142 | ||
143 | perf_session__set_id_hdr_size(session); | 143 | /* |
144 | perf_session__set_comm_exec(session); | 144 | * set session attributes that are present in perf.data |
145 | * but not in pipe-mode. | ||
146 | */ | ||
147 | if (!file->is_pipe) { | ||
148 | perf_session__set_id_hdr_size(session); | ||
149 | perf_session__set_comm_exec(session); | ||
150 | } | ||
145 | } | 151 | } |
146 | } else { | 152 | } else { |
147 | session->machines.host.env = &perf_env; | 153 | session->machines.host.env = &perf_env; |
@@ -156,7 +162,11 @@ struct perf_session *perf_session__new(struct perf_data_file *file, | |||
156 | pr_warning("Cannot read kernel map\n"); | 162 | pr_warning("Cannot read kernel map\n"); |
157 | } | 163 | } |
158 | 164 | ||
159 | if (tool && tool->ordering_requires_timestamps && | 165 | /* |
166 | * In pipe-mode, evlist is empty until PERF_RECORD_HEADER_ATTR is | ||
167 | * processed, so perf_evlist__sample_id_all is not meaningful here. | ||
168 | */ | ||
169 | if ((!file || !file->is_pipe) && tool && tool->ordering_requires_timestamps && | ||
160 | tool->ordered_events && !perf_evlist__sample_id_all(session->evlist)) { | 170 | tool->ordered_events && !perf_evlist__sample_id_all(session->evlist)) { |
161 | dump_printf("WARNING: No sample_id_all support, falling back to unordered processing\n"); | 171 | dump_printf("WARNING: No sample_id_all support, falling back to unordered processing\n"); |
162 | tool->ordered_events = false; | 172 | tool->ordered_events = false; |
@@ -1656,6 +1666,7 @@ static int __perf_session__process_pipe_events(struct perf_session *session) | |||
1656 | buf = malloc(cur_size); | 1666 | buf = malloc(cur_size); |
1657 | if (!buf) | 1667 | if (!buf) |
1658 | return -errno; | 1668 | return -errno; |
1669 | ordered_events__set_copy_on_queue(oe, true); | ||
1659 | more: | 1670 | more: |
1660 | event = buf; | 1671 | event = buf; |
1661 | err = readn(fd, event, sizeof(struct perf_event_header)); | 1672 | err = readn(fd, event, sizeof(struct perf_event_header)); |
diff --git a/tools/perf/util/string.c b/tools/perf/util/string.c index bddca519dd58..e8feb142c9c9 100644 --- a/tools/perf/util/string.c +++ b/tools/perf/util/string.c | |||
@@ -322,12 +322,8 @@ char *strxfrchar(char *s, char from, char to) | |||
322 | */ | 322 | */ |
323 | char *ltrim(char *s) | 323 | char *ltrim(char *s) |
324 | { | 324 | { |
325 | int len = strlen(s); | 325 | while (isspace(*s)) |
326 | |||
327 | while (len && isspace(*s)) { | ||
328 | len--; | ||
329 | s++; | 326 | s++; |
330 | } | ||
331 | 327 | ||
332 | return s; | 328 | return s; |
333 | } | 329 | } |