diff options
Diffstat (limited to 'tools/perf')
-rw-r--r-- | tools/perf/Makefile | 7 | ||||
-rw-r--r-- | tools/perf/builtin-record.c | 4 | ||||
-rw-r--r-- | tools/perf/builtin-report.c | 5 | ||||
-rw-r--r-- | tools/perf/builtin-test.c | 19 | ||||
-rw-r--r-- | tools/perf/builtin-top.c | 23 | ||||
-rw-r--r-- | tools/perf/util/event.h | 3 | ||||
-rw-r--r-- | tools/perf/util/evlist.c | 7 | ||||
-rw-r--r-- | tools/perf/util/evlist.h | 3 | ||||
-rw-r--r-- | tools/perf/util/evsel.c | 15 | ||||
-rw-r--r-- | tools/perf/util/evsel.h | 10 | ||||
-rw-r--r-- | tools/perf/util/header.c | 9 | ||||
-rw-r--r-- | tools/perf/util/intlist.c | 101 | ||||
-rw-r--r-- | tools/perf/util/intlist.h | 75 | ||||
-rw-r--r-- | tools/perf/util/parse-events-test.c | 12 | ||||
-rw-r--r-- | tools/perf/util/parse-options.c | 3 | ||||
-rw-r--r-- | tools/perf/util/python-ext-sources | 2 | ||||
-rw-r--r-- | tools/perf/util/python.c | 6 | ||||
-rw-r--r-- | tools/perf/util/rblist.c | 107 | ||||
-rw-r--r-- | tools/perf/util/rblist.h | 47 | ||||
-rw-r--r-- | tools/perf/util/session.c | 48 | ||||
-rw-r--r-- | tools/perf/util/session.h | 24 | ||||
-rw-r--r-- | tools/perf/util/strlist.c | 130 | ||||
-rw-r--r-- | tools/perf/util/strlist.h | 11 | ||||
-rw-r--r-- | tools/perf/util/symbol.c | 14 | ||||
-rw-r--r-- | tools/perf/util/target.c | 2 |
25 files changed, 500 insertions, 187 deletions
diff --git a/tools/perf/Makefile b/tools/perf/Makefile index 77f124fe57ad..35655c3a7b7a 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile | |||
@@ -319,6 +319,8 @@ LIB_H += $(ARCH_INCLUDE) | |||
319 | LIB_H += util/cgroup.h | 319 | LIB_H += util/cgroup.h |
320 | LIB_H += $(TRACE_EVENT_DIR)event-parse.h | 320 | LIB_H += $(TRACE_EVENT_DIR)event-parse.h |
321 | LIB_H += util/target.h | 321 | LIB_H += util/target.h |
322 | LIB_H += util/rblist.h | ||
323 | LIB_H += util/intlist.h | ||
322 | 324 | ||
323 | LIB_OBJS += $(OUTPUT)util/abspath.o | 325 | LIB_OBJS += $(OUTPUT)util/abspath.o |
324 | LIB_OBJS += $(OUTPUT)util/alias.o | 326 | LIB_OBJS += $(OUTPUT)util/alias.o |
@@ -383,6 +385,8 @@ LIB_OBJS += $(OUTPUT)util/xyarray.o | |||
383 | LIB_OBJS += $(OUTPUT)util/cpumap.o | 385 | LIB_OBJS += $(OUTPUT)util/cpumap.o |
384 | LIB_OBJS += $(OUTPUT)util/cgroup.o | 386 | LIB_OBJS += $(OUTPUT)util/cgroup.o |
385 | LIB_OBJS += $(OUTPUT)util/target.o | 387 | LIB_OBJS += $(OUTPUT)util/target.o |
388 | LIB_OBJS += $(OUTPUT)util/rblist.o | ||
389 | LIB_OBJS += $(OUTPUT)util/intlist.o | ||
386 | 390 | ||
387 | BUILTIN_OBJS += $(OUTPUT)builtin-annotate.o | 391 | BUILTIN_OBJS += $(OUTPUT)builtin-annotate.o |
388 | 392 | ||
@@ -983,7 +987,8 @@ clean: | |||
983 | $(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo $(OUTPUT)common-cmds.h TAGS tags cscope* | 987 | $(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo $(OUTPUT)common-cmds.h TAGS tags cscope* |
984 | $(MAKE) -C Documentation/ clean | 988 | $(MAKE) -C Documentation/ clean |
985 | $(RM) $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)PERF-CFLAGS | 989 | $(RM) $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)PERF-CFLAGS |
986 | $(RM) $(OUTPUT)util/*-{bison,flex}* | 990 | $(RM) $(OUTPUT)util/*-bison* |
991 | $(RM) $(OUTPUT)util/*-flex* | ||
987 | $(python-clean) | 992 | $(python-clean) |
988 | 993 | ||
989 | .PHONY: all install clean strip $(LIBTRACEEVENT) | 994 | .PHONY: all install clean strip $(LIBTRACEEVENT) |
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index f5a6452931e6..4db6e1ba54e3 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c | |||
@@ -313,7 +313,7 @@ try_again: | |||
313 | } | 313 | } |
314 | } | 314 | } |
315 | 315 | ||
316 | perf_session__update_sample_type(session); | 316 | perf_session__set_id_hdr_size(session); |
317 | } | 317 | } |
318 | 318 | ||
319 | static int process_buildids(struct perf_record *rec) | 319 | static int process_buildids(struct perf_record *rec) |
@@ -844,8 +844,6 @@ int cmd_record(int argc, const char **argv, const char *prefix __used) | |||
844 | struct perf_record *rec = &record; | 844 | struct perf_record *rec = &record; |
845 | char errbuf[BUFSIZ]; | 845 | char errbuf[BUFSIZ]; |
846 | 846 | ||
847 | perf_header__set_cmdline(argc, argv); | ||
848 | |||
849 | evsel_list = perf_evlist__new(NULL, NULL); | 847 | evsel_list = perf_evlist__new(NULL, NULL); |
850 | if (evsel_list == NULL) | 848 | if (evsel_list == NULL) |
851 | return -ENOMEM; | 849 | return -ENOMEM; |
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 69b1c1185159..7c88a243b5db 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c | |||
@@ -249,8 +249,9 @@ static int process_read_event(struct perf_tool *tool, | |||
249 | static int perf_report__setup_sample_type(struct perf_report *rep) | 249 | static int perf_report__setup_sample_type(struct perf_report *rep) |
250 | { | 250 | { |
251 | struct perf_session *self = rep->session; | 251 | struct perf_session *self = rep->session; |
252 | u64 sample_type = perf_evlist__sample_type(self->evlist); | ||
252 | 253 | ||
253 | if (!self->fd_pipe && !(self->sample_type & PERF_SAMPLE_CALLCHAIN)) { | 254 | if (!self->fd_pipe && !(sample_type & PERF_SAMPLE_CALLCHAIN)) { |
254 | if (sort__has_parent) { | 255 | if (sort__has_parent) { |
255 | ui__error("Selected --sort parent, but no " | 256 | ui__error("Selected --sort parent, but no " |
256 | "callchain data. Did you call " | 257 | "callchain data. Did you call " |
@@ -274,7 +275,7 @@ static int perf_report__setup_sample_type(struct perf_report *rep) | |||
274 | 275 | ||
275 | if (sort__branch_mode == 1) { | 276 | if (sort__branch_mode == 1) { |
276 | if (!self->fd_pipe && | 277 | if (!self->fd_pipe && |
277 | !(self->sample_type & PERF_SAMPLE_BRANCH_STACK)) { | 278 | !(sample_type & PERF_SAMPLE_BRANCH_STACK)) { |
278 | ui__error("Selected -b but no branch data. " | 279 | ui__error("Selected -b but no branch data. " |
279 | "Did you call perf record without -b?\n"); | 280 | "Did you call perf record without -b?\n"); |
280 | return -1; | 281 | return -1; |
diff --git a/tools/perf/builtin-test.c b/tools/perf/builtin-test.c index d909eb74a0eb..1d592f5cbea9 100644 --- a/tools/perf/builtin-test.c +++ b/tools/perf/builtin-test.c | |||
@@ -478,7 +478,6 @@ static int test__basic_mmap(void) | |||
478 | unsigned int nr_events[nsyscalls], | 478 | unsigned int nr_events[nsyscalls], |
479 | expected_nr_events[nsyscalls], i, j; | 479 | expected_nr_events[nsyscalls], i, j; |
480 | struct perf_evsel *evsels[nsyscalls], *evsel; | 480 | struct perf_evsel *evsels[nsyscalls], *evsel; |
481 | int sample_size = __perf_evsel__sample_size(attr.sample_type); | ||
482 | 481 | ||
483 | for (i = 0; i < nsyscalls; ++i) { | 482 | for (i = 0; i < nsyscalls; ++i) { |
484 | char name[64]; | 483 | char name[64]; |
@@ -563,8 +562,7 @@ static int test__basic_mmap(void) | |||
563 | goto out_munmap; | 562 | goto out_munmap; |
564 | } | 563 | } |
565 | 564 | ||
566 | err = perf_event__parse_sample(event, attr.sample_type, sample_size, | 565 | err = perf_evlist__parse_sample(evlist, event, &sample, false); |
567 | false, &sample, false); | ||
568 | if (err) { | 566 | if (err) { |
569 | pr_err("Can't parse sample, err = %d\n", err); | 567 | pr_err("Can't parse sample, err = %d\n", err); |
570 | goto out_munmap; | 568 | goto out_munmap; |
@@ -661,12 +659,12 @@ static int test__PERF_RECORD(void) | |||
661 | const char *cmd = "sleep"; | 659 | const char *cmd = "sleep"; |
662 | const char *argv[] = { cmd, "1", NULL, }; | 660 | const char *argv[] = { cmd, "1", NULL, }; |
663 | char *bname; | 661 | char *bname; |
664 | u64 sample_type, prev_time = 0; | 662 | u64 prev_time = 0; |
665 | bool found_cmd_mmap = false, | 663 | bool found_cmd_mmap = false, |
666 | found_libc_mmap = false, | 664 | found_libc_mmap = false, |
667 | found_vdso_mmap = false, | 665 | found_vdso_mmap = false, |
668 | found_ld_mmap = false; | 666 | found_ld_mmap = false; |
669 | int err = -1, errs = 0, i, wakeups = 0, sample_size; | 667 | int err = -1, errs = 0, i, wakeups = 0; |
670 | u32 cpu; | 668 | u32 cpu; |
671 | int total_events = 0, nr_events[PERF_RECORD_MAX] = { 0, }; | 669 | int total_events = 0, nr_events[PERF_RECORD_MAX] = { 0, }; |
672 | 670 | ||
@@ -757,13 +755,6 @@ static int test__PERF_RECORD(void) | |||
757 | } | 755 | } |
758 | 756 | ||
759 | /* | 757 | /* |
760 | * We'll need these two to parse the PERF_SAMPLE_* fields in each | ||
761 | * event. | ||
762 | */ | ||
763 | sample_type = perf_evlist__sample_type(evlist); | ||
764 | sample_size = __perf_evsel__sample_size(sample_type); | ||
765 | |||
766 | /* | ||
767 | * Now that all is properly set up, enable the events, they will | 758 | * Now that all is properly set up, enable the events, they will |
768 | * count just on workload.pid, which will start... | 759 | * count just on workload.pid, which will start... |
769 | */ | 760 | */ |
@@ -788,9 +779,7 @@ static int test__PERF_RECORD(void) | |||
788 | if (type < PERF_RECORD_MAX) | 779 | if (type < PERF_RECORD_MAX) |
789 | nr_events[type]++; | 780 | nr_events[type]++; |
790 | 781 | ||
791 | err = perf_event__parse_sample(event, sample_type, | 782 | err = perf_evlist__parse_sample(evlist, event, &sample, false); |
792 | sample_size, true, | ||
793 | &sample, false); | ||
794 | if (err < 0) { | 783 | if (err < 0) { |
795 | if (verbose) | 784 | if (verbose) |
796 | perf_event__fprintf(event, stderr); | 785 | perf_event__fprintf(event, stderr); |
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 35e86c6df713..68cd61ef6ac5 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c | |||
@@ -38,6 +38,7 @@ | |||
38 | #include "util/cpumap.h" | 38 | #include "util/cpumap.h" |
39 | #include "util/xyarray.h" | 39 | #include "util/xyarray.h" |
40 | #include "util/sort.h" | 40 | #include "util/sort.h" |
41 | #include "util/intlist.h" | ||
41 | 42 | ||
42 | #include "util/debug.h" | 43 | #include "util/debug.h" |
43 | 44 | ||
@@ -706,8 +707,16 @@ static void perf_event__process_sample(struct perf_tool *tool, | |||
706 | int err; | 707 | int err; |
707 | 708 | ||
708 | if (!machine && perf_guest) { | 709 | if (!machine && perf_guest) { |
709 | pr_err("Can't find guest [%d]'s kernel information\n", | 710 | static struct intlist *seen; |
710 | event->ip.pid); | 711 | |
712 | if (!seen) | ||
713 | seen = intlist__new(); | ||
714 | |||
715 | if (!intlist__has_entry(seen, event->ip.pid)) { | ||
716 | pr_err("Can't find guest [%d]'s kernel information\n", | ||
717 | event->ip.pid); | ||
718 | intlist__add(seen, event->ip.pid); | ||
719 | } | ||
711 | return; | 720 | return; |
712 | } | 721 | } |
713 | 722 | ||
@@ -811,7 +820,7 @@ static void perf_top__mmap_read_idx(struct perf_top *top, int idx) | |||
811 | int ret; | 820 | int ret; |
812 | 821 | ||
813 | while ((event = perf_evlist__mmap_read(top->evlist, idx)) != NULL) { | 822 | while ((event = perf_evlist__mmap_read(top->evlist, idx)) != NULL) { |
814 | ret = perf_session__parse_sample(session, event, &sample); | 823 | ret = perf_evlist__parse_sample(top->evlist, event, &sample, false); |
815 | if (ret) { | 824 | if (ret) { |
816 | pr_err("Can't parse sample, err = %d\n", ret); | 825 | pr_err("Can't parse sample, err = %d\n", ret); |
817 | continue; | 826 | continue; |
@@ -943,8 +952,10 @@ try_again: | |||
943 | * based cpu-clock-tick sw counter, which | 952 | * based cpu-clock-tick sw counter, which |
944 | * is always available even if no PMU support: | 953 | * is always available even if no PMU support: |
945 | */ | 954 | */ |
946 | if (attr->type == PERF_TYPE_HARDWARE && | 955 | if ((err == ENOENT || err == ENXIO) && |
947 | attr->config == PERF_COUNT_HW_CPU_CYCLES) { | 956 | (attr->type == PERF_TYPE_HARDWARE) && |
957 | (attr->config == PERF_COUNT_HW_CPU_CYCLES)) { | ||
958 | |||
948 | if (verbose) | 959 | if (verbose) |
949 | ui__warning("Cycles event not supported,\n" | 960 | ui__warning("Cycles event not supported,\n" |
950 | "trying to fall back to cpu-clock-ticks\n"); | 961 | "trying to fall back to cpu-clock-ticks\n"); |
@@ -1032,7 +1043,7 @@ static int __cmd_top(struct perf_top *top) | |||
1032 | &top->session->host_machine); | 1043 | &top->session->host_machine); |
1033 | perf_top__start_counters(top); | 1044 | perf_top__start_counters(top); |
1034 | top->session->evlist = top->evlist; | 1045 | top->session->evlist = top->evlist; |
1035 | perf_session__update_sample_type(top->session); | 1046 | perf_session__set_id_hdr_size(top->session); |
1036 | 1047 | ||
1037 | /* Wait for a minimal set of events before starting the snapshot */ | 1048 | /* Wait for a minimal set of events before starting the snapshot */ |
1038 | poll(top->evlist->pollfd, top->evlist->nr_fds, 100); | 1049 | poll(top->evlist->pollfd, top->evlist->nr_fds, 100); |
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index 1b197280c621..d84870b06426 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h | |||
@@ -197,9 +197,6 @@ int perf_event__preprocess_sample(const union perf_event *self, | |||
197 | 197 | ||
198 | const char *perf_event__name(unsigned int id); | 198 | const char *perf_event__name(unsigned int id); |
199 | 199 | ||
200 | int perf_event__parse_sample(const union perf_event *event, u64 type, | ||
201 | int sample_size, bool sample_id_all, | ||
202 | struct perf_sample *sample, bool swapped); | ||
203 | int perf_event__synthesize_sample(union perf_event *event, u64 type, | 200 | int perf_event__synthesize_sample(union perf_event *event, u64 type, |
204 | const struct perf_sample *sample, | 201 | const struct perf_sample *sample, |
205 | bool swapped); | 202 | bool swapped); |
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 3edfd3483816..9b38681add9e 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c | |||
@@ -881,3 +881,10 @@ int perf_evlist__start_workload(struct perf_evlist *evlist) | |||
881 | 881 | ||
882 | return 0; | 882 | return 0; |
883 | } | 883 | } |
884 | |||
885 | int perf_evlist__parse_sample(struct perf_evlist *evlist, union perf_event *event, | ||
886 | struct perf_sample *sample, bool swapped) | ||
887 | { | ||
888 | struct perf_evsel *e = list_entry(evlist->entries.next, struct perf_evsel, node); | ||
889 | return perf_evsel__parse_sample(e, event, sample, swapped); | ||
890 | } | ||
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index 40d4d3cdced0..528c1acd9298 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h | |||
@@ -122,6 +122,9 @@ u64 perf_evlist__sample_type(const struct perf_evlist *evlist); | |||
122 | bool perf_evlist__sample_id_all(const const struct perf_evlist *evlist); | 122 | bool perf_evlist__sample_id_all(const const struct perf_evlist *evlist); |
123 | u16 perf_evlist__id_hdr_size(const struct perf_evlist *evlist); | 123 | u16 perf_evlist__id_hdr_size(const struct perf_evlist *evlist); |
124 | 124 | ||
125 | int perf_evlist__parse_sample(struct perf_evlist *evlist, union perf_event *event, | ||
126 | struct perf_sample *sample, bool swapped); | ||
127 | |||
125 | bool perf_evlist__valid_sample_type(const struct perf_evlist *evlist); | 128 | bool perf_evlist__valid_sample_type(const struct perf_evlist *evlist); |
126 | bool perf_evlist__valid_sample_id_all(const struct perf_evlist *evlist); | 129 | bool perf_evlist__valid_sample_id_all(const struct perf_evlist *evlist); |
127 | 130 | ||
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index e81771364867..2eaae140def2 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c | |||
@@ -20,7 +20,7 @@ | |||
20 | #define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y)) | 20 | #define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y)) |
21 | #define GROUP_FD(group_fd, cpu) (*(int *)xyarray__entry(group_fd, cpu, 0)) | 21 | #define GROUP_FD(group_fd, cpu) (*(int *)xyarray__entry(group_fd, cpu, 0)) |
22 | 22 | ||
23 | int __perf_evsel__sample_size(u64 sample_type) | 23 | static int __perf_evsel__sample_size(u64 sample_type) |
24 | { | 24 | { |
25 | u64 mask = sample_type & PERF_SAMPLE_MASK; | 25 | u64 mask = sample_type & PERF_SAMPLE_MASK; |
26 | int size = 0; | 26 | int size = 0; |
@@ -53,6 +53,7 @@ void perf_evsel__init(struct perf_evsel *evsel, | |||
53 | evsel->attr = *attr; | 53 | evsel->attr = *attr; |
54 | INIT_LIST_HEAD(&evsel->node); | 54 | INIT_LIST_HEAD(&evsel->node); |
55 | hists__init(&evsel->hists); | 55 | hists__init(&evsel->hists); |
56 | evsel->sample_size = __perf_evsel__sample_size(attr->sample_type); | ||
56 | } | 57 | } |
57 | 58 | ||
58 | struct perf_evsel *perf_evsel__new(struct perf_event_attr *attr, int idx) | 59 | struct perf_evsel *perf_evsel__new(struct perf_event_attr *attr, int idx) |
@@ -728,10 +729,10 @@ static bool sample_overlap(const union perf_event *event, | |||
728 | return false; | 729 | return false; |
729 | } | 730 | } |
730 | 731 | ||
731 | int perf_event__parse_sample(const union perf_event *event, u64 type, | 732 | int perf_evsel__parse_sample(struct perf_evsel *evsel, union perf_event *event, |
732 | int sample_size, bool sample_id_all, | ||
733 | struct perf_sample *data, bool swapped) | 733 | struct perf_sample *data, bool swapped) |
734 | { | 734 | { |
735 | u64 type = evsel->attr.sample_type; | ||
735 | const u64 *array; | 736 | const u64 *array; |
736 | 737 | ||
737 | /* | 738 | /* |
@@ -746,14 +747,14 @@ int perf_event__parse_sample(const union perf_event *event, u64 type, | |||
746 | data->period = 1; | 747 | data->period = 1; |
747 | 748 | ||
748 | if (event->header.type != PERF_RECORD_SAMPLE) { | 749 | if (event->header.type != PERF_RECORD_SAMPLE) { |
749 | if (!sample_id_all) | 750 | if (!evsel->attr.sample_id_all) |
750 | return 0; | 751 | return 0; |
751 | return perf_event__parse_id_sample(event, type, data, swapped); | 752 | return perf_event__parse_id_sample(event, type, data, swapped); |
752 | } | 753 | } |
753 | 754 | ||
754 | array = event->sample.array; | 755 | array = event->sample.array; |
755 | 756 | ||
756 | if (sample_size + sizeof(event->header) > event->header.size) | 757 | if (evsel->sample_size + sizeof(event->header) > event->header.size) |
757 | return -EFAULT; | 758 | return -EFAULT; |
758 | 759 | ||
759 | if (type & PERF_SAMPLE_IP) { | 760 | if (type & PERF_SAMPLE_IP) { |
@@ -895,7 +896,7 @@ int perf_event__synthesize_sample(union perf_event *event, u64 type, | |||
895 | u.val32[1] = sample->tid; | 896 | u.val32[1] = sample->tid; |
896 | if (swapped) { | 897 | if (swapped) { |
897 | /* | 898 | /* |
898 | * Inverse of what is done in perf_event__parse_sample | 899 | * Inverse of what is done in perf_evsel__parse_sample |
899 | */ | 900 | */ |
900 | u.val32[0] = bswap_32(u.val32[0]); | 901 | u.val32[0] = bswap_32(u.val32[0]); |
901 | u.val32[1] = bswap_32(u.val32[1]); | 902 | u.val32[1] = bswap_32(u.val32[1]); |
@@ -930,7 +931,7 @@ int perf_event__synthesize_sample(union perf_event *event, u64 type, | |||
930 | u.val32[0] = sample->cpu; | 931 | u.val32[0] = sample->cpu; |
931 | if (swapped) { | 932 | if (swapped) { |
932 | /* | 933 | /* |
933 | * Inverse of what is done in perf_event__parse_sample | 934 | * Inverse of what is done in perf_evsel__parse_sample |
934 | */ | 935 | */ |
935 | u.val32[0] = bswap_32(u.val32[0]); | 936 | u.val32[0] = bswap_32(u.val32[0]); |
936 | u.val64 = bswap_64(u.val64); | 937 | u.val64 = bswap_64(u.val64); |
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index 67cc5033d192..b559929983bb 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h | |||
@@ -65,6 +65,7 @@ struct perf_evsel { | |||
65 | void *func; | 65 | void *func; |
66 | void *data; | 66 | void *data; |
67 | } handler; | 67 | } handler; |
68 | unsigned int sample_size; | ||
68 | bool supported; | 69 | bool supported; |
69 | }; | 70 | }; |
70 | 71 | ||
@@ -177,13 +178,8 @@ static inline int perf_evsel__read_scaled(struct perf_evsel *evsel, | |||
177 | return __perf_evsel__read(evsel, ncpus, nthreads, true); | 178 | return __perf_evsel__read(evsel, ncpus, nthreads, true); |
178 | } | 179 | } |
179 | 180 | ||
180 | int __perf_evsel__sample_size(u64 sample_type); | ||
181 | |||
182 | static inline int perf_evsel__sample_size(struct perf_evsel *evsel) | ||
183 | { | ||
184 | return __perf_evsel__sample_size(evsel->attr.sample_type); | ||
185 | } | ||
186 | |||
187 | void hists__init(struct hists *hists); | 181 | void hists__init(struct hists *hists); |
188 | 182 | ||
183 | int perf_evsel__parse_sample(struct perf_evsel *evsel, union perf_event *event, | ||
184 | struct perf_sample *sample, bool swapped); | ||
189 | #endif /* __PERF_EVSEL_H */ | 185 | #endif /* __PERF_EVSEL_H */ |
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 3a6d20443330..74ea3c2f8138 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c | |||
@@ -174,6 +174,15 @@ perf_header__set_cmdline(int argc, const char **argv) | |||
174 | { | 174 | { |
175 | int i; | 175 | int i; |
176 | 176 | ||
177 | /* | ||
178 | * If header_argv has already been set, do not override it. | ||
179 | * This allows a command to set the cmdline, parse args and | ||
180 | * then call another builtin function that implements a | ||
181 | * command -- e.g, cmd_kvm calling cmd_record. | ||
182 | */ | ||
183 | if (header_argv) | ||
184 | return 0; | ||
185 | |||
177 | header_argc = (u32)argc; | 186 | header_argc = (u32)argc; |
178 | 187 | ||
179 | /* do not include NULL termination */ | 188 | /* do not include NULL termination */ |
diff --git a/tools/perf/util/intlist.c b/tools/perf/util/intlist.c new file mode 100644 index 000000000000..fd530dced9cb --- /dev/null +++ b/tools/perf/util/intlist.c | |||
@@ -0,0 +1,101 @@ | |||
1 | /* | ||
2 | * Based on intlist.c by: | ||
3 | * (c) 2009 Arnaldo Carvalho de Melo <acme@redhat.com> | ||
4 | * | ||
5 | * Licensed under the GPLv2. | ||
6 | */ | ||
7 | |||
8 | #include <errno.h> | ||
9 | #include <stdlib.h> | ||
10 | #include <linux/compiler.h> | ||
11 | |||
12 | #include "intlist.h" | ||
13 | |||
14 | static struct rb_node *intlist__node_new(struct rblist *rblist __used, | ||
15 | const void *entry) | ||
16 | { | ||
17 | int i = (int)((long)entry); | ||
18 | struct rb_node *rc = NULL; | ||
19 | struct int_node *node = malloc(sizeof(*node)); | ||
20 | |||
21 | if (node != NULL) { | ||
22 | node->i = i; | ||
23 | rc = &node->rb_node; | ||
24 | } | ||
25 | |||
26 | return rc; | ||
27 | } | ||
28 | |||
29 | static void int_node__delete(struct int_node *ilist) | ||
30 | { | ||
31 | free(ilist); | ||
32 | } | ||
33 | |||
34 | static void intlist__node_delete(struct rblist *rblist __used, | ||
35 | struct rb_node *rb_node) | ||
36 | { | ||
37 | struct int_node *node = container_of(rb_node, struct int_node, rb_node); | ||
38 | |||
39 | int_node__delete(node); | ||
40 | } | ||
41 | |||
42 | static int intlist__node_cmp(struct rb_node *rb_node, const void *entry) | ||
43 | { | ||
44 | int i = (int)((long)entry); | ||
45 | struct int_node *node = container_of(rb_node, struct int_node, rb_node); | ||
46 | |||
47 | return node->i - i; | ||
48 | } | ||
49 | |||
50 | int intlist__add(struct intlist *ilist, int i) | ||
51 | { | ||
52 | return rblist__add_node(&ilist->rblist, (void *)((long)i)); | ||
53 | } | ||
54 | |||
55 | void intlist__remove(struct intlist *ilist __used, struct int_node *node) | ||
56 | { | ||
57 | int_node__delete(node); | ||
58 | } | ||
59 | |||
60 | struct int_node *intlist__find(struct intlist *ilist, int i) | ||
61 | { | ||
62 | struct int_node *node = NULL; | ||
63 | struct rb_node *rb_node = rblist__find(&ilist->rblist, (void *)((long)i)); | ||
64 | |||
65 | if (rb_node) | ||
66 | node = container_of(rb_node, struct int_node, rb_node); | ||
67 | |||
68 | return node; | ||
69 | } | ||
70 | |||
71 | struct intlist *intlist__new(void) | ||
72 | { | ||
73 | struct intlist *ilist = malloc(sizeof(*ilist)); | ||
74 | |||
75 | if (ilist != NULL) { | ||
76 | rblist__init(&ilist->rblist); | ||
77 | ilist->rblist.node_cmp = intlist__node_cmp; | ||
78 | ilist->rblist.node_new = intlist__node_new; | ||
79 | ilist->rblist.node_delete = intlist__node_delete; | ||
80 | } | ||
81 | |||
82 | return ilist; | ||
83 | } | ||
84 | |||
85 | void intlist__delete(struct intlist *ilist) | ||
86 | { | ||
87 | if (ilist != NULL) | ||
88 | rblist__delete(&ilist->rblist); | ||
89 | } | ||
90 | |||
91 | struct int_node *intlist__entry(const struct intlist *ilist, unsigned int idx) | ||
92 | { | ||
93 | struct int_node *node = NULL; | ||
94 | struct rb_node *rb_node; | ||
95 | |||
96 | rb_node = rblist__entry(&ilist->rblist, idx); | ||
97 | if (rb_node) | ||
98 | node = container_of(rb_node, struct int_node, rb_node); | ||
99 | |||
100 | return node; | ||
101 | } | ||
diff --git a/tools/perf/util/intlist.h b/tools/perf/util/intlist.h new file mode 100644 index 000000000000..6d63ab90db50 --- /dev/null +++ b/tools/perf/util/intlist.h | |||
@@ -0,0 +1,75 @@ | |||
1 | #ifndef __PERF_INTLIST_H | ||
2 | #define __PERF_INTLIST_H | ||
3 | |||
4 | #include <linux/rbtree.h> | ||
5 | #include <stdbool.h> | ||
6 | |||
7 | #include "rblist.h" | ||
8 | |||
9 | struct int_node { | ||
10 | struct rb_node rb_node; | ||
11 | int i; | ||
12 | }; | ||
13 | |||
14 | struct intlist { | ||
15 | struct rblist rblist; | ||
16 | }; | ||
17 | |||
18 | struct intlist *intlist__new(void); | ||
19 | void intlist__delete(struct intlist *ilist); | ||
20 | |||
21 | void intlist__remove(struct intlist *ilist, struct int_node *in); | ||
22 | int intlist__add(struct intlist *ilist, int i); | ||
23 | |||
24 | struct int_node *intlist__entry(const struct intlist *ilist, unsigned int idx); | ||
25 | struct int_node *intlist__find(struct intlist *ilist, int i); | ||
26 | |||
27 | static inline bool intlist__has_entry(struct intlist *ilist, int i) | ||
28 | { | ||
29 | return intlist__find(ilist, i) != NULL; | ||
30 | } | ||
31 | |||
32 | static inline bool intlist__empty(const struct intlist *ilist) | ||
33 | { | ||
34 | return rblist__empty(&ilist->rblist); | ||
35 | } | ||
36 | |||
37 | static inline unsigned int intlist__nr_entries(const struct intlist *ilist) | ||
38 | { | ||
39 | return rblist__nr_entries(&ilist->rblist); | ||
40 | } | ||
41 | |||
42 | /* For intlist iteration */ | ||
43 | static inline struct int_node *intlist__first(struct intlist *ilist) | ||
44 | { | ||
45 | struct rb_node *rn = rb_first(&ilist->rblist.entries); | ||
46 | return rn ? rb_entry(rn, struct int_node, rb_node) : NULL; | ||
47 | } | ||
48 | static inline struct int_node *intlist__next(struct int_node *in) | ||
49 | { | ||
50 | struct rb_node *rn; | ||
51 | if (!in) | ||
52 | return NULL; | ||
53 | rn = rb_next(&in->rb_node); | ||
54 | return rn ? rb_entry(rn, struct int_node, rb_node) : NULL; | ||
55 | } | ||
56 | |||
57 | /** | ||
58 | * intlist_for_each - iterate over a intlist | ||
59 | * @pos: the &struct int_node to use as a loop cursor. | ||
60 | * @ilist: the &struct intlist for loop. | ||
61 | */ | ||
62 | #define intlist__for_each(pos, ilist) \ | ||
63 | for (pos = intlist__first(ilist); pos; pos = intlist__next(pos)) | ||
64 | |||
65 | /** | ||
66 | * intlist_for_each_safe - iterate over a intlist safe against removal of | ||
67 | * int_node | ||
68 | * @pos: the &struct int_node to use as a loop cursor. | ||
69 | * @n: another &struct int_node to use as temporary storage. | ||
70 | * @ilist: the &struct intlist for loop. | ||
71 | */ | ||
72 | #define intlist__for_each_safe(pos, n, ilist) \ | ||
73 | for (pos = intlist__first(ilist), n = intlist__next(pos); pos;\ | ||
74 | pos = n, n = intlist__next(n)) | ||
75 | #endif /* __PERF_INTLIST_H */ | ||
diff --git a/tools/perf/util/parse-events-test.c b/tools/perf/util/parse-events-test.c index 1b997d2b89ce..127d648cc548 100644 --- a/tools/perf/util/parse-events-test.c +++ b/tools/perf/util/parse-events-test.c | |||
@@ -13,6 +13,9 @@ do { \ | |||
13 | } \ | 13 | } \ |
14 | } while (0) | 14 | } while (0) |
15 | 15 | ||
16 | #define PERF_TP_SAMPLE_TYPE (PERF_SAMPLE_RAW | PERF_SAMPLE_TIME | \ | ||
17 | PERF_SAMPLE_CPU | PERF_SAMPLE_PERIOD) | ||
18 | |||
16 | static int test__checkevent_tracepoint(struct perf_evlist *evlist) | 19 | static int test__checkevent_tracepoint(struct perf_evlist *evlist) |
17 | { | 20 | { |
18 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | 21 | struct perf_evsel *evsel = list_entry(evlist->entries.next, |
@@ -21,8 +24,7 @@ static int test__checkevent_tracepoint(struct perf_evlist *evlist) | |||
21 | TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); | 24 | TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); |
22 | TEST_ASSERT_VAL("wrong type", PERF_TYPE_TRACEPOINT == evsel->attr.type); | 25 | TEST_ASSERT_VAL("wrong type", PERF_TYPE_TRACEPOINT == evsel->attr.type); |
23 | TEST_ASSERT_VAL("wrong sample_type", | 26 | TEST_ASSERT_VAL("wrong sample_type", |
24 | (PERF_SAMPLE_RAW | PERF_SAMPLE_TIME | PERF_SAMPLE_CPU) == | 27 | PERF_TP_SAMPLE_TYPE == evsel->attr.sample_type); |
25 | evsel->attr.sample_type); | ||
26 | TEST_ASSERT_VAL("wrong sample_period", 1 == evsel->attr.sample_period); | 28 | TEST_ASSERT_VAL("wrong sample_period", 1 == evsel->attr.sample_period); |
27 | return 0; | 29 | return 0; |
28 | } | 30 | } |
@@ -37,8 +39,7 @@ static int test__checkevent_tracepoint_multi(struct perf_evlist *evlist) | |||
37 | TEST_ASSERT_VAL("wrong type", | 39 | TEST_ASSERT_VAL("wrong type", |
38 | PERF_TYPE_TRACEPOINT == evsel->attr.type); | 40 | PERF_TYPE_TRACEPOINT == evsel->attr.type); |
39 | TEST_ASSERT_VAL("wrong sample_type", | 41 | TEST_ASSERT_VAL("wrong sample_type", |
40 | (PERF_SAMPLE_RAW | PERF_SAMPLE_TIME | PERF_SAMPLE_CPU) | 42 | PERF_TP_SAMPLE_TYPE == evsel->attr.sample_type); |
41 | == evsel->attr.sample_type); | ||
42 | TEST_ASSERT_VAL("wrong sample_period", | 43 | TEST_ASSERT_VAL("wrong sample_period", |
43 | 1 == evsel->attr.sample_period); | 44 | 1 == evsel->attr.sample_period); |
44 | } | 45 | } |
@@ -428,8 +429,7 @@ static int test__checkevent_list(struct perf_evlist *evlist) | |||
428 | evsel = list_entry(evsel->node.next, struct perf_evsel, node); | 429 | evsel = list_entry(evsel->node.next, struct perf_evsel, node); |
429 | TEST_ASSERT_VAL("wrong type", PERF_TYPE_TRACEPOINT == evsel->attr.type); | 430 | TEST_ASSERT_VAL("wrong type", PERF_TYPE_TRACEPOINT == evsel->attr.type); |
430 | TEST_ASSERT_VAL("wrong sample_type", | 431 | TEST_ASSERT_VAL("wrong sample_type", |
431 | (PERF_SAMPLE_RAW | PERF_SAMPLE_TIME | PERF_SAMPLE_CPU) == | 432 | PERF_TP_SAMPLE_TYPE == evsel->attr.sample_type); |
432 | evsel->attr.sample_type); | ||
433 | TEST_ASSERT_VAL("wrong sample_period", 1 == evsel->attr.sample_period); | 433 | TEST_ASSERT_VAL("wrong sample_period", 1 == evsel->attr.sample_period); |
434 | TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); | 434 | TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); |
435 | TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); | 435 | TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); |
diff --git a/tools/perf/util/parse-options.c b/tools/perf/util/parse-options.c index 99d02aa57dbf..594f8fad5ecd 100644 --- a/tools/perf/util/parse-options.c +++ b/tools/perf/util/parse-options.c | |||
@@ -1,6 +1,7 @@ | |||
1 | #include "util.h" | 1 | #include "util.h" |
2 | #include "parse-options.h" | 2 | #include "parse-options.h" |
3 | #include "cache.h" | 3 | #include "cache.h" |
4 | #include "header.h" | ||
4 | 5 | ||
5 | #define OPT_SHORT 1 | 6 | #define OPT_SHORT 1 |
6 | #define OPT_UNSET 2 | 7 | #define OPT_UNSET 2 |
@@ -413,6 +414,8 @@ int parse_options(int argc, const char **argv, const struct option *options, | |||
413 | { | 414 | { |
414 | struct parse_opt_ctx_t ctx; | 415 | struct parse_opt_ctx_t ctx; |
415 | 416 | ||
417 | perf_header__set_cmdline(argc, argv); | ||
418 | |||
416 | parse_options_start(&ctx, argc, argv, flags); | 419 | parse_options_start(&ctx, argc, argv, flags); |
417 | switch (parse_options_step(&ctx, options, usagestr)) { | 420 | switch (parse_options_step(&ctx, options, usagestr)) { |
418 | case PARSE_OPT_HELP: | 421 | case PARSE_OPT_HELP: |
diff --git a/tools/perf/util/python-ext-sources b/tools/perf/util/python-ext-sources index 2884e67ee625..213362850abd 100644 --- a/tools/perf/util/python-ext-sources +++ b/tools/perf/util/python-ext-sources | |||
@@ -10,10 +10,12 @@ util/ctype.c | |||
10 | util/evlist.c | 10 | util/evlist.c |
11 | util/evsel.c | 11 | util/evsel.c |
12 | util/cpumap.c | 12 | util/cpumap.c |
13 | util/hweight.c | ||
13 | util/thread_map.c | 14 | util/thread_map.c |
14 | util/util.c | 15 | util/util.c |
15 | util/xyarray.c | 16 | util/xyarray.c |
16 | util/cgroup.c | 17 | util/cgroup.c |
17 | util/debugfs.c | 18 | util/debugfs.c |
19 | util/rblist.c | ||
18 | util/strlist.c | 20 | util/strlist.c |
19 | ../../lib/rbtree.c | 21 | ../../lib/rbtree.c |
diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index e03b58a48424..0688bfb6d280 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c | |||
@@ -797,17 +797,13 @@ static PyObject *pyrf_evlist__read_on_cpu(struct pyrf_evlist *pevlist, | |||
797 | 797 | ||
798 | event = perf_evlist__mmap_read(evlist, cpu); | 798 | event = perf_evlist__mmap_read(evlist, cpu); |
799 | if (event != NULL) { | 799 | if (event != NULL) { |
800 | struct perf_evsel *first; | ||
801 | PyObject *pyevent = pyrf_event__new(event); | 800 | PyObject *pyevent = pyrf_event__new(event); |
802 | struct pyrf_event *pevent = (struct pyrf_event *)pyevent; | 801 | struct pyrf_event *pevent = (struct pyrf_event *)pyevent; |
803 | 802 | ||
804 | if (pyevent == NULL) | 803 | if (pyevent == NULL) |
805 | return PyErr_NoMemory(); | 804 | return PyErr_NoMemory(); |
806 | 805 | ||
807 | first = list_entry(evlist->entries.next, struct perf_evsel, node); | 806 | err = perf_evlist__parse_sample(evlist, event, &pevent->sample, false); |
808 | err = perf_event__parse_sample(event, first->attr.sample_type, | ||
809 | perf_evsel__sample_size(first), | ||
810 | sample_id_all, &pevent->sample, false); | ||
811 | if (err) | 807 | if (err) |
812 | return PyErr_Format(PyExc_OSError, | 808 | return PyErr_Format(PyExc_OSError, |
813 | "perf: can't parse sample, err=%d", err); | 809 | "perf: can't parse sample, err=%d", err); |
diff --git a/tools/perf/util/rblist.c b/tools/perf/util/rblist.c new file mode 100644 index 000000000000..0171fb611004 --- /dev/null +++ b/tools/perf/util/rblist.c | |||
@@ -0,0 +1,107 @@ | |||
1 | /* | ||
2 | * Based on strlist.c by: | ||
3 | * (c) 2009 Arnaldo Carvalho de Melo <acme@redhat.com> | ||
4 | * | ||
5 | * Licensed under the GPLv2. | ||
6 | */ | ||
7 | |||
8 | #include <errno.h> | ||
9 | #include <stdio.h> | ||
10 | #include <stdlib.h> | ||
11 | |||
12 | #include "rblist.h" | ||
13 | |||
14 | int rblist__add_node(struct rblist *rblist, const void *new_entry) | ||
15 | { | ||
16 | struct rb_node **p = &rblist->entries.rb_node; | ||
17 | struct rb_node *parent = NULL, *new_node; | ||
18 | |||
19 | while (*p != NULL) { | ||
20 | int rc; | ||
21 | |||
22 | parent = *p; | ||
23 | |||
24 | rc = rblist->node_cmp(parent, new_entry); | ||
25 | if (rc > 0) | ||
26 | p = &(*p)->rb_left; | ||
27 | else if (rc < 0) | ||
28 | p = &(*p)->rb_right; | ||
29 | else | ||
30 | return -EEXIST; | ||
31 | } | ||
32 | |||
33 | new_node = rblist->node_new(rblist, new_entry); | ||
34 | if (new_node == NULL) | ||
35 | return -ENOMEM; | ||
36 | |||
37 | rb_link_node(new_node, parent, p); | ||
38 | rb_insert_color(new_node, &rblist->entries); | ||
39 | ++rblist->nr_entries; | ||
40 | |||
41 | return 0; | ||
42 | } | ||
43 | |||
44 | void rblist__remove_node(struct rblist *rblist, struct rb_node *rb_node) | ||
45 | { | ||
46 | rb_erase(rb_node, &rblist->entries); | ||
47 | rblist->node_delete(rblist, rb_node); | ||
48 | } | ||
49 | |||
50 | struct rb_node *rblist__find(struct rblist *rblist, const void *entry) | ||
51 | { | ||
52 | struct rb_node **p = &rblist->entries.rb_node; | ||
53 | struct rb_node *parent = NULL; | ||
54 | |||
55 | while (*p != NULL) { | ||
56 | int rc; | ||
57 | |||
58 | parent = *p; | ||
59 | |||
60 | rc = rblist->node_cmp(parent, entry); | ||
61 | if (rc > 0) | ||
62 | p = &(*p)->rb_left; | ||
63 | else if (rc < 0) | ||
64 | p = &(*p)->rb_right; | ||
65 | else | ||
66 | return parent; | ||
67 | } | ||
68 | |||
69 | return NULL; | ||
70 | } | ||
71 | |||
72 | void rblist__init(struct rblist *rblist) | ||
73 | { | ||
74 | if (rblist != NULL) { | ||
75 | rblist->entries = RB_ROOT; | ||
76 | rblist->nr_entries = 0; | ||
77 | } | ||
78 | |||
79 | return; | ||
80 | } | ||
81 | |||
82 | void rblist__delete(struct rblist *rblist) | ||
83 | { | ||
84 | if (rblist != NULL) { | ||
85 | struct rb_node *pos, *next = rb_first(&rblist->entries); | ||
86 | |||
87 | while (next) { | ||
88 | pos = next; | ||
89 | next = rb_next(pos); | ||
90 | rb_erase(pos, &rblist->entries); | ||
91 | rblist->node_delete(rblist, pos); | ||
92 | } | ||
93 | free(rblist); | ||
94 | } | ||
95 | } | ||
96 | |||
97 | struct rb_node *rblist__entry(const struct rblist *rblist, unsigned int idx) | ||
98 | { | ||
99 | struct rb_node *node; | ||
100 | |||
101 | for (node = rb_first(&rblist->entries); node; node = rb_next(node)) { | ||
102 | if (!idx--) | ||
103 | return node; | ||
104 | } | ||
105 | |||
106 | return NULL; | ||
107 | } | ||
diff --git a/tools/perf/util/rblist.h b/tools/perf/util/rblist.h new file mode 100644 index 000000000000..6d0cae5ae83d --- /dev/null +++ b/tools/perf/util/rblist.h | |||
@@ -0,0 +1,47 @@ | |||
1 | #ifndef __PERF_RBLIST_H | ||
2 | #define __PERF_RBLIST_H | ||
3 | |||
4 | #include <linux/rbtree.h> | ||
5 | #include <stdbool.h> | ||
6 | |||
7 | /* | ||
8 | * create node structs of the form: | ||
9 | * struct my_node { | ||
10 | * struct rb_node rb_node; | ||
11 | * ... my data ... | ||
12 | * }; | ||
13 | * | ||
14 | * create list structs of the form: | ||
15 | * struct mylist { | ||
16 | * struct rblist rblist; | ||
17 | * ... my data ... | ||
18 | * }; | ||
19 | */ | ||
20 | |||
21 | struct rblist { | ||
22 | struct rb_root entries; | ||
23 | unsigned int nr_entries; | ||
24 | |||
25 | int (*node_cmp)(struct rb_node *rbn, const void *entry); | ||
26 | struct rb_node *(*node_new)(struct rblist *rlist, const void *new_entry); | ||
27 | void (*node_delete)(struct rblist *rblist, struct rb_node *rb_node); | ||
28 | }; | ||
29 | |||
30 | void rblist__init(struct rblist *rblist); | ||
31 | void rblist__delete(struct rblist *rblist); | ||
32 | int rblist__add_node(struct rblist *rblist, const void *new_entry); | ||
33 | void rblist__remove_node(struct rblist *rblist, struct rb_node *rb_node); | ||
34 | struct rb_node *rblist__find(struct rblist *rblist, const void *entry); | ||
35 | struct rb_node *rblist__entry(const struct rblist *rblist, unsigned int idx); | ||
36 | |||
37 | static inline bool rblist__empty(const struct rblist *rblist) | ||
38 | { | ||
39 | return rblist->nr_entries == 0; | ||
40 | } | ||
41 | |||
42 | static inline unsigned int rblist__nr_entries(const struct rblist *rblist) | ||
43 | { | ||
44 | return rblist->nr_entries; | ||
45 | } | ||
46 | |||
47 | #endif /* __PERF_RBLIST_H */ | ||
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 8e4f0755d2aa..2437fb0b463a 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c | |||
@@ -80,14 +80,12 @@ out_close: | |||
80 | return -1; | 80 | return -1; |
81 | } | 81 | } |
82 | 82 | ||
83 | void perf_session__update_sample_type(struct perf_session *self) | 83 | void perf_session__set_id_hdr_size(struct perf_session *session) |
84 | { | 84 | { |
85 | self->sample_type = perf_evlist__sample_type(self->evlist); | 85 | u16 id_hdr_size = perf_evlist__id_hdr_size(session->evlist); |
86 | self->sample_size = __perf_evsel__sample_size(self->sample_type); | 86 | |
87 | self->sample_id_all = perf_evlist__sample_id_all(self->evlist); | 87 | session->host_machine.id_hdr_size = id_hdr_size; |
88 | self->id_hdr_size = perf_evlist__id_hdr_size(self->evlist); | 88 | machines__set_id_hdr_size(&session->machines, id_hdr_size); |
89 | self->host_machine.id_hdr_size = self->id_hdr_size; | ||
90 | machines__set_id_hdr_size(&self->machines, self->id_hdr_size); | ||
91 | } | 89 | } |
92 | 90 | ||
93 | int perf_session__create_kernel_maps(struct perf_session *self) | 91 | int perf_session__create_kernel_maps(struct perf_session *self) |
@@ -147,7 +145,7 @@ struct perf_session *perf_session__new(const char *filename, int mode, | |||
147 | if (mode == O_RDONLY) { | 145 | if (mode == O_RDONLY) { |
148 | if (perf_session__open(self, force) < 0) | 146 | if (perf_session__open(self, force) < 0) |
149 | goto out_delete; | 147 | goto out_delete; |
150 | perf_session__update_sample_type(self); | 148 | perf_session__set_id_hdr_size(self); |
151 | } else if (mode == O_WRONLY) { | 149 | } else if (mode == O_WRONLY) { |
152 | /* | 150 | /* |
153 | * In O_RDONLY mode this will be performed when reading the | 151 | * In O_RDONLY mode this will be performed when reading the |
@@ -158,7 +156,7 @@ struct perf_session *perf_session__new(const char *filename, int mode, | |||
158 | } | 156 | } |
159 | 157 | ||
160 | if (tool && tool->ordering_requires_timestamps && | 158 | if (tool && tool->ordering_requires_timestamps && |
161 | tool->ordered_samples && !self->sample_id_all) { | 159 | tool->ordered_samples && !perf_evlist__sample_id_all(self->evlist)) { |
162 | dump_printf("WARNING: No sample_id_all support, falling back to unordered processing\n"); | 160 | dump_printf("WARNING: No sample_id_all support, falling back to unordered processing\n"); |
163 | tool->ordered_samples = false; | 161 | tool->ordered_samples = false; |
164 | } | 162 | } |
@@ -673,7 +671,8 @@ static void flush_sample_queue(struct perf_session *s, | |||
673 | if (iter->timestamp > limit) | 671 | if (iter->timestamp > limit) |
674 | break; | 672 | break; |
675 | 673 | ||
676 | ret = perf_session__parse_sample(s, iter->event, &sample); | 674 | ret = perf_evlist__parse_sample(s->evlist, iter->event, &sample, |
675 | s->header.needs_swap); | ||
677 | if (ret) | 676 | if (ret) |
678 | pr_err("Can't parse sample, err = %d\n", ret); | 677 | pr_err("Can't parse sample, err = %d\n", ret); |
679 | else | 678 | else |
@@ -865,16 +864,18 @@ static void perf_session__print_tstamp(struct perf_session *session, | |||
865 | union perf_event *event, | 864 | union perf_event *event, |
866 | struct perf_sample *sample) | 865 | struct perf_sample *sample) |
867 | { | 866 | { |
867 | u64 sample_type = perf_evlist__sample_type(session->evlist); | ||
868 | |||
868 | if (event->header.type != PERF_RECORD_SAMPLE && | 869 | if (event->header.type != PERF_RECORD_SAMPLE && |
869 | !session->sample_id_all) { | 870 | !perf_evlist__sample_id_all(session->evlist)) { |
870 | fputs("-1 -1 ", stdout); | 871 | fputs("-1 -1 ", stdout); |
871 | return; | 872 | return; |
872 | } | 873 | } |
873 | 874 | ||
874 | if ((session->sample_type & PERF_SAMPLE_CPU)) | 875 | if ((sample_type & PERF_SAMPLE_CPU)) |
875 | printf("%u ", sample->cpu); | 876 | printf("%u ", sample->cpu); |
876 | 877 | ||
877 | if (session->sample_type & PERF_SAMPLE_TIME) | 878 | if (sample_type & PERF_SAMPLE_TIME) |
878 | printf("%" PRIu64 " ", sample->time); | 879 | printf("%" PRIu64 " ", sample->time); |
879 | } | 880 | } |
880 | 881 | ||
@@ -899,6 +900,8 @@ static void dump_event(struct perf_session *session, union perf_event *event, | |||
899 | static void dump_sample(struct perf_session *session, union perf_event *event, | 900 | static void dump_sample(struct perf_session *session, union perf_event *event, |
900 | struct perf_sample *sample) | 901 | struct perf_sample *sample) |
901 | { | 902 | { |
903 | u64 sample_type; | ||
904 | |||
902 | if (!dump_trace) | 905 | if (!dump_trace) |
903 | return; | 906 | return; |
904 | 907 | ||
@@ -906,10 +909,12 @@ static void dump_sample(struct perf_session *session, union perf_event *event, | |||
906 | event->header.misc, sample->pid, sample->tid, sample->ip, | 909 | event->header.misc, sample->pid, sample->tid, sample->ip, |
907 | sample->period, sample->addr); | 910 | sample->period, sample->addr); |
908 | 911 | ||
909 | if (session->sample_type & PERF_SAMPLE_CALLCHAIN) | 912 | sample_type = perf_evlist__sample_type(session->evlist); |
913 | |||
914 | if (sample_type & PERF_SAMPLE_CALLCHAIN) | ||
910 | callchain__printf(sample); | 915 | callchain__printf(sample); |
911 | 916 | ||
912 | if (session->sample_type & PERF_SAMPLE_BRANCH_STACK) | 917 | if (sample_type & PERF_SAMPLE_BRANCH_STACK) |
913 | branch_stack__printf(sample); | 918 | branch_stack__printf(sample); |
914 | } | 919 | } |
915 | 920 | ||
@@ -1006,7 +1011,7 @@ static int perf_session__preprocess_sample(struct perf_session *session, | |||
1006 | union perf_event *event, struct perf_sample *sample) | 1011 | union perf_event *event, struct perf_sample *sample) |
1007 | { | 1012 | { |
1008 | if (event->header.type != PERF_RECORD_SAMPLE || | 1013 | if (event->header.type != PERF_RECORD_SAMPLE || |
1009 | !(session->sample_type & PERF_SAMPLE_CALLCHAIN)) | 1014 | !(perf_evlist__sample_type(session->evlist) & PERF_SAMPLE_CALLCHAIN)) |
1010 | return 0; | 1015 | return 0; |
1011 | 1016 | ||
1012 | if (!ip_callchain__valid(sample->callchain, event)) { | 1017 | if (!ip_callchain__valid(sample->callchain, event)) { |
@@ -1030,7 +1035,7 @@ static int perf_session__process_user_event(struct perf_session *session, union | |||
1030 | case PERF_RECORD_HEADER_ATTR: | 1035 | case PERF_RECORD_HEADER_ATTR: |
1031 | err = tool->attr(event, &session->evlist); | 1036 | err = tool->attr(event, &session->evlist); |
1032 | if (err == 0) | 1037 | if (err == 0) |
1033 | perf_session__update_sample_type(session); | 1038 | perf_session__set_id_hdr_size(session); |
1034 | return err; | 1039 | return err; |
1035 | case PERF_RECORD_HEADER_EVENT_TYPE: | 1040 | case PERF_RECORD_HEADER_EVENT_TYPE: |
1036 | return tool->event_type(tool, event); | 1041 | return tool->event_type(tool, event); |
@@ -1065,7 +1070,7 @@ static int perf_session__process_event(struct perf_session *session, | |||
1065 | int ret; | 1070 | int ret; |
1066 | 1071 | ||
1067 | if (session->header.needs_swap) | 1072 | if (session->header.needs_swap) |
1068 | event_swap(event, session->sample_id_all); | 1073 | event_swap(event, perf_evlist__sample_id_all(session->evlist)); |
1069 | 1074 | ||
1070 | if (event->header.type >= PERF_RECORD_HEADER_MAX) | 1075 | if (event->header.type >= PERF_RECORD_HEADER_MAX) |
1071 | return -EINVAL; | 1076 | return -EINVAL; |
@@ -1078,7 +1083,8 @@ static int perf_session__process_event(struct perf_session *session, | |||
1078 | /* | 1083 | /* |
1079 | * For all kernel events we get the sample data | 1084 | * For all kernel events we get the sample data |
1080 | */ | 1085 | */ |
1081 | ret = perf_session__parse_sample(session, event, &sample); | 1086 | ret = perf_evlist__parse_sample(session->evlist, event, &sample, |
1087 | session->header.needs_swap); | ||
1082 | if (ret) | 1088 | if (ret) |
1083 | return ret; | 1089 | return ret; |
1084 | 1090 | ||
@@ -1389,9 +1395,9 @@ int perf_session__process_events(struct perf_session *self, | |||
1389 | return err; | 1395 | return err; |
1390 | } | 1396 | } |
1391 | 1397 | ||
1392 | bool perf_session__has_traces(struct perf_session *self, const char *msg) | 1398 | bool perf_session__has_traces(struct perf_session *session, const char *msg) |
1393 | { | 1399 | { |
1394 | if (!(self->sample_type & PERF_SAMPLE_RAW)) { | 1400 | if (!(perf_evlist__sample_type(session->evlist) & PERF_SAMPLE_RAW)) { |
1395 | pr_err("No trace sample to read. Did you call 'perf %s'?\n", msg); | 1401 | pr_err("No trace sample to read. Did you call 'perf %s'?\n", msg); |
1396 | return false; | 1402 | return false; |
1397 | } | 1403 | } |
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h index 7c435bde6eb0..1f7ec87db7d7 100644 --- a/tools/perf/util/session.h +++ b/tools/perf/util/session.h | |||
@@ -41,13 +41,9 @@ struct perf_session { | |||
41 | * perf.data file. | 41 | * perf.data file. |
42 | */ | 42 | */ |
43 | struct hists hists; | 43 | struct hists hists; |
44 | u64 sample_type; | ||
45 | int sample_size; | ||
46 | int fd; | 44 | int fd; |
47 | bool fd_pipe; | 45 | bool fd_pipe; |
48 | bool repipe; | 46 | bool repipe; |
49 | bool sample_id_all; | ||
50 | u16 id_hdr_size; | ||
51 | int cwdlen; | 47 | int cwdlen; |
52 | char *cwd; | 48 | char *cwd; |
53 | struct ordered_samples ordered_samples; | 49 | struct ordered_samples ordered_samples; |
@@ -86,7 +82,7 @@ void perf_event__attr_swap(struct perf_event_attr *attr); | |||
86 | 82 | ||
87 | int perf_session__create_kernel_maps(struct perf_session *self); | 83 | int perf_session__create_kernel_maps(struct perf_session *self); |
88 | 84 | ||
89 | void perf_session__update_sample_type(struct perf_session *self); | 85 | void perf_session__set_id_hdr_size(struct perf_session *session); |
90 | void perf_session__remove_thread(struct perf_session *self, struct thread *th); | 86 | void perf_session__remove_thread(struct perf_session *self, struct thread *th); |
91 | 87 | ||
92 | static inline | 88 | static inline |
@@ -130,24 +126,6 @@ size_t perf_session__fprintf_dsos_buildid(struct perf_session *self, | |||
130 | 126 | ||
131 | size_t perf_session__fprintf_nr_events(struct perf_session *session, FILE *fp); | 127 | size_t perf_session__fprintf_nr_events(struct perf_session *session, FILE *fp); |
132 | 128 | ||
133 | static inline int perf_session__parse_sample(struct perf_session *session, | ||
134 | const union perf_event *event, | ||
135 | struct perf_sample *sample) | ||
136 | { | ||
137 | return perf_event__parse_sample(event, session->sample_type, | ||
138 | session->sample_size, | ||
139 | session->sample_id_all, sample, | ||
140 | session->header.needs_swap); | ||
141 | } | ||
142 | |||
143 | static inline int perf_session__synthesize_sample(struct perf_session *session, | ||
144 | union perf_event *event, | ||
145 | const struct perf_sample *sample) | ||
146 | { | ||
147 | return perf_event__synthesize_sample(event, session->sample_type, | ||
148 | sample, session->header.needs_swap); | ||
149 | } | ||
150 | |||
151 | struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session, | 129 | struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session, |
152 | unsigned int type); | 130 | unsigned int type); |
153 | 131 | ||
diff --git a/tools/perf/util/strlist.c b/tools/perf/util/strlist.c index 6783a2043555..95856ff3dda4 100644 --- a/tools/perf/util/strlist.c +++ b/tools/perf/util/strlist.c | |||
@@ -10,23 +10,28 @@ | |||
10 | #include <stdlib.h> | 10 | #include <stdlib.h> |
11 | #include <string.h> | 11 | #include <string.h> |
12 | 12 | ||
13 | static struct str_node *str_node__new(const char *s, bool dupstr) | 13 | static |
14 | struct rb_node *strlist__node_new(struct rblist *rblist, const void *entry) | ||
14 | { | 15 | { |
15 | struct str_node *self = malloc(sizeof(*self)); | 16 | const char *s = entry; |
17 | struct rb_node *rc = NULL; | ||
18 | struct strlist *strlist = container_of(rblist, struct strlist, rblist); | ||
19 | struct str_node *snode = malloc(sizeof(*snode)); | ||
16 | 20 | ||
17 | if (self != NULL) { | 21 | if (snode != NULL) { |
18 | if (dupstr) { | 22 | if (strlist->dupstr) { |
19 | s = strdup(s); | 23 | s = strdup(s); |
20 | if (s == NULL) | 24 | if (s == NULL) |
21 | goto out_delete; | 25 | goto out_delete; |
22 | } | 26 | } |
23 | self->s = s; | 27 | snode->s = s; |
28 | rc = &snode->rb_node; | ||
24 | } | 29 | } |
25 | 30 | ||
26 | return self; | 31 | return rc; |
27 | 32 | ||
28 | out_delete: | 33 | out_delete: |
29 | free(self); | 34 | free(snode); |
30 | return NULL; | 35 | return NULL; |
31 | } | 36 | } |
32 | 37 | ||
@@ -37,36 +42,26 @@ static void str_node__delete(struct str_node *self, bool dupstr) | |||
37 | free(self); | 42 | free(self); |
38 | } | 43 | } |
39 | 44 | ||
40 | int strlist__add(struct strlist *self, const char *new_entry) | 45 | static |
46 | void strlist__node_delete(struct rblist *rblist, struct rb_node *rb_node) | ||
41 | { | 47 | { |
42 | struct rb_node **p = &self->entries.rb_node; | 48 | struct strlist *slist = container_of(rblist, struct strlist, rblist); |
43 | struct rb_node *parent = NULL; | 49 | struct str_node *snode = container_of(rb_node, struct str_node, rb_node); |
44 | struct str_node *sn; | ||
45 | |||
46 | while (*p != NULL) { | ||
47 | int rc; | ||
48 | |||
49 | parent = *p; | ||
50 | sn = rb_entry(parent, struct str_node, rb_node); | ||
51 | rc = strcmp(sn->s, new_entry); | ||
52 | |||
53 | if (rc > 0) | ||
54 | p = &(*p)->rb_left; | ||
55 | else if (rc < 0) | ||
56 | p = &(*p)->rb_right; | ||
57 | else | ||
58 | return -EEXIST; | ||
59 | } | ||
60 | 50 | ||
61 | sn = str_node__new(new_entry, self->dupstr); | 51 | str_node__delete(snode, slist->dupstr); |
62 | if (sn == NULL) | 52 | } |
63 | return -ENOMEM; | ||
64 | 53 | ||
65 | rb_link_node(&sn->rb_node, parent, p); | 54 | static int strlist__node_cmp(struct rb_node *rb_node, const void *entry) |
66 | rb_insert_color(&sn->rb_node, &self->entries); | 55 | { |
67 | ++self->nr_entries; | 56 | const char *str = entry; |
57 | struct str_node *snode = container_of(rb_node, struct str_node, rb_node); | ||
58 | |||
59 | return strcmp(snode->s, str); | ||
60 | } | ||
68 | 61 | ||
69 | return 0; | 62 | int strlist__add(struct strlist *self, const char *new_entry) |
63 | { | ||
64 | return rblist__add_node(&self->rblist, new_entry); | ||
70 | } | 65 | } |
71 | 66 | ||
72 | int strlist__load(struct strlist *self, const char *filename) | 67 | int strlist__load(struct strlist *self, const char *filename) |
@@ -96,34 +91,20 @@ out: | |||
96 | return err; | 91 | return err; |
97 | } | 92 | } |
98 | 93 | ||
99 | void strlist__remove(struct strlist *self, struct str_node *sn) | 94 | void strlist__remove(struct strlist *slist, struct str_node *snode) |
100 | { | 95 | { |
101 | rb_erase(&sn->rb_node, &self->entries); | 96 | str_node__delete(snode, slist->dupstr); |
102 | str_node__delete(sn, self->dupstr); | ||
103 | } | 97 | } |
104 | 98 | ||
105 | struct str_node *strlist__find(struct strlist *self, const char *entry) | 99 | struct str_node *strlist__find(struct strlist *slist, const char *entry) |
106 | { | 100 | { |
107 | struct rb_node **p = &self->entries.rb_node; | 101 | struct str_node *snode = NULL; |
108 | struct rb_node *parent = NULL; | 102 | struct rb_node *rb_node = rblist__find(&slist->rblist, entry); |
109 | |||
110 | while (*p != NULL) { | ||
111 | struct str_node *sn; | ||
112 | int rc; | ||
113 | |||
114 | parent = *p; | ||
115 | sn = rb_entry(parent, struct str_node, rb_node); | ||
116 | rc = strcmp(sn->s, entry); | ||
117 | |||
118 | if (rc > 0) | ||
119 | p = &(*p)->rb_left; | ||
120 | else if (rc < 0) | ||
121 | p = &(*p)->rb_right; | ||
122 | else | ||
123 | return sn; | ||
124 | } | ||
125 | 103 | ||
126 | return NULL; | 104 | if (rb_node) |
105 | snode = container_of(rb_node, struct str_node, rb_node); | ||
106 | |||
107 | return snode; | ||
127 | } | 108 | } |
128 | 109 | ||
129 | static int strlist__parse_list_entry(struct strlist *self, const char *s) | 110 | static int strlist__parse_list_entry(struct strlist *self, const char *s) |
@@ -156,9 +137,12 @@ struct strlist *strlist__new(bool dupstr, const char *slist) | |||
156 | struct strlist *self = malloc(sizeof(*self)); | 137 | struct strlist *self = malloc(sizeof(*self)); |
157 | 138 | ||
158 | if (self != NULL) { | 139 | if (self != NULL) { |
159 | self->entries = RB_ROOT; | 140 | rblist__init(&self->rblist); |
141 | self->rblist.node_cmp = strlist__node_cmp; | ||
142 | self->rblist.node_new = strlist__node_new; | ||
143 | self->rblist.node_delete = strlist__node_delete; | ||
144 | |||
160 | self->dupstr = dupstr; | 145 | self->dupstr = dupstr; |
161 | self->nr_entries = 0; | ||
162 | if (slist && strlist__parse_list(self, slist) != 0) | 146 | if (slist && strlist__parse_list(self, slist) != 0) |
163 | goto out_error; | 147 | goto out_error; |
164 | } | 148 | } |
@@ -171,30 +155,18 @@ out_error: | |||
171 | 155 | ||
172 | void strlist__delete(struct strlist *self) | 156 | void strlist__delete(struct strlist *self) |
173 | { | 157 | { |
174 | if (self != NULL) { | 158 | if (self != NULL) |
175 | struct str_node *pos; | 159 | rblist__delete(&self->rblist); |
176 | struct rb_node *next = rb_first(&self->entries); | ||
177 | |||
178 | while (next) { | ||
179 | pos = rb_entry(next, struct str_node, rb_node); | ||
180 | next = rb_next(&pos->rb_node); | ||
181 | strlist__remove(self, pos); | ||
182 | } | ||
183 | self->entries = RB_ROOT; | ||
184 | free(self); | ||
185 | } | ||
186 | } | 160 | } |
187 | 161 | ||
188 | struct str_node *strlist__entry(const struct strlist *self, unsigned int idx) | 162 | struct str_node *strlist__entry(const struct strlist *slist, unsigned int idx) |
189 | { | 163 | { |
190 | struct rb_node *nd; | 164 | struct str_node *snode = NULL; |
165 | struct rb_node *rb_node; | ||
191 | 166 | ||
192 | for (nd = rb_first(&self->entries); nd; nd = rb_next(nd)) { | 167 | rb_node = rblist__entry(&slist->rblist, idx); |
193 | struct str_node *pos = rb_entry(nd, struct str_node, rb_node); | 168 | if (rb_node) |
169 | snode = container_of(rb_node, struct str_node, rb_node); | ||
194 | 170 | ||
195 | if (!idx--) | 171 | return snode; |
196 | return pos; | ||
197 | } | ||
198 | |||
199 | return NULL; | ||
200 | } | 172 | } |
diff --git a/tools/perf/util/strlist.h b/tools/perf/util/strlist.h index 3ba839007d2c..dd9f922ec67c 100644 --- a/tools/perf/util/strlist.h +++ b/tools/perf/util/strlist.h | |||
@@ -4,14 +4,15 @@ | |||
4 | #include <linux/rbtree.h> | 4 | #include <linux/rbtree.h> |
5 | #include <stdbool.h> | 5 | #include <stdbool.h> |
6 | 6 | ||
7 | #include "rblist.h" | ||
8 | |||
7 | struct str_node { | 9 | struct str_node { |
8 | struct rb_node rb_node; | 10 | struct rb_node rb_node; |
9 | const char *s; | 11 | const char *s; |
10 | }; | 12 | }; |
11 | 13 | ||
12 | struct strlist { | 14 | struct strlist { |
13 | struct rb_root entries; | 15 | struct rblist rblist; |
14 | unsigned int nr_entries; | ||
15 | bool dupstr; | 16 | bool dupstr; |
16 | }; | 17 | }; |
17 | 18 | ||
@@ -32,18 +33,18 @@ static inline bool strlist__has_entry(struct strlist *self, const char *entry) | |||
32 | 33 | ||
33 | static inline bool strlist__empty(const struct strlist *self) | 34 | static inline bool strlist__empty(const struct strlist *self) |
34 | { | 35 | { |
35 | return self->nr_entries == 0; | 36 | return rblist__empty(&self->rblist); |
36 | } | 37 | } |
37 | 38 | ||
38 | static inline unsigned int strlist__nr_entries(const struct strlist *self) | 39 | static inline unsigned int strlist__nr_entries(const struct strlist *self) |
39 | { | 40 | { |
40 | return self->nr_entries; | 41 | return rblist__nr_entries(&self->rblist); |
41 | } | 42 | } |
42 | 43 | ||
43 | /* For strlist iteration */ | 44 | /* For strlist iteration */ |
44 | static inline struct str_node *strlist__first(struct strlist *self) | 45 | static inline struct str_node *strlist__first(struct strlist *self) |
45 | { | 46 | { |
46 | struct rb_node *rn = rb_first(&self->entries); | 47 | struct rb_node *rn = rb_first(&self->rblist.entries); |
47 | return rn ? rb_entry(rn, struct str_node, rb_node) : NULL; | 48 | return rn ? rb_entry(rn, struct str_node, rb_node) : NULL; |
48 | } | 49 | } |
49 | static inline struct str_node *strlist__next(struct str_node *sn) | 50 | static inline struct str_node *strlist__next(struct str_node *sn) |
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index fdad4eeeb429..8b63b678e127 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c | |||
@@ -64,7 +64,7 @@ static enum dso_binary_type binary_type_symtab[] = { | |||
64 | DSO_BINARY_TYPE__NOT_FOUND, | 64 | DSO_BINARY_TYPE__NOT_FOUND, |
65 | }; | 65 | }; |
66 | 66 | ||
67 | #define DSO_BINARY_TYPE__SYMTAB_CNT sizeof(binary_type_symtab) | 67 | #define DSO_BINARY_TYPE__SYMTAB_CNT ARRAY_SIZE(binary_type_symtab) |
68 | 68 | ||
69 | static enum dso_binary_type binary_type_data[] = { | 69 | static enum dso_binary_type binary_type_data[] = { |
70 | DSO_BINARY_TYPE__BUILD_ID_CACHE, | 70 | DSO_BINARY_TYPE__BUILD_ID_CACHE, |
@@ -72,7 +72,7 @@ static enum dso_binary_type binary_type_data[] = { | |||
72 | DSO_BINARY_TYPE__NOT_FOUND, | 72 | DSO_BINARY_TYPE__NOT_FOUND, |
73 | }; | 73 | }; |
74 | 74 | ||
75 | #define DSO_BINARY_TYPE__DATA_CNT sizeof(binary_type_data) | 75 | #define DSO_BINARY_TYPE__DATA_CNT ARRAY_SIZE(binary_type_data) |
76 | 76 | ||
77 | int dso__name_len(const struct dso *dso) | 77 | int dso__name_len(const struct dso *dso) |
78 | { | 78 | { |
@@ -2875,6 +2875,7 @@ int machines__create_guest_kernel_maps(struct rb_root *machines) | |||
2875 | int i, items = 0; | 2875 | int i, items = 0; |
2876 | char path[PATH_MAX]; | 2876 | char path[PATH_MAX]; |
2877 | pid_t pid; | 2877 | pid_t pid; |
2878 | char *endp; | ||
2878 | 2879 | ||
2879 | if (symbol_conf.default_guest_vmlinux_name || | 2880 | if (symbol_conf.default_guest_vmlinux_name || |
2880 | symbol_conf.default_guest_modules || | 2881 | symbol_conf.default_guest_modules || |
@@ -2891,7 +2892,14 @@ int machines__create_guest_kernel_maps(struct rb_root *machines) | |||
2891 | /* Filter out . and .. */ | 2892 | /* Filter out . and .. */ |
2892 | continue; | 2893 | continue; |
2893 | } | 2894 | } |
2894 | pid = atoi(namelist[i]->d_name); | 2895 | pid = (pid_t)strtol(namelist[i]->d_name, &endp, 10); |
2896 | if ((*endp != '\0') || | ||
2897 | (endp == namelist[i]->d_name) || | ||
2898 | (errno == ERANGE)) { | ||
2899 | pr_debug("invalid directory (%s). Skipping.\n", | ||
2900 | namelist[i]->d_name); | ||
2901 | continue; | ||
2902 | } | ||
2895 | sprintf(path, "%s/%s/proc/kallsyms", | 2903 | sprintf(path, "%s/%s/proc/kallsyms", |
2896 | symbol_conf.guestmount, | 2904 | symbol_conf.guestmount, |
2897 | namelist[i]->d_name); | 2905 | namelist[i]->d_name); |
diff --git a/tools/perf/util/target.c b/tools/perf/util/target.c index 3f59c496e64c..051eaa68095e 100644 --- a/tools/perf/util/target.c +++ b/tools/perf/util/target.c | |||
@@ -110,7 +110,7 @@ int perf_target__strerror(struct perf_target *target, int errnum, | |||
110 | int idx; | 110 | int idx; |
111 | const char *msg; | 111 | const char *msg; |
112 | 112 | ||
113 | BUG_ON(buflen > 0); | 113 | BUG_ON(buflen == 0); |
114 | 114 | ||
115 | if (errnum >= 0) { | 115 | if (errnum >= 0) { |
116 | const char *err = strerror_r(errnum, buf, buflen); | 116 | const char *err = strerror_r(errnum, buf, buflen); |