diff options
| author | Jens Axboe <axboe@kernel.dk> | 2012-07-30 03:03:10 -0400 |
|---|---|---|
| committer | Jens Axboe <axboe@kernel.dk> | 2012-07-30 03:03:10 -0400 |
| commit | 72ea1f74fcdf874cca6d2c0962379523bbd99e2c (patch) | |
| tree | 4c67be6c73356086ff44ef1b8b1c9479702689ca /tools | |
| parent | b1af9be5ef77898c05667bb9dbf3b180d91d3292 (diff) | |
| parent | a73ff3231df59a4b92ccd0dd4e73897c5822489b (diff) | |
Merge branch 'for-jens' of git://git.drbd.org/linux-drbd into for-3.6/drivers
Diffstat (limited to 'tools')
26 files changed, 325 insertions, 85 deletions
diff --git a/tools/hv/hv_kvp_daemon.c b/tools/hv/hv_kvp_daemon.c index 146fd6147e84..d9834b362943 100644 --- a/tools/hv/hv_kvp_daemon.c +++ b/tools/hv/hv_kvp_daemon.c | |||
| @@ -701,14 +701,18 @@ int main(void) | |||
| 701 | pfd.fd = fd; | 701 | pfd.fd = fd; |
| 702 | 702 | ||
| 703 | while (1) { | 703 | while (1) { |
| 704 | struct sockaddr *addr_p = (struct sockaddr *) &addr; | ||
| 705 | socklen_t addr_l = sizeof(addr); | ||
| 704 | pfd.events = POLLIN; | 706 | pfd.events = POLLIN; |
| 705 | pfd.revents = 0; | 707 | pfd.revents = 0; |
| 706 | poll(&pfd, 1, -1); | 708 | poll(&pfd, 1, -1); |
| 707 | 709 | ||
| 708 | len = recv(fd, kvp_recv_buffer, sizeof(kvp_recv_buffer), 0); | 710 | len = recvfrom(fd, kvp_recv_buffer, sizeof(kvp_recv_buffer), 0, |
| 711 | addr_p, &addr_l); | ||
| 709 | 712 | ||
| 710 | if (len < 0) { | 713 | if (len < 0 || addr.nl_pid) { |
| 711 | syslog(LOG_ERR, "recv failed; error:%d", len); | 714 | syslog(LOG_ERR, "recvfrom failed; pid:%u error:%d %s", |
| 715 | addr.nl_pid, errno, strerror(errno)); | ||
| 712 | close(fd); | 716 | close(fd); |
| 713 | return -1; | 717 | return -1; |
| 714 | } | 718 | } |
diff --git a/tools/perf/MANIFEST b/tools/perf/MANIFEST index 5476bc0a1eac..b4b572e8c100 100644 --- a/tools/perf/MANIFEST +++ b/tools/perf/MANIFEST | |||
| @@ -1,4 +1,6 @@ | |||
| 1 | tools/perf | 1 | tools/perf |
| 2 | tools/scripts | ||
| 3 | tools/lib/traceevent | ||
| 2 | include/linux/const.h | 4 | include/linux/const.h |
| 3 | include/linux/perf_event.h | 5 | include/linux/perf_event.h |
| 4 | include/linux/rbtree.h | 6 | include/linux/rbtree.h |
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 8c767c6bca91..25249f76329d 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c | |||
| @@ -152,7 +152,7 @@ static int perf_evsel__add_hist_entry(struct perf_evsel *evsel, | |||
| 152 | 152 | ||
| 153 | if (symbol_conf.use_callchain) { | 153 | if (symbol_conf.use_callchain) { |
| 154 | err = callchain_append(he->callchain, | 154 | err = callchain_append(he->callchain, |
| 155 | &evsel->hists.callchain_cursor, | 155 | &callchain_cursor, |
| 156 | sample->period); | 156 | sample->period); |
| 157 | if (err) | 157 | if (err) |
| 158 | return err; | 158 | return err; |
| @@ -162,7 +162,7 @@ static int perf_evsel__add_hist_entry(struct perf_evsel *evsel, | |||
| 162 | * so we don't allocated the extra space needed because the stdio | 162 | * so we don't allocated the extra space needed because the stdio |
| 163 | * code will not use it. | 163 | * code will not use it. |
| 164 | */ | 164 | */ |
| 165 | if (al->sym != NULL && use_browser > 0) { | 165 | if (he->ms.sym != NULL && use_browser > 0) { |
| 166 | struct annotation *notes = symbol__annotation(he->ms.sym); | 166 | struct annotation *notes = symbol__annotation(he->ms.sym); |
| 167 | 167 | ||
| 168 | assert(evsel != NULL); | 168 | assert(evsel != NULL); |
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 62ae30d34fa6..07b5c7703dd1 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c | |||
| @@ -1129,7 +1129,7 @@ static int add_default_attributes(void) | |||
| 1129 | return 0; | 1129 | return 0; |
| 1130 | 1130 | ||
| 1131 | if (!evsel_list->nr_entries) { | 1131 | if (!evsel_list->nr_entries) { |
| 1132 | if (perf_evlist__add_attrs_array(evsel_list, default_attrs) < 0) | 1132 | if (perf_evlist__add_default_attrs(evsel_list, default_attrs) < 0) |
| 1133 | return -1; | 1133 | return -1; |
| 1134 | } | 1134 | } |
| 1135 | 1135 | ||
| @@ -1139,21 +1139,21 @@ static int add_default_attributes(void) | |||
| 1139 | return 0; | 1139 | return 0; |
| 1140 | 1140 | ||
| 1141 | /* Append detailed run extra attributes: */ | 1141 | /* Append detailed run extra attributes: */ |
| 1142 | if (perf_evlist__add_attrs_array(evsel_list, detailed_attrs) < 0) | 1142 | if (perf_evlist__add_default_attrs(evsel_list, detailed_attrs) < 0) |
| 1143 | return -1; | 1143 | return -1; |
| 1144 | 1144 | ||
| 1145 | if (detailed_run < 2) | 1145 | if (detailed_run < 2) |
| 1146 | return 0; | 1146 | return 0; |
| 1147 | 1147 | ||
| 1148 | /* Append very detailed run extra attributes: */ | 1148 | /* Append very detailed run extra attributes: */ |
| 1149 | if (perf_evlist__add_attrs_array(evsel_list, very_detailed_attrs) < 0) | 1149 | if (perf_evlist__add_default_attrs(evsel_list, very_detailed_attrs) < 0) |
| 1150 | return -1; | 1150 | return -1; |
| 1151 | 1151 | ||
| 1152 | if (detailed_run < 3) | 1152 | if (detailed_run < 3) |
| 1153 | return 0; | 1153 | return 0; |
| 1154 | 1154 | ||
| 1155 | /* Append very, very detailed run extra attributes: */ | 1155 | /* Append very, very detailed run extra attributes: */ |
| 1156 | return perf_evlist__add_attrs_array(evsel_list, very_very_detailed_attrs); | 1156 | return perf_evlist__add_default_attrs(evsel_list, very_very_detailed_attrs); |
| 1157 | } | 1157 | } |
| 1158 | 1158 | ||
| 1159 | int cmd_stat(int argc, const char **argv, const char *prefix __used) | 1159 | int cmd_stat(int argc, const char **argv, const char *prefix __used) |
| @@ -1179,6 +1179,12 @@ int cmd_stat(int argc, const char **argv, const char *prefix __used) | |||
| 1179 | fprintf(stderr, "cannot use both --output and --log-fd\n"); | 1179 | fprintf(stderr, "cannot use both --output and --log-fd\n"); |
| 1180 | usage_with_options(stat_usage, options); | 1180 | usage_with_options(stat_usage, options); |
| 1181 | } | 1181 | } |
| 1182 | |||
| 1183 | if (output_fd < 0) { | ||
| 1184 | fprintf(stderr, "argument to --log-fd must be a > 0\n"); | ||
| 1185 | usage_with_options(stat_usage, options); | ||
| 1186 | } | ||
| 1187 | |||
| 1182 | if (!output) { | 1188 | if (!output) { |
| 1183 | struct timespec tm; | 1189 | struct timespec tm; |
| 1184 | mode = append_file ? "a" : "w"; | 1190 | mode = append_file ? "a" : "w"; |
| @@ -1190,7 +1196,7 @@ int cmd_stat(int argc, const char **argv, const char *prefix __used) | |||
| 1190 | } | 1196 | } |
| 1191 | clock_gettime(CLOCK_REALTIME, &tm); | 1197 | clock_gettime(CLOCK_REALTIME, &tm); |
| 1192 | fprintf(output, "# started on %s\n", ctime(&tm.tv_sec)); | 1198 | fprintf(output, "# started on %s\n", ctime(&tm.tv_sec)); |
| 1193 | } else if (output_fd != 2) { | 1199 | } else if (output_fd > 0) { |
| 1194 | mode = append_file ? "a" : "w"; | 1200 | mode = append_file ? "a" : "w"; |
| 1195 | output = fdopen(output_fd, mode); | 1201 | output = fdopen(output_fd, mode); |
| 1196 | if (!output) { | 1202 | if (!output) { |
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 871b540293e1..6bb0277b7dfe 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c | |||
| @@ -787,7 +787,7 @@ static void perf_event__process_sample(struct perf_tool *tool, | |||
| 787 | } | 787 | } |
| 788 | 788 | ||
| 789 | if (symbol_conf.use_callchain) { | 789 | if (symbol_conf.use_callchain) { |
| 790 | err = callchain_append(he->callchain, &evsel->hists.callchain_cursor, | 790 | err = callchain_append(he->callchain, &callchain_cursor, |
| 791 | sample->period); | 791 | sample->period); |
| 792 | if (err) | 792 | if (err) |
| 793 | return; | 793 | return; |
diff --git a/tools/perf/design.txt b/tools/perf/design.txt index bd0bb1b1279b..67e5d0cace85 100644 --- a/tools/perf/design.txt +++ b/tools/perf/design.txt | |||
| @@ -409,14 +409,15 @@ Counters can be enabled and disabled in two ways: via ioctl and via | |||
| 409 | prctl. When a counter is disabled, it doesn't count or generate | 409 | prctl. When a counter is disabled, it doesn't count or generate |
| 410 | events but does continue to exist and maintain its count value. | 410 | events but does continue to exist and maintain its count value. |
| 411 | 411 | ||
| 412 | An individual counter or counter group can be enabled with | 412 | An individual counter can be enabled with |
| 413 | 413 | ||
| 414 | ioctl(fd, PERF_EVENT_IOC_ENABLE); | 414 | ioctl(fd, PERF_EVENT_IOC_ENABLE, 0); |
| 415 | 415 | ||
| 416 | or disabled with | 416 | or disabled with |
| 417 | 417 | ||
| 418 | ioctl(fd, PERF_EVENT_IOC_DISABLE); | 418 | ioctl(fd, PERF_EVENT_IOC_DISABLE, 0); |
| 419 | 419 | ||
| 420 | For a counter group, pass PERF_IOC_FLAG_GROUP as the third argument. | ||
| 420 | Enabling or disabling the leader of a group enables or disables the | 421 | Enabling or disabling the leader of a group enables or disables the |
| 421 | whole group; that is, while the group leader is disabled, none of the | 422 | whole group; that is, while the group leader is disabled, none of the |
| 422 | counters in the group will count. Enabling or disabling a member of a | 423 | counters in the group will count. Enabling or disabling a member of a |
diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c index 4deea6aaf927..34b1c46eaf42 100644 --- a/tools/perf/ui/browsers/annotate.c +++ b/tools/perf/ui/browsers/annotate.c | |||
| @@ -668,7 +668,7 @@ static int annotate_browser__run(struct annotate_browser *browser, int evidx, | |||
| 668 | "q/ESC/CTRL+C Exit\n\n" | 668 | "q/ESC/CTRL+C Exit\n\n" |
| 669 | "-> Go to target\n" | 669 | "-> Go to target\n" |
| 670 | "<- Exit\n" | 670 | "<- Exit\n" |
| 671 | "h Cycle thru hottest instructions\n" | 671 | "H Cycle thru hottest instructions\n" |
| 672 | "j Toggle showing jump to target arrows\n" | 672 | "j Toggle showing jump to target arrows\n" |
| 673 | "J Toggle showing number of jump sources on targets\n" | 673 | "J Toggle showing number of jump sources on targets\n" |
| 674 | "n Search next string\n" | 674 | "n Search next string\n" |
diff --git a/tools/perf/util/PERF-VERSION-GEN b/tools/perf/util/PERF-VERSION-GEN index ad73300f7bac..95264f304179 100755 --- a/tools/perf/util/PERF-VERSION-GEN +++ b/tools/perf/util/PERF-VERSION-GEN | |||
| @@ -12,7 +12,7 @@ LF=' | |||
| 12 | # First check if there is a .git to get the version from git describe | 12 | # First check if there is a .git to get the version from git describe |
| 13 | # otherwise try to get the version from the kernel makefile | 13 | # otherwise try to get the version from the kernel makefile |
| 14 | if test -d ../../.git -o -f ../../.git && | 14 | if test -d ../../.git -o -f ../../.git && |
| 15 | VN=$(git describe --abbrev=4 HEAD 2>/dev/null) && | 15 | VN=$(git describe --match 'v[0-9].[0-9]*' --abbrev=4 HEAD 2>/dev/null) && |
| 16 | case "$VN" in | 16 | case "$VN" in |
| 17 | *$LF*) (exit 1) ;; | 17 | *$LF*) (exit 1) ;; |
| 18 | v[0-9]*) | 18 | v[0-9]*) |
diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c index 9f7106a8d9a4..3a6bff47614f 100644 --- a/tools/perf/util/callchain.c +++ b/tools/perf/util/callchain.c | |||
| @@ -18,6 +18,8 @@ | |||
| 18 | #include "util.h" | 18 | #include "util.h" |
| 19 | #include "callchain.h" | 19 | #include "callchain.h" |
| 20 | 20 | ||
| 21 | __thread struct callchain_cursor callchain_cursor; | ||
| 22 | |||
| 21 | bool ip_callchain__valid(struct ip_callchain *chain, | 23 | bool ip_callchain__valid(struct ip_callchain *chain, |
| 22 | const union perf_event *event) | 24 | const union perf_event *event) |
| 23 | { | 25 | { |
diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h index 7f9c0f1ae3a9..3bdb407f9cd9 100644 --- a/tools/perf/util/callchain.h +++ b/tools/perf/util/callchain.h | |||
| @@ -76,6 +76,8 @@ struct callchain_cursor { | |||
| 76 | struct callchain_cursor_node *curr; | 76 | struct callchain_cursor_node *curr; |
| 77 | }; | 77 | }; |
| 78 | 78 | ||
| 79 | extern __thread struct callchain_cursor callchain_cursor; | ||
| 80 | |||
| 79 | static inline void callchain_init(struct callchain_root *root) | 81 | static inline void callchain_init(struct callchain_root *root) |
| 80 | { | 82 | { |
| 81 | INIT_LIST_HEAD(&root->node.siblings); | 83 | INIT_LIST_HEAD(&root->node.siblings); |
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 4ac5f5ae4ce9..7400fb3fc50c 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c | |||
| @@ -159,6 +159,17 @@ out_delete_partial_list: | |||
| 159 | return -1; | 159 | return -1; |
| 160 | } | 160 | } |
| 161 | 161 | ||
| 162 | int __perf_evlist__add_default_attrs(struct perf_evlist *evlist, | ||
| 163 | struct perf_event_attr *attrs, size_t nr_attrs) | ||
| 164 | { | ||
| 165 | size_t i; | ||
| 166 | |||
| 167 | for (i = 0; i < nr_attrs; i++) | ||
| 168 | event_attr_init(attrs + i); | ||
| 169 | |||
| 170 | return perf_evlist__add_attrs(evlist, attrs, nr_attrs); | ||
| 171 | } | ||
| 172 | |||
| 162 | static int trace_event__id(const char *evname) | 173 | static int trace_event__id(const char *evname) |
| 163 | { | 174 | { |
| 164 | char *filename, *colon; | 175 | char *filename, *colon; |
| @@ -263,7 +274,8 @@ void perf_evlist__disable(struct perf_evlist *evlist) | |||
| 263 | for (cpu = 0; cpu < evlist->cpus->nr; cpu++) { | 274 | for (cpu = 0; cpu < evlist->cpus->nr; cpu++) { |
| 264 | list_for_each_entry(pos, &evlist->entries, node) { | 275 | list_for_each_entry(pos, &evlist->entries, node) { |
| 265 | for (thread = 0; thread < evlist->threads->nr; thread++) | 276 | for (thread = 0; thread < evlist->threads->nr; thread++) |
| 266 | ioctl(FD(pos, cpu, thread), PERF_EVENT_IOC_DISABLE); | 277 | ioctl(FD(pos, cpu, thread), |
| 278 | PERF_EVENT_IOC_DISABLE, 0); | ||
| 267 | } | 279 | } |
| 268 | } | 280 | } |
| 269 | } | 281 | } |
| @@ -276,7 +288,8 @@ void perf_evlist__enable(struct perf_evlist *evlist) | |||
| 276 | for (cpu = 0; cpu < evlist->cpus->nr; cpu++) { | 288 | for (cpu = 0; cpu < evlist->cpus->nr; cpu++) { |
| 277 | list_for_each_entry(pos, &evlist->entries, node) { | 289 | list_for_each_entry(pos, &evlist->entries, node) { |
| 278 | for (thread = 0; thread < evlist->threads->nr; thread++) | 290 | for (thread = 0; thread < evlist->threads->nr; thread++) |
| 279 | ioctl(FD(pos, cpu, thread), PERF_EVENT_IOC_ENABLE); | 291 | ioctl(FD(pos, cpu, thread), |
| 292 | PERF_EVENT_IOC_ENABLE, 0); | ||
| 280 | } | 293 | } |
| 281 | } | 294 | } |
| 282 | } | 295 | } |
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index 58abb63ac13a..989bee9624c2 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h | |||
| @@ -54,6 +54,8 @@ void perf_evlist__add(struct perf_evlist *evlist, struct perf_evsel *entry); | |||
| 54 | int perf_evlist__add_default(struct perf_evlist *evlist); | 54 | int perf_evlist__add_default(struct perf_evlist *evlist); |
| 55 | int perf_evlist__add_attrs(struct perf_evlist *evlist, | 55 | int perf_evlist__add_attrs(struct perf_evlist *evlist, |
| 56 | struct perf_event_attr *attrs, size_t nr_attrs); | 56 | struct perf_event_attr *attrs, size_t nr_attrs); |
| 57 | int __perf_evlist__add_default_attrs(struct perf_evlist *evlist, | ||
| 58 | struct perf_event_attr *attrs, size_t nr_attrs); | ||
| 57 | int perf_evlist__add_tracepoints(struct perf_evlist *evlist, | 59 | int perf_evlist__add_tracepoints(struct perf_evlist *evlist, |
| 58 | const char *tracepoints[], size_t nr_tracepoints); | 60 | const char *tracepoints[], size_t nr_tracepoints); |
| 59 | int perf_evlist__set_tracepoints_handlers(struct perf_evlist *evlist, | 61 | int perf_evlist__set_tracepoints_handlers(struct perf_evlist *evlist, |
| @@ -62,6 +64,8 @@ int perf_evlist__set_tracepoints_handlers(struct perf_evlist *evlist, | |||
| 62 | 64 | ||
| 63 | #define perf_evlist__add_attrs_array(evlist, array) \ | 65 | #define perf_evlist__add_attrs_array(evlist, array) \ |
| 64 | perf_evlist__add_attrs(evlist, array, ARRAY_SIZE(array)) | 66 | perf_evlist__add_attrs(evlist, array, ARRAY_SIZE(array)) |
| 67 | #define perf_evlist__add_default_attrs(evlist, array) \ | ||
| 68 | __perf_evlist__add_default_attrs(evlist, array, ARRAY_SIZE(array)) | ||
| 65 | 69 | ||
| 66 | #define perf_evlist__add_tracepoints_array(evlist, array) \ | 70 | #define perf_evlist__add_tracepoints_array(evlist, array) \ |
| 67 | perf_evlist__add_tracepoints(evlist, array, ARRAY_SIZE(array)) | 71 | perf_evlist__add_tracepoints(evlist, array, ARRAY_SIZE(array)) |
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 91d19138f3ec..9f6cebd798ee 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c | |||
| @@ -494,16 +494,24 @@ int perf_evsel__open_per_thread(struct perf_evsel *evsel, | |||
| 494 | } | 494 | } |
| 495 | 495 | ||
| 496 | static int perf_event__parse_id_sample(const union perf_event *event, u64 type, | 496 | static int perf_event__parse_id_sample(const union perf_event *event, u64 type, |
| 497 | struct perf_sample *sample) | 497 | struct perf_sample *sample, |
| 498 | bool swapped) | ||
| 498 | { | 499 | { |
| 499 | const u64 *array = event->sample.array; | 500 | const u64 *array = event->sample.array; |
| 501 | union u64_swap u; | ||
| 500 | 502 | ||
| 501 | array += ((event->header.size - | 503 | array += ((event->header.size - |
| 502 | sizeof(event->header)) / sizeof(u64)) - 1; | 504 | sizeof(event->header)) / sizeof(u64)) - 1; |
| 503 | 505 | ||
| 504 | if (type & PERF_SAMPLE_CPU) { | 506 | if (type & PERF_SAMPLE_CPU) { |
| 505 | u32 *p = (u32 *)array; | 507 | u.val64 = *array; |
| 506 | sample->cpu = *p; | 508 | if (swapped) { |
| 509 | /* undo swap of u64, then swap on individual u32s */ | ||
| 510 | u.val64 = bswap_64(u.val64); | ||
| 511 | u.val32[0] = bswap_32(u.val32[0]); | ||
| 512 | } | ||
| 513 | |||
| 514 | sample->cpu = u.val32[0]; | ||
| 507 | array--; | 515 | array--; |
| 508 | } | 516 | } |
| 509 | 517 | ||
| @@ -523,9 +531,16 @@ static int perf_event__parse_id_sample(const union perf_event *event, u64 type, | |||
| 523 | } | 531 | } |
| 524 | 532 | ||
| 525 | if (type & PERF_SAMPLE_TID) { | 533 | if (type & PERF_SAMPLE_TID) { |
| 526 | u32 *p = (u32 *)array; | 534 | u.val64 = *array; |
| 527 | sample->pid = p[0]; | 535 | if (swapped) { |
| 528 | sample->tid = p[1]; | 536 | /* undo swap of u64, then swap on individual u32s */ |
| 537 | u.val64 = bswap_64(u.val64); | ||
| 538 | u.val32[0] = bswap_32(u.val32[0]); | ||
| 539 | u.val32[1] = bswap_32(u.val32[1]); | ||
| 540 | } | ||
| 541 | |||
| 542 | sample->pid = u.val32[0]; | ||
| 543 | sample->tid = u.val32[1]; | ||
| 529 | } | 544 | } |
| 530 | 545 | ||
| 531 | return 0; | 546 | return 0; |
| @@ -562,7 +577,7 @@ int perf_event__parse_sample(const union perf_event *event, u64 type, | |||
| 562 | if (event->header.type != PERF_RECORD_SAMPLE) { | 577 | if (event->header.type != PERF_RECORD_SAMPLE) { |
| 563 | if (!sample_id_all) | 578 | if (!sample_id_all) |
| 564 | return 0; | 579 | return 0; |
| 565 | return perf_event__parse_id_sample(event, type, data); | 580 | return perf_event__parse_id_sample(event, type, data, swapped); |
| 566 | } | 581 | } |
| 567 | 582 | ||
| 568 | array = event->sample.array; | 583 | array = event->sample.array; |
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 2dd5edf161b7..e909d43cf542 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c | |||
| @@ -1942,7 +1942,6 @@ int perf_file_header__read(struct perf_file_header *header, | |||
| 1942 | else | 1942 | else |
| 1943 | return -1; | 1943 | return -1; |
| 1944 | } else if (ph->needs_swap) { | 1944 | } else if (ph->needs_swap) { |
| 1945 | unsigned int i; | ||
| 1946 | /* | 1945 | /* |
| 1947 | * feature bitmap is declared as an array of unsigned longs -- | 1946 | * feature bitmap is declared as an array of unsigned longs -- |
| 1948 | * not good since its size can differ between the host that | 1947 | * not good since its size can differ between the host that |
| @@ -1958,14 +1957,17 @@ int perf_file_header__read(struct perf_file_header *header, | |||
| 1958 | * file), punt and fallback to the original behavior -- | 1957 | * file), punt and fallback to the original behavior -- |
| 1959 | * clearing all feature bits and setting buildid. | 1958 | * clearing all feature bits and setting buildid. |
| 1960 | */ | 1959 | */ |
| 1961 | for (i = 0; i < BITS_TO_LONGS(HEADER_FEAT_BITS); ++i) | 1960 | mem_bswap_64(&header->adds_features, |
| 1962 | header->adds_features[i] = bswap_64(header->adds_features[i]); | 1961 | BITS_TO_U64(HEADER_FEAT_BITS)); |
| 1963 | 1962 | ||
| 1964 | if (!test_bit(HEADER_HOSTNAME, header->adds_features)) { | 1963 | if (!test_bit(HEADER_HOSTNAME, header->adds_features)) { |
| 1965 | for (i = 0; i < BITS_TO_LONGS(HEADER_FEAT_BITS); ++i) { | 1964 | /* unswap as u64 */ |
| 1966 | header->adds_features[i] = bswap_64(header->adds_features[i]); | 1965 | mem_bswap_64(&header->adds_features, |
| 1967 | header->adds_features[i] = bswap_32(header->adds_features[i]); | 1966 | BITS_TO_U64(HEADER_FEAT_BITS)); |
| 1968 | } | 1967 | |
| 1968 | /* unswap as u32 */ | ||
| 1969 | mem_bswap_32(&header->adds_features, | ||
| 1970 | BITS_TO_U32(HEADER_FEAT_BITS)); | ||
| 1969 | } | 1971 | } |
| 1970 | 1972 | ||
| 1971 | if (!test_bit(HEADER_HOSTNAME, header->adds_features)) { | 1973 | if (!test_bit(HEADER_HOSTNAME, header->adds_features)) { |
| @@ -2091,6 +2093,35 @@ static int read_attr(int fd, struct perf_header *ph, | |||
| 2091 | return ret <= 0 ? -1 : 0; | 2093 | return ret <= 0 ? -1 : 0; |
| 2092 | } | 2094 | } |
| 2093 | 2095 | ||
| 2096 | static int perf_evsel__set_tracepoint_name(struct perf_evsel *evsel) | ||
| 2097 | { | ||
| 2098 | struct event_format *event = trace_find_event(evsel->attr.config); | ||
| 2099 | char bf[128]; | ||
| 2100 | |||
| 2101 | if (event == NULL) | ||
| 2102 | return -1; | ||
| 2103 | |||
| 2104 | snprintf(bf, sizeof(bf), "%s:%s", event->system, event->name); | ||
| 2105 | evsel->name = strdup(bf); | ||
| 2106 | if (event->name == NULL) | ||
| 2107 | return -1; | ||
| 2108 | |||
| 2109 | return 0; | ||
| 2110 | } | ||
| 2111 | |||
| 2112 | static int perf_evlist__set_tracepoint_names(struct perf_evlist *evlist) | ||
| 2113 | { | ||
| 2114 | struct perf_evsel *pos; | ||
| 2115 | |||
| 2116 | list_for_each_entry(pos, &evlist->entries, node) { | ||
| 2117 | if (pos->attr.type == PERF_TYPE_TRACEPOINT && | ||
| 2118 | perf_evsel__set_tracepoint_name(pos)) | ||
| 2119 | return -1; | ||
| 2120 | } | ||
| 2121 | |||
| 2122 | return 0; | ||
| 2123 | } | ||
| 2124 | |||
| 2094 | int perf_session__read_header(struct perf_session *session, int fd) | 2125 | int perf_session__read_header(struct perf_session *session, int fd) |
| 2095 | { | 2126 | { |
| 2096 | struct perf_header *header = &session->header; | 2127 | struct perf_header *header = &session->header; |
| @@ -2172,6 +2203,9 @@ int perf_session__read_header(struct perf_session *session, int fd) | |||
| 2172 | 2203 | ||
| 2173 | lseek(fd, header->data_offset, SEEK_SET); | 2204 | lseek(fd, header->data_offset, SEEK_SET); |
| 2174 | 2205 | ||
| 2206 | if (perf_evlist__set_tracepoint_names(session->evlist)) | ||
| 2207 | goto out_delete_evlist; | ||
| 2208 | |||
| 2175 | header->frozen = 1; | 2209 | header->frozen = 1; |
| 2176 | return 0; | 2210 | return 0; |
| 2177 | out_errno: | 2211 | out_errno: |
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index 1293b5ebea4d..514e2a4b367d 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c | |||
| @@ -378,7 +378,7 @@ void hist_entry__free(struct hist_entry *he) | |||
| 378 | * collapse the histogram | 378 | * collapse the histogram |
| 379 | */ | 379 | */ |
| 380 | 380 | ||
| 381 | static bool hists__collapse_insert_entry(struct hists *hists, | 381 | static bool hists__collapse_insert_entry(struct hists *hists __used, |
| 382 | struct rb_root *root, | 382 | struct rb_root *root, |
| 383 | struct hist_entry *he) | 383 | struct hist_entry *he) |
| 384 | { | 384 | { |
| @@ -397,8 +397,9 @@ static bool hists__collapse_insert_entry(struct hists *hists, | |||
| 397 | iter->period += he->period; | 397 | iter->period += he->period; |
| 398 | iter->nr_events += he->nr_events; | 398 | iter->nr_events += he->nr_events; |
| 399 | if (symbol_conf.use_callchain) { | 399 | if (symbol_conf.use_callchain) { |
| 400 | callchain_cursor_reset(&hists->callchain_cursor); | 400 | callchain_cursor_reset(&callchain_cursor); |
| 401 | callchain_merge(&hists->callchain_cursor, iter->callchain, | 401 | callchain_merge(&callchain_cursor, |
| 402 | iter->callchain, | ||
| 402 | he->callchain); | 403 | he->callchain); |
| 403 | } | 404 | } |
| 404 | hist_entry__free(he); | 405 | hist_entry__free(he); |
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index cfc64e293f90..34bb556d6219 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h | |||
| @@ -67,8 +67,6 @@ struct hists { | |||
| 67 | struct events_stats stats; | 67 | struct events_stats stats; |
| 68 | u64 event_stream; | 68 | u64 event_stream; |
| 69 | u16 col_len[HISTC_NR_COLS]; | 69 | u16 col_len[HISTC_NR_COLS]; |
| 70 | /* Best would be to reuse the session callchain cursor */ | ||
| 71 | struct callchain_cursor callchain_cursor; | ||
| 72 | }; | 70 | }; |
| 73 | 71 | ||
| 74 | struct hist_entry *__hists__add_entry(struct hists *self, | 72 | struct hist_entry *__hists__add_entry(struct hists *self, |
diff --git a/tools/perf/util/include/linux/bitops.h b/tools/perf/util/include/linux/bitops.h index f1584833bd22..587a230d2075 100644 --- a/tools/perf/util/include/linux/bitops.h +++ b/tools/perf/util/include/linux/bitops.h | |||
| @@ -8,6 +8,8 @@ | |||
| 8 | #define BITS_PER_LONG __WORDSIZE | 8 | #define BITS_PER_LONG __WORDSIZE |
| 9 | #define BITS_PER_BYTE 8 | 9 | #define BITS_PER_BYTE 8 |
| 10 | #define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long)) | 10 | #define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long)) |
| 11 | #define BITS_TO_U64(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(u64)) | ||
| 12 | #define BITS_TO_U32(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(u32)) | ||
| 11 | 13 | ||
| 12 | #define for_each_set_bit(bit, addr, size) \ | 14 | #define for_each_set_bit(bit, addr, size) \ |
| 13 | for ((bit) = find_first_bit((addr), (size)); \ | 15 | for ((bit) = find_first_bit((addr), (size)); \ |
diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index 35ae56864e4f..a1f4e3669142 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c | |||
| @@ -669,25 +669,26 @@ struct machine *machines__find(struct rb_root *self, pid_t pid) | |||
| 669 | struct machine *machines__findnew(struct rb_root *self, pid_t pid) | 669 | struct machine *machines__findnew(struct rb_root *self, pid_t pid) |
| 670 | { | 670 | { |
| 671 | char path[PATH_MAX]; | 671 | char path[PATH_MAX]; |
| 672 | const char *root_dir; | 672 | const char *root_dir = ""; |
| 673 | struct machine *machine = machines__find(self, pid); | 673 | struct machine *machine = machines__find(self, pid); |
| 674 | 674 | ||
| 675 | if (!machine || machine->pid != pid) { | 675 | if (machine && (machine->pid == pid)) |
| 676 | if (pid == HOST_KERNEL_ID || pid == DEFAULT_GUEST_KERNEL_ID) | 676 | goto out; |
| 677 | root_dir = ""; | 677 | |
| 678 | else { | 678 | if ((pid != HOST_KERNEL_ID) && |
| 679 | if (!symbol_conf.guestmount) | 679 | (pid != DEFAULT_GUEST_KERNEL_ID) && |
| 680 | goto out; | 680 | (symbol_conf.guestmount)) { |
| 681 | sprintf(path, "%s/%d", symbol_conf.guestmount, pid); | 681 | sprintf(path, "%s/%d", symbol_conf.guestmount, pid); |
| 682 | if (access(path, R_OK)) { | 682 | if (access(path, R_OK)) { |
| 683 | pr_err("Can't access file %s\n", path); | 683 | pr_err("Can't access file %s\n", path); |
| 684 | goto out; | 684 | machine = NULL; |
| 685 | } | 685 | goto out; |
| 686 | root_dir = path; | ||
| 687 | } | 686 | } |
| 688 | machine = machines__add(self, pid, root_dir); | 687 | root_dir = path; |
| 689 | } | 688 | } |
| 690 | 689 | ||
| 690 | machine = machines__add(self, pid, root_dir); | ||
| 691 | |||
| 691 | out: | 692 | out: |
| 692 | return machine; | 693 | return machine; |
| 693 | } | 694 | } |
diff --git a/tools/perf/util/pager.c b/tools/perf/util/pager.c index 1915de20dcac..3322b8446e89 100644 --- a/tools/perf/util/pager.c +++ b/tools/perf/util/pager.c | |||
| @@ -57,6 +57,10 @@ void setup_pager(void) | |||
| 57 | } | 57 | } |
| 58 | if (!pager) | 58 | if (!pager) |
| 59 | pager = getenv("PAGER"); | 59 | pager = getenv("PAGER"); |
| 60 | if (!pager) { | ||
| 61 | if (!access("/usr/bin/pager", X_OK)) | ||
| 62 | pager = "/usr/bin/pager"; | ||
| 63 | } | ||
| 60 | if (!pager) | 64 | if (!pager) |
| 61 | pager = "less"; | 65 | pager = "less"; |
| 62 | else if (!*pager || !strcmp(pager, "cat")) | 66 | else if (!*pager || !strcmp(pager, "cat")) |
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index 59dccc98b554..0dda25d82d06 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c | |||
| @@ -2164,16 +2164,12 @@ int del_perf_probe_events(struct strlist *dellist) | |||
| 2164 | 2164 | ||
| 2165 | error: | 2165 | error: |
| 2166 | if (kfd >= 0) { | 2166 | if (kfd >= 0) { |
| 2167 | if (namelist) | 2167 | strlist__delete(namelist); |
| 2168 | strlist__delete(namelist); | ||
| 2169 | |||
| 2170 | close(kfd); | 2168 | close(kfd); |
| 2171 | } | 2169 | } |
| 2172 | 2170 | ||
| 2173 | if (ufd >= 0) { | 2171 | if (ufd >= 0) { |
| 2174 | if (unamelist) | 2172 | strlist__delete(unamelist); |
| 2175 | strlist__delete(unamelist); | ||
| 2176 | |||
| 2177 | close(ufd); | 2173 | close(ufd); |
| 2178 | } | 2174 | } |
| 2179 | 2175 | ||
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 93d355d27109..56142d0fb8d7 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c | |||
| @@ -288,7 +288,8 @@ struct branch_info *machine__resolve_bstack(struct machine *self, | |||
| 288 | return bi; | 288 | return bi; |
| 289 | } | 289 | } |
| 290 | 290 | ||
| 291 | int machine__resolve_callchain(struct machine *self, struct perf_evsel *evsel, | 291 | int machine__resolve_callchain(struct machine *self, |
| 292 | struct perf_evsel *evsel __used, | ||
| 292 | struct thread *thread, | 293 | struct thread *thread, |
| 293 | struct ip_callchain *chain, | 294 | struct ip_callchain *chain, |
| 294 | struct symbol **parent) | 295 | struct symbol **parent) |
| @@ -297,7 +298,12 @@ int machine__resolve_callchain(struct machine *self, struct perf_evsel *evsel, | |||
| 297 | unsigned int i; | 298 | unsigned int i; |
| 298 | int err; | 299 | int err; |
| 299 | 300 | ||
| 300 | callchain_cursor_reset(&evsel->hists.callchain_cursor); | 301 | callchain_cursor_reset(&callchain_cursor); |
| 302 | |||
| 303 | if (chain->nr > PERF_MAX_STACK_DEPTH) { | ||
| 304 | pr_warning("corrupted callchain. skipping...\n"); | ||
| 305 | return 0; | ||
| 306 | } | ||
| 301 | 307 | ||
| 302 | for (i = 0; i < chain->nr; i++) { | 308 | for (i = 0; i < chain->nr; i++) { |
| 303 | u64 ip; | 309 | u64 ip; |
| @@ -317,7 +323,14 @@ int machine__resolve_callchain(struct machine *self, struct perf_evsel *evsel, | |||
| 317 | case PERF_CONTEXT_USER: | 323 | case PERF_CONTEXT_USER: |
| 318 | cpumode = PERF_RECORD_MISC_USER; break; | 324 | cpumode = PERF_RECORD_MISC_USER; break; |
| 319 | default: | 325 | default: |
| 320 | break; | 326 | pr_debug("invalid callchain context: " |
| 327 | "%"PRId64"\n", (s64) ip); | ||
| 328 | /* | ||
| 329 | * It seems the callchain is corrupted. | ||
| 330 | * Discard all. | ||
| 331 | */ | ||
| 332 | callchain_cursor_reset(&callchain_cursor); | ||
| 333 | return 0; | ||
| 321 | } | 334 | } |
| 322 | continue; | 335 | continue; |
| 323 | } | 336 | } |
| @@ -333,7 +346,7 @@ int machine__resolve_callchain(struct machine *self, struct perf_evsel *evsel, | |||
| 333 | break; | 346 | break; |
| 334 | } | 347 | } |
| 335 | 348 | ||
| 336 | err = callchain_cursor_append(&evsel->hists.callchain_cursor, | 349 | err = callchain_cursor_append(&callchain_cursor, |
| 337 | ip, al.map, al.sym); | 350 | ip, al.map, al.sym); |
| 338 | if (err) | 351 | if (err) |
| 339 | return err; | 352 | return err; |
| @@ -429,6 +442,16 @@ static void perf_tool__fill_defaults(struct perf_tool *tool) | |||
| 429 | tool->finished_round = process_finished_round_stub; | 442 | tool->finished_round = process_finished_round_stub; |
| 430 | } | 443 | } |
| 431 | } | 444 | } |
| 445 | |||
| 446 | void mem_bswap_32(void *src, int byte_size) | ||
| 447 | { | ||
| 448 | u32 *m = src; | ||
| 449 | while (byte_size > 0) { | ||
| 450 | *m = bswap_32(*m); | ||
| 451 | byte_size -= sizeof(u32); | ||
| 452 | ++m; | ||
| 453 | } | ||
| 454 | } | ||
| 432 | 455 | ||
| 433 | void mem_bswap_64(void *src, int byte_size) | 456 | void mem_bswap_64(void *src, int byte_size) |
| 434 | { | 457 | { |
| @@ -441,37 +464,65 @@ void mem_bswap_64(void *src, int byte_size) | |||
| 441 | } | 464 | } |
| 442 | } | 465 | } |
| 443 | 466 | ||
| 444 | static void perf_event__all64_swap(union perf_event *event) | 467 | static void swap_sample_id_all(union perf_event *event, void *data) |
| 468 | { | ||
| 469 | void *end = (void *) event + event->header.size; | ||
| 470 | int size = end - data; | ||
| 471 | |||
| 472 | BUG_ON(size % sizeof(u64)); | ||
| 473 | mem_bswap_64(data, size); | ||
| 474 | } | ||
| 475 | |||
| 476 | static void perf_event__all64_swap(union perf_event *event, | ||
| 477 | bool sample_id_all __used) | ||
| 445 | { | 478 | { |
| 446 | struct perf_event_header *hdr = &event->header; | 479 | struct perf_event_header *hdr = &event->header; |
| 447 | mem_bswap_64(hdr + 1, event->header.size - sizeof(*hdr)); | 480 | mem_bswap_64(hdr + 1, event->header.size - sizeof(*hdr)); |
| 448 | } | 481 | } |
| 449 | 482 | ||
| 450 | static void perf_event__comm_swap(union perf_event *event) | 483 | static void perf_event__comm_swap(union perf_event *event, bool sample_id_all) |
| 451 | { | 484 | { |
| 452 | event->comm.pid = bswap_32(event->comm.pid); | 485 | event->comm.pid = bswap_32(event->comm.pid); |
| 453 | event->comm.tid = bswap_32(event->comm.tid); | 486 | event->comm.tid = bswap_32(event->comm.tid); |
| 487 | |||
| 488 | if (sample_id_all) { | ||
| 489 | void *data = &event->comm.comm; | ||
| 490 | |||
| 491 | data += ALIGN(strlen(data) + 1, sizeof(u64)); | ||
| 492 | swap_sample_id_all(event, data); | ||
| 493 | } | ||
| 454 | } | 494 | } |
| 455 | 495 | ||
| 456 | static void perf_event__mmap_swap(union perf_event *event) | 496 | static void perf_event__mmap_swap(union perf_event *event, |
| 497 | bool sample_id_all) | ||
| 457 | { | 498 | { |
| 458 | event->mmap.pid = bswap_32(event->mmap.pid); | 499 | event->mmap.pid = bswap_32(event->mmap.pid); |
| 459 | event->mmap.tid = bswap_32(event->mmap.tid); | 500 | event->mmap.tid = bswap_32(event->mmap.tid); |
| 460 | event->mmap.start = bswap_64(event->mmap.start); | 501 | event->mmap.start = bswap_64(event->mmap.start); |
| 461 | event->mmap.len = bswap_64(event->mmap.len); | 502 | event->mmap.len = bswap_64(event->mmap.len); |
| 462 | event->mmap.pgoff = bswap_64(event->mmap.pgoff); | 503 | event->mmap.pgoff = bswap_64(event->mmap.pgoff); |
| 504 | |||
| 505 | if (sample_id_all) { | ||
| 506 | void *data = &event->mmap.filename; | ||
| 507 | |||
| 508 | data += ALIGN(strlen(data) + 1, sizeof(u64)); | ||
| 509 | swap_sample_id_all(event, data); | ||
| 510 | } | ||
| 463 | } | 511 | } |
| 464 | 512 | ||
| 465 | static void perf_event__task_swap(union perf_event *event) | 513 | static void perf_event__task_swap(union perf_event *event, bool sample_id_all) |
| 466 | { | 514 | { |
| 467 | event->fork.pid = bswap_32(event->fork.pid); | 515 | event->fork.pid = bswap_32(event->fork.pid); |
| 468 | event->fork.tid = bswap_32(event->fork.tid); | 516 | event->fork.tid = bswap_32(event->fork.tid); |
| 469 | event->fork.ppid = bswap_32(event->fork.ppid); | 517 | event->fork.ppid = bswap_32(event->fork.ppid); |
| 470 | event->fork.ptid = bswap_32(event->fork.ptid); | 518 | event->fork.ptid = bswap_32(event->fork.ptid); |
| 471 | event->fork.time = bswap_64(event->fork.time); | 519 | event->fork.time = bswap_64(event->fork.time); |
| 520 | |||
| 521 | if (sample_id_all) | ||
| 522 | swap_sample_id_all(event, &event->fork + 1); | ||
| 472 | } | 523 | } |
| 473 | 524 | ||
| 474 | static void perf_event__read_swap(union perf_event *event) | 525 | static void perf_event__read_swap(union perf_event *event, bool sample_id_all) |
| 475 | { | 526 | { |
| 476 | event->read.pid = bswap_32(event->read.pid); | 527 | event->read.pid = bswap_32(event->read.pid); |
| 477 | event->read.tid = bswap_32(event->read.tid); | 528 | event->read.tid = bswap_32(event->read.tid); |
| @@ -479,6 +530,9 @@ static void perf_event__read_swap(union perf_event *event) | |||
| 479 | event->read.time_enabled = bswap_64(event->read.time_enabled); | 530 | event->read.time_enabled = bswap_64(event->read.time_enabled); |
| 480 | event->read.time_running = bswap_64(event->read.time_running); | 531 | event->read.time_running = bswap_64(event->read.time_running); |
| 481 | event->read.id = bswap_64(event->read.id); | 532 | event->read.id = bswap_64(event->read.id); |
| 533 | |||
| 534 | if (sample_id_all) | ||
| 535 | swap_sample_id_all(event, &event->read + 1); | ||
| 482 | } | 536 | } |
| 483 | 537 | ||
| 484 | static u8 revbyte(u8 b) | 538 | static u8 revbyte(u8 b) |
| @@ -530,7 +584,8 @@ void perf_event__attr_swap(struct perf_event_attr *attr) | |||
| 530 | swap_bitfield((u8 *) (&attr->read_format + 1), sizeof(u64)); | 584 | swap_bitfield((u8 *) (&attr->read_format + 1), sizeof(u64)); |
| 531 | } | 585 | } |
| 532 | 586 | ||
| 533 | static void perf_event__hdr_attr_swap(union perf_event *event) | 587 | static void perf_event__hdr_attr_swap(union perf_event *event, |
| 588 | bool sample_id_all __used) | ||
| 534 | { | 589 | { |
| 535 | size_t size; | 590 | size_t size; |
| 536 | 591 | ||
| @@ -541,18 +596,21 @@ static void perf_event__hdr_attr_swap(union perf_event *event) | |||
| 541 | mem_bswap_64(event->attr.id, size); | 596 | mem_bswap_64(event->attr.id, size); |
| 542 | } | 597 | } |
| 543 | 598 | ||
| 544 | static void perf_event__event_type_swap(union perf_event *event) | 599 | static void perf_event__event_type_swap(union perf_event *event, |
| 600 | bool sample_id_all __used) | ||
| 545 | { | 601 | { |
| 546 | event->event_type.event_type.event_id = | 602 | event->event_type.event_type.event_id = |
| 547 | bswap_64(event->event_type.event_type.event_id); | 603 | bswap_64(event->event_type.event_type.event_id); |
| 548 | } | 604 | } |
| 549 | 605 | ||
| 550 | static void perf_event__tracing_data_swap(union perf_event *event) | 606 | static void perf_event__tracing_data_swap(union perf_event *event, |
| 607 | bool sample_id_all __used) | ||
| 551 | { | 608 | { |
| 552 | event->tracing_data.size = bswap_32(event->tracing_data.size); | 609 | event->tracing_data.size = bswap_32(event->tracing_data.size); |
| 553 | } | 610 | } |
| 554 | 611 | ||
| 555 | typedef void (*perf_event__swap_op)(union perf_event *event); | 612 | typedef void (*perf_event__swap_op)(union perf_event *event, |
| 613 | bool sample_id_all); | ||
| 556 | 614 | ||
| 557 | static perf_event__swap_op perf_event__swap_ops[] = { | 615 | static perf_event__swap_op perf_event__swap_ops[] = { |
| 558 | [PERF_RECORD_MMAP] = perf_event__mmap_swap, | 616 | [PERF_RECORD_MMAP] = perf_event__mmap_swap, |
| @@ -868,7 +926,7 @@ static struct machine * | |||
| 868 | else | 926 | else |
| 869 | pid = event->ip.pid; | 927 | pid = event->ip.pid; |
| 870 | 928 | ||
| 871 | return perf_session__find_machine(session, pid); | 929 | return perf_session__findnew_machine(session, pid); |
| 872 | } | 930 | } |
| 873 | 931 | ||
| 874 | return perf_session__find_host_machine(session); | 932 | return perf_session__find_host_machine(session); |
| @@ -986,6 +1044,15 @@ static int perf_session__process_user_event(struct perf_session *session, union | |||
| 986 | } | 1044 | } |
| 987 | } | 1045 | } |
| 988 | 1046 | ||
| 1047 | static void event_swap(union perf_event *event, bool sample_id_all) | ||
| 1048 | { | ||
| 1049 | perf_event__swap_op swap; | ||
| 1050 | |||
| 1051 | swap = perf_event__swap_ops[event->header.type]; | ||
| 1052 | if (swap) | ||
| 1053 | swap(event, sample_id_all); | ||
| 1054 | } | ||
| 1055 | |||
| 989 | static int perf_session__process_event(struct perf_session *session, | 1056 | static int perf_session__process_event(struct perf_session *session, |
| 990 | union perf_event *event, | 1057 | union perf_event *event, |
| 991 | struct perf_tool *tool, | 1058 | struct perf_tool *tool, |
| @@ -994,9 +1061,8 @@ static int perf_session__process_event(struct perf_session *session, | |||
| 994 | struct perf_sample sample; | 1061 | struct perf_sample sample; |
| 995 | int ret; | 1062 | int ret; |
| 996 | 1063 | ||
| 997 | if (session->header.needs_swap && | 1064 | if (session->header.needs_swap) |
| 998 | perf_event__swap_ops[event->header.type]) | 1065 | event_swap(event, session->sample_id_all); |
| 999 | perf_event__swap_ops[event->header.type](event); | ||
| 1000 | 1066 | ||
| 1001 | if (event->header.type >= PERF_RECORD_HEADER_MAX) | 1067 | if (event->header.type >= PERF_RECORD_HEADER_MAX) |
| 1002 | return -EINVAL; | 1068 | return -EINVAL; |
| @@ -1428,7 +1494,6 @@ void perf_event__print_ip(union perf_event *event, struct perf_sample *sample, | |||
| 1428 | int print_sym, int print_dso, int print_symoffset) | 1494 | int print_sym, int print_dso, int print_symoffset) |
| 1429 | { | 1495 | { |
| 1430 | struct addr_location al; | 1496 | struct addr_location al; |
| 1431 | struct callchain_cursor *cursor = &evsel->hists.callchain_cursor; | ||
| 1432 | struct callchain_cursor_node *node; | 1497 | struct callchain_cursor_node *node; |
| 1433 | 1498 | ||
| 1434 | if (perf_event__preprocess_sample(event, machine, &al, sample, | 1499 | if (perf_event__preprocess_sample(event, machine, &al, sample, |
| @@ -1446,10 +1511,10 @@ void perf_event__print_ip(union perf_event *event, struct perf_sample *sample, | |||
| 1446 | error("Failed to resolve callchain. Skipping\n"); | 1511 | error("Failed to resolve callchain. Skipping\n"); |
| 1447 | return; | 1512 | return; |
| 1448 | } | 1513 | } |
| 1449 | callchain_cursor_commit(cursor); | 1514 | callchain_cursor_commit(&callchain_cursor); |
| 1450 | 1515 | ||
| 1451 | while (1) { | 1516 | while (1) { |
| 1452 | node = callchain_cursor_current(cursor); | 1517 | node = callchain_cursor_current(&callchain_cursor); |
| 1453 | if (!node) | 1518 | if (!node) |
| 1454 | break; | 1519 | break; |
| 1455 | 1520 | ||
| @@ -1460,12 +1525,12 @@ void perf_event__print_ip(union perf_event *event, struct perf_sample *sample, | |||
| 1460 | } | 1525 | } |
| 1461 | if (print_dso) { | 1526 | if (print_dso) { |
| 1462 | printf(" ("); | 1527 | printf(" ("); |
| 1463 | map__fprintf_dsoname(al.map, stdout); | 1528 | map__fprintf_dsoname(node->map, stdout); |
| 1464 | printf(")"); | 1529 | printf(")"); |
| 1465 | } | 1530 | } |
| 1466 | printf("\n"); | 1531 | printf("\n"); |
| 1467 | 1532 | ||
| 1468 | callchain_cursor_advance(cursor); | 1533 | callchain_cursor_advance(&callchain_cursor); |
| 1469 | } | 1534 | } |
| 1470 | 1535 | ||
| 1471 | } else { | 1536 | } else { |
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h index 7a5434c00565..0c702e3f0a36 100644 --- a/tools/perf/util/session.h +++ b/tools/perf/util/session.h | |||
| @@ -80,6 +80,7 @@ struct branch_info *machine__resolve_bstack(struct machine *self, | |||
| 80 | bool perf_session__has_traces(struct perf_session *self, const char *msg); | 80 | bool perf_session__has_traces(struct perf_session *self, const char *msg); |
| 81 | 81 | ||
| 82 | void mem_bswap_64(void *src, int byte_size); | 82 | void mem_bswap_64(void *src, int byte_size); |
| 83 | void mem_bswap_32(void *src, int byte_size); | ||
| 83 | void perf_event__attr_swap(struct perf_event_attr *attr); | 84 | void perf_event__attr_swap(struct perf_event_attr *attr); |
| 84 | 85 | ||
| 85 | int perf_session__create_kernel_maps(struct perf_session *self); | 86 | int perf_session__create_kernel_maps(struct perf_session *self); |
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index e2ba8858f3e1..3e2e5ea0f03f 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c | |||
| @@ -323,6 +323,7 @@ struct dso *dso__new(const char *name) | |||
| 323 | dso->sorted_by_name = 0; | 323 | dso->sorted_by_name = 0; |
| 324 | dso->has_build_id = 0; | 324 | dso->has_build_id = 0; |
| 325 | dso->kernel = DSO_TYPE_USER; | 325 | dso->kernel = DSO_TYPE_USER; |
| 326 | dso->needs_swap = DSO_SWAP__UNSET; | ||
| 326 | INIT_LIST_HEAD(&dso->node); | 327 | INIT_LIST_HEAD(&dso->node); |
| 327 | } | 328 | } |
| 328 | 329 | ||
| @@ -1156,6 +1157,33 @@ static size_t elf_addr_to_index(Elf *elf, GElf_Addr addr) | |||
| 1156 | return -1; | 1157 | return -1; |
| 1157 | } | 1158 | } |
| 1158 | 1159 | ||
| 1160 | static int dso__swap_init(struct dso *dso, unsigned char eidata) | ||
| 1161 | { | ||
| 1162 | static unsigned int const endian = 1; | ||
| 1163 | |||
| 1164 | dso->needs_swap = DSO_SWAP__NO; | ||
| 1165 | |||
| 1166 | switch (eidata) { | ||
| 1167 | case ELFDATA2LSB: | ||
| 1168 | /* We are big endian, DSO is little endian. */ | ||
| 1169 | if (*(unsigned char const *)&endian != 1) | ||
| 1170 | dso->needs_swap = DSO_SWAP__YES; | ||
| 1171 | break; | ||
| 1172 | |||
| 1173 | case ELFDATA2MSB: | ||
| 1174 | /* We are little endian, DSO is big endian. */ | ||
| 1175 | if (*(unsigned char const *)&endian != 0) | ||
| 1176 | dso->needs_swap = DSO_SWAP__YES; | ||
| 1177 | break; | ||
| 1178 | |||
| 1179 | default: | ||
| 1180 | pr_err("unrecognized DSO data encoding %d\n", eidata); | ||
| 1181 | return -EINVAL; | ||
| 1182 | } | ||
| 1183 | |||
| 1184 | return 0; | ||
| 1185 | } | ||
| 1186 | |||
| 1159 | static int dso__load_sym(struct dso *dso, struct map *map, const char *name, | 1187 | static int dso__load_sym(struct dso *dso, struct map *map, const char *name, |
| 1160 | int fd, symbol_filter_t filter, int kmodule, | 1188 | int fd, symbol_filter_t filter, int kmodule, |
| 1161 | int want_symtab) | 1189 | int want_symtab) |
| @@ -1187,6 +1215,9 @@ static int dso__load_sym(struct dso *dso, struct map *map, const char *name, | |||
| 1187 | goto out_elf_end; | 1215 | goto out_elf_end; |
| 1188 | } | 1216 | } |
| 1189 | 1217 | ||
| 1218 | if (dso__swap_init(dso, ehdr.e_ident[EI_DATA])) | ||
| 1219 | goto out_elf_end; | ||
| 1220 | |||
| 1190 | /* Always reject images with a mismatched build-id: */ | 1221 | /* Always reject images with a mismatched build-id: */ |
| 1191 | if (dso->has_build_id) { | 1222 | if (dso->has_build_id) { |
| 1192 | u8 build_id[BUILD_ID_SIZE]; | 1223 | u8 build_id[BUILD_ID_SIZE]; |
| @@ -1272,7 +1303,7 @@ static int dso__load_sym(struct dso *dso, struct map *map, const char *name, | |||
| 1272 | if (opdsec && sym.st_shndx == opdidx) { | 1303 | if (opdsec && sym.st_shndx == opdidx) { |
| 1273 | u32 offset = sym.st_value - opdshdr.sh_addr; | 1304 | u32 offset = sym.st_value - opdshdr.sh_addr; |
| 1274 | u64 *opd = opddata->d_buf + offset; | 1305 | u64 *opd = opddata->d_buf + offset; |
| 1275 | sym.st_value = *opd; | 1306 | sym.st_value = DSO__SWAP(dso, u64, *opd); |
| 1276 | sym.st_shndx = elf_addr_to_index(elf, sym.st_value); | 1307 | sym.st_shndx = elf_addr_to_index(elf, sym.st_value); |
| 1277 | } | 1308 | } |
| 1278 | 1309 | ||
| @@ -2786,8 +2817,11 @@ int machine__load_vmlinux_path(struct machine *machine, enum map_type type, | |||
| 2786 | 2817 | ||
| 2787 | struct map *dso__new_map(const char *name) | 2818 | struct map *dso__new_map(const char *name) |
| 2788 | { | 2819 | { |
| 2820 | struct map *map = NULL; | ||
| 2789 | struct dso *dso = dso__new(name); | 2821 | struct dso *dso = dso__new(name); |
| 2790 | struct map *map = map__new2(0, dso, MAP__FUNCTION); | 2822 | |
| 2823 | if (dso) | ||
| 2824 | map = map__new2(0, dso, MAP__FUNCTION); | ||
| 2791 | 2825 | ||
| 2792 | return map; | 2826 | return map; |
| 2793 | } | 2827 | } |
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index 5649d63798cb..af0752b1aca1 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h | |||
| @@ -9,6 +9,7 @@ | |||
| 9 | #include <linux/list.h> | 9 | #include <linux/list.h> |
| 10 | #include <linux/rbtree.h> | 10 | #include <linux/rbtree.h> |
| 11 | #include <stdio.h> | 11 | #include <stdio.h> |
| 12 | #include <byteswap.h> | ||
| 12 | 13 | ||
| 13 | #ifdef HAVE_CPLUS_DEMANGLE | 14 | #ifdef HAVE_CPLUS_DEMANGLE |
| 14 | extern char *cplus_demangle(const char *, int); | 15 | extern char *cplus_demangle(const char *, int); |
| @@ -160,11 +161,18 @@ enum dso_kernel_type { | |||
| 160 | DSO_TYPE_GUEST_KERNEL | 161 | DSO_TYPE_GUEST_KERNEL |
| 161 | }; | 162 | }; |
| 162 | 163 | ||
| 164 | enum dso_swap_type { | ||
| 165 | DSO_SWAP__UNSET, | ||
| 166 | DSO_SWAP__NO, | ||
| 167 | DSO_SWAP__YES, | ||
| 168 | }; | ||
| 169 | |||
| 163 | struct dso { | 170 | struct dso { |
| 164 | struct list_head node; | 171 | struct list_head node; |
| 165 | struct rb_root symbols[MAP__NR_TYPES]; | 172 | struct rb_root symbols[MAP__NR_TYPES]; |
| 166 | struct rb_root symbol_names[MAP__NR_TYPES]; | 173 | struct rb_root symbol_names[MAP__NR_TYPES]; |
| 167 | enum dso_kernel_type kernel; | 174 | enum dso_kernel_type kernel; |
| 175 | enum dso_swap_type needs_swap; | ||
| 168 | u8 adjust_symbols:1; | 176 | u8 adjust_symbols:1; |
| 169 | u8 has_build_id:1; | 177 | u8 has_build_id:1; |
| 170 | u8 hit:1; | 178 | u8 hit:1; |
| @@ -182,6 +190,28 @@ struct dso { | |||
| 182 | char name[0]; | 190 | char name[0]; |
| 183 | }; | 191 | }; |
| 184 | 192 | ||
| 193 | #define DSO__SWAP(dso, type, val) \ | ||
| 194 | ({ \ | ||
| 195 | type ____r = val; \ | ||
| 196 | BUG_ON(dso->needs_swap == DSO_SWAP__UNSET); \ | ||
| 197 | if (dso->needs_swap == DSO_SWAP__YES) { \ | ||
| 198 | switch (sizeof(____r)) { \ | ||
| 199 | case 2: \ | ||
| 200 | ____r = bswap_16(val); \ | ||
| 201 | break; \ | ||
| 202 | case 4: \ | ||
| 203 | ____r = bswap_32(val); \ | ||
| 204 | break; \ | ||
| 205 | case 8: \ | ||
| 206 | ____r = bswap_64(val); \ | ||
| 207 | break; \ | ||
| 208 | default: \ | ||
| 209 | BUG_ON(1); \ | ||
| 210 | } \ | ||
| 211 | } \ | ||
| 212 | ____r; \ | ||
| 213 | }) | ||
| 214 | |||
| 185 | struct dso *dso__new(const char *name); | 215 | struct dso *dso__new(const char *name); |
| 186 | void dso__delete(struct dso *dso); | 216 | void dso__delete(struct dso *dso); |
| 187 | 217 | ||
diff --git a/tools/perf/util/trace-event-parse.c b/tools/perf/util/trace-event-parse.c index df2fddbf0cd2..5dd3b5ec8411 100644 --- a/tools/perf/util/trace-event-parse.c +++ b/tools/perf/util/trace-event-parse.c | |||
| @@ -198,9 +198,8 @@ void print_trace_event(int cpu, void *data, int size) | |||
| 198 | record.data = data; | 198 | record.data = data; |
| 199 | 199 | ||
| 200 | trace_seq_init(&s); | 200 | trace_seq_init(&s); |
| 201 | pevent_print_event(pevent, &s, &record); | 201 | pevent_event_info(&s, event, &record); |
| 202 | trace_seq_do_printf(&s); | 202 | trace_seq_do_printf(&s); |
| 203 | printf("\n"); | ||
| 204 | } | 203 | } |
| 205 | 204 | ||
| 206 | void print_event(int cpu, void *data, int size, unsigned long long nsecs, | 205 | void print_event(int cpu, void *data, int size, unsigned long long nsecs, |
diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index ab2f682fd44c..16de7ad4850f 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c | |||
| @@ -73,8 +73,8 @@ int backwards_count; | |||
| 73 | char *progname; | 73 | char *progname; |
| 74 | 74 | ||
| 75 | int num_cpus; | 75 | int num_cpus; |
| 76 | cpu_set_t *cpu_mask; | 76 | cpu_set_t *cpu_present_set, *cpu_mask; |
| 77 | size_t cpu_mask_size; | 77 | size_t cpu_present_setsize, cpu_mask_size; |
| 78 | 78 | ||
| 79 | struct counters { | 79 | struct counters { |
| 80 | unsigned long long tsc; /* per thread */ | 80 | unsigned long long tsc; /* per thread */ |
| @@ -103,6 +103,12 @@ struct timeval tv_even; | |||
| 103 | struct timeval tv_odd; | 103 | struct timeval tv_odd; |
| 104 | struct timeval tv_delta; | 104 | struct timeval tv_delta; |
| 105 | 105 | ||
| 106 | int mark_cpu_present(int pkg, int core, int cpu) | ||
| 107 | { | ||
| 108 | CPU_SET_S(cpu, cpu_present_setsize, cpu_present_set); | ||
| 109 | return 0; | ||
| 110 | } | ||
| 111 | |||
| 106 | /* | 112 | /* |
| 107 | * cpu_mask_init(ncpus) | 113 | * cpu_mask_init(ncpus) |
| 108 | * | 114 | * |
| @@ -118,6 +124,18 @@ void cpu_mask_init(int ncpus) | |||
| 118 | } | 124 | } |
| 119 | cpu_mask_size = CPU_ALLOC_SIZE(ncpus); | 125 | cpu_mask_size = CPU_ALLOC_SIZE(ncpus); |
| 120 | CPU_ZERO_S(cpu_mask_size, cpu_mask); | 126 | CPU_ZERO_S(cpu_mask_size, cpu_mask); |
| 127 | |||
| 128 | /* | ||
| 129 | * Allocate and initialize cpu_present_set | ||
| 130 | */ | ||
| 131 | cpu_present_set = CPU_ALLOC(ncpus); | ||
| 132 | if (cpu_present_set == NULL) { | ||
| 133 | perror("CPU_ALLOC"); | ||
| 134 | exit(3); | ||
| 135 | } | ||
| 136 | cpu_present_setsize = CPU_ALLOC_SIZE(ncpus); | ||
| 137 | CPU_ZERO_S(cpu_present_setsize, cpu_present_set); | ||
| 138 | for_all_cpus(mark_cpu_present); | ||
| 121 | } | 139 | } |
| 122 | 140 | ||
| 123 | void cpu_mask_uninit() | 141 | void cpu_mask_uninit() |
| @@ -125,6 +143,9 @@ void cpu_mask_uninit() | |||
| 125 | CPU_FREE(cpu_mask); | 143 | CPU_FREE(cpu_mask); |
| 126 | cpu_mask = NULL; | 144 | cpu_mask = NULL; |
| 127 | cpu_mask_size = 0; | 145 | cpu_mask_size = 0; |
| 146 | CPU_FREE(cpu_present_set); | ||
| 147 | cpu_present_set = NULL; | ||
| 148 | cpu_present_setsize = 0; | ||
| 128 | } | 149 | } |
| 129 | 150 | ||
| 130 | int cpu_migrate(int cpu) | 151 | int cpu_migrate(int cpu) |
| @@ -912,6 +933,8 @@ int is_snb(unsigned int family, unsigned int model) | |||
| 912 | switch (model) { | 933 | switch (model) { |
| 913 | case 0x2A: | 934 | case 0x2A: |
| 914 | case 0x2D: | 935 | case 0x2D: |
| 936 | case 0x3A: /* IVB */ | ||
| 937 | case 0x3D: /* IVB Xeon */ | ||
| 915 | return 1; | 938 | return 1; |
| 916 | } | 939 | } |
| 917 | return 0; | 940 | return 0; |
| @@ -1047,6 +1070,9 @@ int fork_it(char **argv) | |||
| 1047 | int retval; | 1070 | int retval; |
| 1048 | pid_t child_pid; | 1071 | pid_t child_pid; |
| 1049 | get_counters(cnt_even); | 1072 | get_counters(cnt_even); |
| 1073 | |||
| 1074 | /* clear affinity side-effect of get_counters() */ | ||
| 1075 | sched_setaffinity(0, cpu_present_setsize, cpu_present_set); | ||
| 1050 | gettimeofday(&tv_even, (struct timezone *)NULL); | 1076 | gettimeofday(&tv_even, (struct timezone *)NULL); |
| 1051 | 1077 | ||
| 1052 | child_pid = fork(); | 1078 | child_pid = fork(); |
