diff options
Diffstat (limited to 'tools/perf')
-rw-r--r-- | tools/perf/Documentation/intel-pt.txt | 15 | ||||
-rw-r--r-- | tools/perf/builtin-script.c | 4 | ||||
-rw-r--r-- | tools/perf/config/Makefile | 20 | ||||
-rw-r--r-- | tools/perf/tests/sw-clock.c | 18 | ||||
-rw-r--r-- | tools/perf/tests/task-exit.c | 18 | ||||
-rw-r--r-- | tools/perf/ui/browsers/hists.c | 12 | ||||
-rw-r--r-- | tools/perf/util/Build | 2 | ||||
-rw-r--r-- | tools/perf/util/evlist.c | 138 | ||||
-rw-r--r-- | tools/perf/util/evlist.h | 9 | ||||
-rw-r--r-- | tools/perf/util/evsel.c | 1 | ||||
-rw-r--r-- | tools/perf/util/evsel.h | 1 | ||||
-rw-r--r-- | tools/perf/util/header.c | 4 | ||||
-rw-r--r-- | tools/perf/util/intel-bts.c | 2 | ||||
-rw-r--r-- | tools/perf/util/intel-pt.c | 2 | ||||
-rw-r--r-- | tools/perf/util/parse-events.c | 7 | ||||
-rw-r--r-- | tools/perf/util/parse-events.y | 2 | ||||
-rw-r--r-- | tools/perf/util/perf_regs.c | 2 | ||||
-rw-r--r-- | tools/perf/util/perf_regs.h | 1 | ||||
-rw-r--r-- | tools/perf/util/probe-event.c | 13 | ||||
-rw-r--r-- | tools/perf/util/session.c | 5 | ||||
-rw-r--r-- | tools/perf/util/stat.c | 16 | ||||
-rw-r--r-- | tools/perf/util/symbol-elf.c | 37 | ||||
-rw-r--r-- | tools/perf/util/util.c | 2 |
23 files changed, 190 insertions, 141 deletions
diff --git a/tools/perf/Documentation/intel-pt.txt b/tools/perf/Documentation/intel-pt.txt index 4a0501d7a3b4..c94c9de3173e 100644 --- a/tools/perf/Documentation/intel-pt.txt +++ b/tools/perf/Documentation/intel-pt.txt | |||
@@ -364,21 +364,6 @@ cyc_thresh Specifies how frequently CYC packets are produced - see cyc | |||
364 | 364 | ||
365 | CYC packets are not requested by default. | 365 | CYC packets are not requested by default. |
366 | 366 | ||
367 | no_force_psb This is a driver option and is not in the IA32_RTIT_CTL MSR. | ||
368 | |||
369 | It stops the driver resetting the byte count to zero whenever | ||
370 | enabling the trace (for example on context switches) which in | ||
371 | turn results in no PSB being forced. However some processors | ||
372 | will produce a PSB anyway. | ||
373 | |||
374 | In any case, there is still a PSB when the trace is enabled for | ||
375 | the first time. | ||
376 | |||
377 | no_force_psb can be used to slightly decrease the trace size but | ||
378 | may make it harder for the decoder to recover from errors. | ||
379 | |||
380 | no_force_psb is not selected by default. | ||
381 | |||
382 | 367 | ||
383 | new snapshot option | 368 | new snapshot option |
384 | ------------------- | 369 | ------------------- |
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index eb51325e8ad9..284a76e04628 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c | |||
@@ -768,8 +768,8 @@ static int process_exit_event(struct perf_tool *tool, | |||
768 | if (!evsel->attr.sample_id_all) { | 768 | if (!evsel->attr.sample_id_all) { |
769 | sample->cpu = 0; | 769 | sample->cpu = 0; |
770 | sample->time = 0; | 770 | sample->time = 0; |
771 | sample->tid = event->comm.tid; | 771 | sample->tid = event->fork.tid; |
772 | sample->pid = event->comm.pid; | 772 | sample->pid = event->fork.pid; |
773 | } | 773 | } |
774 | print_sample_start(sample, thread, evsel); | 774 | print_sample_start(sample, thread, evsel); |
775 | perf_event__fprintf(event, stdout); | 775 | perf_event__fprintf(event, stdout); |
diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile index 827557fc7511..38a08539f4bf 100644 --- a/tools/perf/config/Makefile +++ b/tools/perf/config/Makefile | |||
@@ -573,9 +573,14 @@ ifndef NO_LIBNUMA | |||
573 | msg := $(warning No numa.h found, disables 'perf bench numa mem' benchmark, please install numactl-devel/libnuma-devel/libnuma-dev); | 573 | msg := $(warning No numa.h found, disables 'perf bench numa mem' benchmark, please install numactl-devel/libnuma-devel/libnuma-dev); |
574 | NO_LIBNUMA := 1 | 574 | NO_LIBNUMA := 1 |
575 | else | 575 | else |
576 | CFLAGS += -DHAVE_LIBNUMA_SUPPORT | 576 | ifeq ($(feature-numa_num_possible_cpus), 0) |
577 | EXTLIBS += -lnuma | 577 | msg := $(warning Old numa library found, disables 'perf bench numa mem' benchmark, please install numactl-devel/libnuma-devel/libnuma-dev >= 2.0.8); |
578 | $(call detected,CONFIG_NUMA) | 578 | NO_LIBNUMA := 1 |
579 | else | ||
580 | CFLAGS += -DHAVE_LIBNUMA_SUPPORT | ||
581 | EXTLIBS += -lnuma | ||
582 | $(call detected,CONFIG_NUMA) | ||
583 | endif | ||
579 | endif | 584 | endif |
580 | endif | 585 | endif |
581 | 586 | ||
@@ -621,8 +626,13 @@ ifdef LIBBABELTRACE | |||
621 | endif | 626 | endif |
622 | 627 | ||
623 | ifndef NO_AUXTRACE | 628 | ifndef NO_AUXTRACE |
624 | $(call detected,CONFIG_AUXTRACE) | 629 | ifeq ($(feature-get_cpuid), 0) |
625 | CFLAGS += -DHAVE_AUXTRACE_SUPPORT | 630 | msg := $(warning Your gcc lacks the __get_cpuid() builtin, disables support for auxtrace/Intel PT, please install a newer gcc); |
631 | NO_AUXTRACE := 1 | ||
632 | else | ||
633 | $(call detected,CONFIG_AUXTRACE) | ||
634 | CFLAGS += -DHAVE_AUXTRACE_SUPPORT | ||
635 | endif | ||
626 | endif | 636 | endif |
627 | 637 | ||
628 | # Among the variables below, these: | 638 | # Among the variables below, these: |
diff --git a/tools/perf/tests/sw-clock.c b/tools/perf/tests/sw-clock.c index 1aa21c90731b..5b83f56a3b6f 100644 --- a/tools/perf/tests/sw-clock.c +++ b/tools/perf/tests/sw-clock.c | |||
@@ -34,6 +34,8 @@ static int __test__sw_clock_freq(enum perf_sw_ids clock_id) | |||
34 | .disabled = 1, | 34 | .disabled = 1, |
35 | .freq = 1, | 35 | .freq = 1, |
36 | }; | 36 | }; |
37 | struct cpu_map *cpus; | ||
38 | struct thread_map *threads; | ||
37 | 39 | ||
38 | attr.sample_freq = 500; | 40 | attr.sample_freq = 500; |
39 | 41 | ||
@@ -50,14 +52,19 @@ static int __test__sw_clock_freq(enum perf_sw_ids clock_id) | |||
50 | } | 52 | } |
51 | perf_evlist__add(evlist, evsel); | 53 | perf_evlist__add(evlist, evsel); |
52 | 54 | ||
53 | evlist->cpus = cpu_map__dummy_new(); | 55 | cpus = cpu_map__dummy_new(); |
54 | evlist->threads = thread_map__new_by_tid(getpid()); | 56 | threads = thread_map__new_by_tid(getpid()); |
55 | if (!evlist->cpus || !evlist->threads) { | 57 | if (!cpus || !threads) { |
56 | err = -ENOMEM; | 58 | err = -ENOMEM; |
57 | pr_debug("Not enough memory to create thread/cpu maps\n"); | 59 | pr_debug("Not enough memory to create thread/cpu maps\n"); |
58 | goto out_delete_evlist; | 60 | goto out_free_maps; |
59 | } | 61 | } |
60 | 62 | ||
63 | perf_evlist__set_maps(evlist, cpus, threads); | ||
64 | |||
65 | cpus = NULL; | ||
66 | threads = NULL; | ||
67 | |||
61 | if (perf_evlist__open(evlist)) { | 68 | if (perf_evlist__open(evlist)) { |
62 | const char *knob = "/proc/sys/kernel/perf_event_max_sample_rate"; | 69 | const char *knob = "/proc/sys/kernel/perf_event_max_sample_rate"; |
63 | 70 | ||
@@ -107,6 +114,9 @@ next_event: | |||
107 | err = -1; | 114 | err = -1; |
108 | } | 115 | } |
109 | 116 | ||
117 | out_free_maps: | ||
118 | cpu_map__put(cpus); | ||
119 | thread_map__put(threads); | ||
110 | out_delete_evlist: | 120 | out_delete_evlist: |
111 | perf_evlist__delete(evlist); | 121 | perf_evlist__delete(evlist); |
112 | return err; | 122 | return err; |
diff --git a/tools/perf/tests/task-exit.c b/tools/perf/tests/task-exit.c index 3a8fedef83bc..add16385f13e 100644 --- a/tools/perf/tests/task-exit.c +++ b/tools/perf/tests/task-exit.c | |||
@@ -43,6 +43,8 @@ int test__task_exit(void) | |||
43 | }; | 43 | }; |
44 | const char *argv[] = { "true", NULL }; | 44 | const char *argv[] = { "true", NULL }; |
45 | char sbuf[STRERR_BUFSIZE]; | 45 | char sbuf[STRERR_BUFSIZE]; |
46 | struct cpu_map *cpus; | ||
47 | struct thread_map *threads; | ||
46 | 48 | ||
47 | signal(SIGCHLD, sig_handler); | 49 | signal(SIGCHLD, sig_handler); |
48 | 50 | ||
@@ -58,14 +60,19 @@ int test__task_exit(void) | |||
58 | * perf_evlist__prepare_workload we'll fill in the only thread | 60 | * perf_evlist__prepare_workload we'll fill in the only thread |
59 | * we're monitoring, the one forked there. | 61 | * we're monitoring, the one forked there. |
60 | */ | 62 | */ |
61 | evlist->cpus = cpu_map__dummy_new(); | 63 | cpus = cpu_map__dummy_new(); |
62 | evlist->threads = thread_map__new_by_tid(-1); | 64 | threads = thread_map__new_by_tid(-1); |
63 | if (!evlist->cpus || !evlist->threads) { | 65 | if (!cpus || !threads) { |
64 | err = -ENOMEM; | 66 | err = -ENOMEM; |
65 | pr_debug("Not enough memory to create thread/cpu maps\n"); | 67 | pr_debug("Not enough memory to create thread/cpu maps\n"); |
66 | goto out_delete_evlist; | 68 | goto out_free_maps; |
67 | } | 69 | } |
68 | 70 | ||
71 | perf_evlist__set_maps(evlist, cpus, threads); | ||
72 | |||
73 | cpus = NULL; | ||
74 | threads = NULL; | ||
75 | |||
69 | err = perf_evlist__prepare_workload(evlist, &target, argv, false, | 76 | err = perf_evlist__prepare_workload(evlist, &target, argv, false, |
70 | workload_exec_failed_signal); | 77 | workload_exec_failed_signal); |
71 | if (err < 0) { | 78 | if (err < 0) { |
@@ -114,6 +121,9 @@ retry: | |||
114 | err = -1; | 121 | err = -1; |
115 | } | 122 | } |
116 | 123 | ||
124 | out_free_maps: | ||
125 | cpu_map__put(cpus); | ||
126 | thread_map__put(threads); | ||
117 | out_delete_evlist: | 127 | out_delete_evlist: |
118 | perf_evlist__delete(evlist); | 128 | perf_evlist__delete(evlist); |
119 | return err; | 129 | return err; |
diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c index cf86f2d3a5e7..c04c60d4863c 100644 --- a/tools/perf/ui/browsers/hists.c +++ b/tools/perf/ui/browsers/hists.c | |||
@@ -1968,7 +1968,8 @@ skip_annotation: | |||
1968 | &options[nr_options], dso); | 1968 | &options[nr_options], dso); |
1969 | nr_options += add_map_opt(browser, &actions[nr_options], | 1969 | nr_options += add_map_opt(browser, &actions[nr_options], |
1970 | &options[nr_options], | 1970 | &options[nr_options], |
1971 | browser->selection->map); | 1971 | browser->selection ? |
1972 | browser->selection->map : NULL); | ||
1972 | 1973 | ||
1973 | /* perf script support */ | 1974 | /* perf script support */ |
1974 | if (browser->he_selection) { | 1975 | if (browser->he_selection) { |
@@ -1976,6 +1977,15 @@ skip_annotation: | |||
1976 | &actions[nr_options], | 1977 | &actions[nr_options], |
1977 | &options[nr_options], | 1978 | &options[nr_options], |
1978 | thread, NULL); | 1979 | thread, NULL); |
1980 | /* | ||
1981 | * Note that browser->selection != NULL | ||
1982 | * when browser->he_selection is not NULL, | ||
1983 | * so we don't need to check browser->selection | ||
1984 | * before fetching browser->selection->sym like what | ||
1985 | * we do before fetching browser->selection->map. | ||
1986 | * | ||
1987 | * See hist_browser__show_entry. | ||
1988 | */ | ||
1979 | nr_options += add_script_opt(browser, | 1989 | nr_options += add_script_opt(browser, |
1980 | &actions[nr_options], | 1990 | &actions[nr_options], |
1981 | &options[nr_options], | 1991 | &options[nr_options], |
diff --git a/tools/perf/util/Build b/tools/perf/util/Build index 349bc96ca1fe..e5f18a288b74 100644 --- a/tools/perf/util/Build +++ b/tools/perf/util/Build | |||
@@ -17,6 +17,7 @@ libperf-y += levenshtein.o | |||
17 | libperf-y += llvm-utils.o | 17 | libperf-y += llvm-utils.o |
18 | libperf-y += parse-options.o | 18 | libperf-y += parse-options.o |
19 | libperf-y += parse-events.o | 19 | libperf-y += parse-events.o |
20 | libperf-y += perf_regs.o | ||
20 | libperf-y += path.o | 21 | libperf-y += path.o |
21 | libperf-y += rbtree.o | 22 | libperf-y += rbtree.o |
22 | libperf-y += bitmap.o | 23 | libperf-y += bitmap.o |
@@ -103,7 +104,6 @@ libperf-$(CONFIG_LIBBABELTRACE) += data-convert-bt.o | |||
103 | 104 | ||
104 | libperf-y += scripting-engines/ | 105 | libperf-y += scripting-engines/ |
105 | 106 | ||
106 | libperf-$(CONFIG_PERF_REGS) += perf_regs.o | ||
107 | libperf-$(CONFIG_ZLIB) += zlib.o | 107 | libperf-$(CONFIG_ZLIB) += zlib.o |
108 | libperf-$(CONFIG_LZMA) += lzma.o | 108 | libperf-$(CONFIG_LZMA) += lzma.o |
109 | 109 | ||
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index d51a5200c8af..c8fc8a258f42 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c | |||
@@ -124,6 +124,33 @@ void perf_evlist__delete(struct perf_evlist *evlist) | |||
124 | free(evlist); | 124 | free(evlist); |
125 | } | 125 | } |
126 | 126 | ||
127 | static void __perf_evlist__propagate_maps(struct perf_evlist *evlist, | ||
128 | struct perf_evsel *evsel) | ||
129 | { | ||
130 | /* | ||
131 | * We already have cpus for evsel (via PMU sysfs) so | ||
132 | * keep it, if there's no target cpu list defined. | ||
133 | */ | ||
134 | if (!evsel->own_cpus || evlist->has_user_cpus) { | ||
135 | cpu_map__put(evsel->cpus); | ||
136 | evsel->cpus = cpu_map__get(evlist->cpus); | ||
137 | } else if (evsel->cpus != evsel->own_cpus) { | ||
138 | cpu_map__put(evsel->cpus); | ||
139 | evsel->cpus = cpu_map__get(evsel->own_cpus); | ||
140 | } | ||
141 | |||
142 | thread_map__put(evsel->threads); | ||
143 | evsel->threads = thread_map__get(evlist->threads); | ||
144 | } | ||
145 | |||
146 | static void perf_evlist__propagate_maps(struct perf_evlist *evlist) | ||
147 | { | ||
148 | struct perf_evsel *evsel; | ||
149 | |||
150 | evlist__for_each(evlist, evsel) | ||
151 | __perf_evlist__propagate_maps(evlist, evsel); | ||
152 | } | ||
153 | |||
127 | void perf_evlist__add(struct perf_evlist *evlist, struct perf_evsel *entry) | 154 | void perf_evlist__add(struct perf_evlist *evlist, struct perf_evsel *entry) |
128 | { | 155 | { |
129 | entry->evlist = evlist; | 156 | entry->evlist = evlist; |
@@ -133,18 +160,19 @@ void perf_evlist__add(struct perf_evlist *evlist, struct perf_evsel *entry) | |||
133 | 160 | ||
134 | if (!evlist->nr_entries++) | 161 | if (!evlist->nr_entries++) |
135 | perf_evlist__set_id_pos(evlist); | 162 | perf_evlist__set_id_pos(evlist); |
163 | |||
164 | __perf_evlist__propagate_maps(evlist, entry); | ||
136 | } | 165 | } |
137 | 166 | ||
138 | void perf_evlist__splice_list_tail(struct perf_evlist *evlist, | 167 | void perf_evlist__splice_list_tail(struct perf_evlist *evlist, |
139 | struct list_head *list, | 168 | struct list_head *list) |
140 | int nr_entries) | ||
141 | { | 169 | { |
142 | bool set_id_pos = !evlist->nr_entries; | 170 | struct perf_evsel *evsel, *temp; |
143 | 171 | ||
144 | list_splice_tail(list, &evlist->entries); | 172 | __evlist__for_each_safe(list, temp, evsel) { |
145 | evlist->nr_entries += nr_entries; | 173 | list_del_init(&evsel->node); |
146 | if (set_id_pos) | 174 | perf_evlist__add(evlist, evsel); |
147 | perf_evlist__set_id_pos(evlist); | 175 | } |
148 | } | 176 | } |
149 | 177 | ||
150 | void __perf_evlist__set_leader(struct list_head *list) | 178 | void __perf_evlist__set_leader(struct list_head *list) |
@@ -210,7 +238,7 @@ static int perf_evlist__add_attrs(struct perf_evlist *evlist, | |||
210 | list_add_tail(&evsel->node, &head); | 238 | list_add_tail(&evsel->node, &head); |
211 | } | 239 | } |
212 | 240 | ||
213 | perf_evlist__splice_list_tail(evlist, &head, nr_attrs); | 241 | perf_evlist__splice_list_tail(evlist, &head); |
214 | 242 | ||
215 | return 0; | 243 | return 0; |
216 | 244 | ||
@@ -1103,71 +1131,56 @@ int perf_evlist__mmap(struct perf_evlist *evlist, unsigned int pages, | |||
1103 | return perf_evlist__mmap_ex(evlist, pages, overwrite, 0, false); | 1131 | return perf_evlist__mmap_ex(evlist, pages, overwrite, 0, false); |
1104 | } | 1132 | } |
1105 | 1133 | ||
1106 | static int perf_evlist__propagate_maps(struct perf_evlist *evlist, | ||
1107 | bool has_user_cpus) | ||
1108 | { | ||
1109 | struct perf_evsel *evsel; | ||
1110 | |||
1111 | evlist__for_each(evlist, evsel) { | ||
1112 | /* | ||
1113 | * We already have cpus for evsel (via PMU sysfs) so | ||
1114 | * keep it, if there's no target cpu list defined. | ||
1115 | */ | ||
1116 | if (evsel->cpus && has_user_cpus) | ||
1117 | cpu_map__put(evsel->cpus); | ||
1118 | |||
1119 | if (!evsel->cpus || has_user_cpus) | ||
1120 | evsel->cpus = cpu_map__get(evlist->cpus); | ||
1121 | |||
1122 | evsel->threads = thread_map__get(evlist->threads); | ||
1123 | |||
1124 | if ((evlist->cpus && !evsel->cpus) || | ||
1125 | (evlist->threads && !evsel->threads)) | ||
1126 | return -ENOMEM; | ||
1127 | } | ||
1128 | |||
1129 | return 0; | ||
1130 | } | ||
1131 | |||
1132 | int perf_evlist__create_maps(struct perf_evlist *evlist, struct target *target) | 1134 | int perf_evlist__create_maps(struct perf_evlist *evlist, struct target *target) |
1133 | { | 1135 | { |
1134 | evlist->threads = thread_map__new_str(target->pid, target->tid, | 1136 | struct cpu_map *cpus; |
1135 | target->uid); | 1137 | struct thread_map *threads; |
1138 | |||
1139 | threads = thread_map__new_str(target->pid, target->tid, target->uid); | ||
1136 | 1140 | ||
1137 | if (evlist->threads == NULL) | 1141 | if (!threads) |
1138 | return -1; | 1142 | return -1; |
1139 | 1143 | ||
1140 | if (target__uses_dummy_map(target)) | 1144 | if (target__uses_dummy_map(target)) |
1141 | evlist->cpus = cpu_map__dummy_new(); | 1145 | cpus = cpu_map__dummy_new(); |
1142 | else | 1146 | else |
1143 | evlist->cpus = cpu_map__new(target->cpu_list); | 1147 | cpus = cpu_map__new(target->cpu_list); |
1144 | 1148 | ||
1145 | if (evlist->cpus == NULL) | 1149 | if (!cpus) |
1146 | goto out_delete_threads; | 1150 | goto out_delete_threads; |
1147 | 1151 | ||
1148 | return perf_evlist__propagate_maps(evlist, !!target->cpu_list); | 1152 | evlist->has_user_cpus = !!target->cpu_list; |
1153 | |||
1154 | perf_evlist__set_maps(evlist, cpus, threads); | ||
1155 | |||
1156 | return 0; | ||
1149 | 1157 | ||
1150 | out_delete_threads: | 1158 | out_delete_threads: |
1151 | thread_map__put(evlist->threads); | 1159 | thread_map__put(threads); |
1152 | evlist->threads = NULL; | ||
1153 | return -1; | 1160 | return -1; |
1154 | } | 1161 | } |
1155 | 1162 | ||
1156 | int perf_evlist__set_maps(struct perf_evlist *evlist, | 1163 | void perf_evlist__set_maps(struct perf_evlist *evlist, struct cpu_map *cpus, |
1157 | struct cpu_map *cpus, | 1164 | struct thread_map *threads) |
1158 | struct thread_map *threads) | ||
1159 | { | 1165 | { |
1160 | if (evlist->cpus) | 1166 | /* |
1167 | * Allow for the possibility that one or another of the maps isn't being | ||
1168 | * changed i.e. don't put it. Note we are assuming the maps that are | ||
1169 | * being applied are brand new and evlist is taking ownership of the | ||
1170 | * original reference count of 1. If that is not the case it is up to | ||
1171 | * the caller to increase the reference count. | ||
1172 | */ | ||
1173 | if (cpus != evlist->cpus) { | ||
1161 | cpu_map__put(evlist->cpus); | 1174 | cpu_map__put(evlist->cpus); |
1175 | evlist->cpus = cpus; | ||
1176 | } | ||
1162 | 1177 | ||
1163 | evlist->cpus = cpus; | 1178 | if (threads != evlist->threads) { |
1164 | |||
1165 | if (evlist->threads) | ||
1166 | thread_map__put(evlist->threads); | 1179 | thread_map__put(evlist->threads); |
1180 | evlist->threads = threads; | ||
1181 | } | ||
1167 | 1182 | ||
1168 | evlist->threads = threads; | 1183 | perf_evlist__propagate_maps(evlist); |
1169 | |||
1170 | return perf_evlist__propagate_maps(evlist, false); | ||
1171 | } | 1184 | } |
1172 | 1185 | ||
1173 | int perf_evlist__apply_filters(struct perf_evlist *evlist, struct perf_evsel **err_evsel) | 1186 | int perf_evlist__apply_filters(struct perf_evlist *evlist, struct perf_evsel **err_evsel) |
@@ -1387,6 +1400,8 @@ void perf_evlist__close(struct perf_evlist *evlist) | |||
1387 | 1400 | ||
1388 | static int perf_evlist__create_syswide_maps(struct perf_evlist *evlist) | 1401 | static int perf_evlist__create_syswide_maps(struct perf_evlist *evlist) |
1389 | { | 1402 | { |
1403 | struct cpu_map *cpus; | ||
1404 | struct thread_map *threads; | ||
1390 | int err = -ENOMEM; | 1405 | int err = -ENOMEM; |
1391 | 1406 | ||
1392 | /* | 1407 | /* |
@@ -1398,20 +1413,19 @@ static int perf_evlist__create_syswide_maps(struct perf_evlist *evlist) | |||
1398 | * error, and we may not want to do that fallback to a | 1413 | * error, and we may not want to do that fallback to a |
1399 | * default cpu identity map :-\ | 1414 | * default cpu identity map :-\ |
1400 | */ | 1415 | */ |
1401 | evlist->cpus = cpu_map__new(NULL); | 1416 | cpus = cpu_map__new(NULL); |
1402 | if (evlist->cpus == NULL) | 1417 | if (!cpus) |
1403 | goto out; | 1418 | goto out; |
1404 | 1419 | ||
1405 | evlist->threads = thread_map__new_dummy(); | 1420 | threads = thread_map__new_dummy(); |
1406 | if (evlist->threads == NULL) | 1421 | if (!threads) |
1407 | goto out_free_cpus; | 1422 | goto out_put; |
1408 | 1423 | ||
1409 | err = 0; | 1424 | perf_evlist__set_maps(evlist, cpus, threads); |
1410 | out: | 1425 | out: |
1411 | return err; | 1426 | return err; |
1412 | out_free_cpus: | 1427 | out_put: |
1413 | cpu_map__put(evlist->cpus); | 1428 | cpu_map__put(cpus); |
1414 | evlist->cpus = NULL; | ||
1415 | goto out; | 1429 | goto out; |
1416 | } | 1430 | } |
1417 | 1431 | ||
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index b39a6198f4ac..115d8b53c601 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h | |||
@@ -42,6 +42,7 @@ struct perf_evlist { | |||
42 | int nr_mmaps; | 42 | int nr_mmaps; |
43 | bool overwrite; | 43 | bool overwrite; |
44 | bool enabled; | 44 | bool enabled; |
45 | bool has_user_cpus; | ||
45 | size_t mmap_len; | 46 | size_t mmap_len; |
46 | int id_pos; | 47 | int id_pos; |
47 | int is_pos; | 48 | int is_pos; |
@@ -155,9 +156,8 @@ int perf_evlist__enable_event_idx(struct perf_evlist *evlist, | |||
155 | void perf_evlist__set_selected(struct perf_evlist *evlist, | 156 | void perf_evlist__set_selected(struct perf_evlist *evlist, |
156 | struct perf_evsel *evsel); | 157 | struct perf_evsel *evsel); |
157 | 158 | ||
158 | int perf_evlist__set_maps(struct perf_evlist *evlist, | 159 | void perf_evlist__set_maps(struct perf_evlist *evlist, struct cpu_map *cpus, |
159 | struct cpu_map *cpus, | 160 | struct thread_map *threads); |
160 | struct thread_map *threads); | ||
161 | int perf_evlist__create_maps(struct perf_evlist *evlist, struct target *target); | 161 | int perf_evlist__create_maps(struct perf_evlist *evlist, struct target *target); |
162 | int perf_evlist__apply_filters(struct perf_evlist *evlist, struct perf_evsel **err_evsel); | 162 | int perf_evlist__apply_filters(struct perf_evlist *evlist, struct perf_evsel **err_evsel); |
163 | 163 | ||
@@ -179,8 +179,7 @@ bool perf_evlist__valid_sample_id_all(struct perf_evlist *evlist); | |||
179 | bool perf_evlist__valid_read_format(struct perf_evlist *evlist); | 179 | bool perf_evlist__valid_read_format(struct perf_evlist *evlist); |
180 | 180 | ||
181 | void perf_evlist__splice_list_tail(struct perf_evlist *evlist, | 181 | void perf_evlist__splice_list_tail(struct perf_evlist *evlist, |
182 | struct list_head *list, | 182 | struct list_head *list); |
183 | int nr_entries); | ||
184 | 183 | ||
185 | static inline struct perf_evsel *perf_evlist__first(struct perf_evlist *evlist) | 184 | static inline struct perf_evsel *perf_evlist__first(struct perf_evlist *evlist) |
186 | { | 185 | { |
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index c53f79123b37..5410483d5219 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c | |||
@@ -1033,6 +1033,7 @@ void perf_evsel__exit(struct perf_evsel *evsel) | |||
1033 | perf_evsel__free_config_terms(evsel); | 1033 | perf_evsel__free_config_terms(evsel); |
1034 | close_cgroup(evsel->cgrp); | 1034 | close_cgroup(evsel->cgrp); |
1035 | cpu_map__put(evsel->cpus); | 1035 | cpu_map__put(evsel->cpus); |
1036 | cpu_map__put(evsel->own_cpus); | ||
1036 | thread_map__put(evsel->threads); | 1037 | thread_map__put(evsel->threads); |
1037 | zfree(&evsel->group_name); | 1038 | zfree(&evsel->group_name); |
1038 | zfree(&evsel->name); | 1039 | zfree(&evsel->name); |
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index 298e6bbca200..ef8925f7211a 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h | |||
@@ -98,6 +98,7 @@ struct perf_evsel { | |||
98 | struct cgroup_sel *cgrp; | 98 | struct cgroup_sel *cgrp; |
99 | void *handler; | 99 | void *handler; |
100 | struct cpu_map *cpus; | 100 | struct cpu_map *cpus; |
101 | struct cpu_map *own_cpus; | ||
101 | struct thread_map *threads; | 102 | struct thread_map *threads; |
102 | unsigned int sample_size; | 103 | unsigned int sample_size; |
103 | int id_pos; | 104 | int id_pos; |
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 41814547da15..fce6634aebe2 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c | |||
@@ -1438,7 +1438,7 @@ static int process_nrcpus(struct perf_file_section *section __maybe_unused, | |||
1438 | if (ph->needs_swap) | 1438 | if (ph->needs_swap) |
1439 | nr = bswap_32(nr); | 1439 | nr = bswap_32(nr); |
1440 | 1440 | ||
1441 | ph->env.nr_cpus_online = nr; | 1441 | ph->env.nr_cpus_avail = nr; |
1442 | 1442 | ||
1443 | ret = readn(fd, &nr, sizeof(nr)); | 1443 | ret = readn(fd, &nr, sizeof(nr)); |
1444 | if (ret != sizeof(nr)) | 1444 | if (ret != sizeof(nr)) |
@@ -1447,7 +1447,7 @@ static int process_nrcpus(struct perf_file_section *section __maybe_unused, | |||
1447 | if (ph->needs_swap) | 1447 | if (ph->needs_swap) |
1448 | nr = bswap_32(nr); | 1448 | nr = bswap_32(nr); |
1449 | 1449 | ||
1450 | ph->env.nr_cpus_avail = nr; | 1450 | ph->env.nr_cpus_online = nr; |
1451 | return 0; | 1451 | return 0; |
1452 | } | 1452 | } |
1453 | 1453 | ||
diff --git a/tools/perf/util/intel-bts.c b/tools/perf/util/intel-bts.c index ea768625ab5b..eb0e7f8bf515 100644 --- a/tools/perf/util/intel-bts.c +++ b/tools/perf/util/intel-bts.c | |||
@@ -623,7 +623,7 @@ static int intel_bts_process_event(struct perf_session *session, | |||
623 | if (err) | 623 | if (err) |
624 | return err; | 624 | return err; |
625 | if (event->header.type == PERF_RECORD_EXIT) { | 625 | if (event->header.type == PERF_RECORD_EXIT) { |
626 | err = intel_bts_process_tid_exit(bts, event->comm.tid); | 626 | err = intel_bts_process_tid_exit(bts, event->fork.tid); |
627 | if (err) | 627 | if (err) |
628 | return err; | 628 | return err; |
629 | } | 629 | } |
diff --git a/tools/perf/util/intel-pt.c b/tools/perf/util/intel-pt.c index bb41c20e6005..535d86f8e4d1 100644 --- a/tools/perf/util/intel-pt.c +++ b/tools/perf/util/intel-pt.c | |||
@@ -1494,7 +1494,7 @@ static int intel_pt_process_event(struct perf_session *session, | |||
1494 | if (pt->timeless_decoding) { | 1494 | if (pt->timeless_decoding) { |
1495 | if (event->header.type == PERF_RECORD_EXIT) { | 1495 | if (event->header.type == PERF_RECORD_EXIT) { |
1496 | err = intel_pt_process_timeless_queues(pt, | 1496 | err = intel_pt_process_timeless_queues(pt, |
1497 | event->comm.tid, | 1497 | event->fork.tid, |
1498 | sample->time); | 1498 | sample->time); |
1499 | } | 1499 | } |
1500 | } else if (timestamp) { | 1500 | } else if (timestamp) { |
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index d826e6f515db..21ed6ee63da9 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c | |||
@@ -287,8 +287,8 @@ __add_event(struct list_head *list, int *idx, | |||
287 | if (!evsel) | 287 | if (!evsel) |
288 | return NULL; | 288 | return NULL; |
289 | 289 | ||
290 | if (cpus) | 290 | evsel->cpus = cpu_map__get(cpus); |
291 | evsel->cpus = cpu_map__get(cpus); | 291 | evsel->own_cpus = cpu_map__get(cpus); |
292 | 292 | ||
293 | if (name) | 293 | if (name) |
294 | evsel->name = strdup(name); | 294 | evsel->name = strdup(name); |
@@ -1140,10 +1140,9 @@ int parse_events(struct perf_evlist *evlist, const char *str, | |||
1140 | ret = parse_events__scanner(str, &data, PE_START_EVENTS); | 1140 | ret = parse_events__scanner(str, &data, PE_START_EVENTS); |
1141 | perf_pmu__parse_cleanup(); | 1141 | perf_pmu__parse_cleanup(); |
1142 | if (!ret) { | 1142 | if (!ret) { |
1143 | int entries = data.idx - evlist->nr_entries; | ||
1144 | struct perf_evsel *last; | 1143 | struct perf_evsel *last; |
1145 | 1144 | ||
1146 | perf_evlist__splice_list_tail(evlist, &data.list, entries); | 1145 | perf_evlist__splice_list_tail(evlist, &data.list); |
1147 | evlist->nr_groups += data.nr_groups; | 1146 | evlist->nr_groups += data.nr_groups; |
1148 | last = perf_evlist__last(evlist); | 1147 | last = perf_evlist__last(evlist); |
1149 | last->cmdline_group_boundary = true; | 1148 | last->cmdline_group_boundary = true; |
diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y index 591905a02b92..9cd70819c795 100644 --- a/tools/perf/util/parse-events.y +++ b/tools/perf/util/parse-events.y | |||
@@ -255,7 +255,7 @@ PE_PMU_EVENT_PRE '-' PE_PMU_EVENT_SUF sep_dc | |||
255 | list_add_tail(&term->list, head); | 255 | list_add_tail(&term->list, head); |
256 | 256 | ||
257 | ALLOC_LIST(list); | 257 | ALLOC_LIST(list); |
258 | ABORT_ON(parse_events_add_pmu(list, &data->idx, "cpu", head)); | 258 | ABORT_ON(parse_events_add_pmu(data, list, "cpu", head)); |
259 | parse_events__free_terms(head); | 259 | parse_events__free_terms(head); |
260 | $$ = list; | 260 | $$ = list; |
261 | } | 261 | } |
diff --git a/tools/perf/util/perf_regs.c b/tools/perf/util/perf_regs.c index 885e8ac83997..6b8eb13e14e4 100644 --- a/tools/perf/util/perf_regs.c +++ b/tools/perf/util/perf_regs.c | |||
@@ -6,6 +6,7 @@ const struct sample_reg __weak sample_reg_masks[] = { | |||
6 | SMPL_REG_END | 6 | SMPL_REG_END |
7 | }; | 7 | }; |
8 | 8 | ||
9 | #ifdef HAVE_PERF_REGS_SUPPORT | ||
9 | int perf_reg_value(u64 *valp, struct regs_dump *regs, int id) | 10 | int perf_reg_value(u64 *valp, struct regs_dump *regs, int id) |
10 | { | 11 | { |
11 | int i, idx = 0; | 12 | int i, idx = 0; |
@@ -29,3 +30,4 @@ out: | |||
29 | *valp = regs->cache_regs[id]; | 30 | *valp = regs->cache_regs[id]; |
30 | return 0; | 31 | return 0; |
31 | } | 32 | } |
33 | #endif | ||
diff --git a/tools/perf/util/perf_regs.h b/tools/perf/util/perf_regs.h index 2984dcc54d67..679d6e493962 100644 --- a/tools/perf/util/perf_regs.h +++ b/tools/perf/util/perf_regs.h | |||
@@ -2,6 +2,7 @@ | |||
2 | #define __PERF_REGS_H | 2 | #define __PERF_REGS_H |
3 | 3 | ||
4 | #include <linux/types.h> | 4 | #include <linux/types.h> |
5 | #include <linux/compiler.h> | ||
5 | 6 | ||
6 | struct regs_dump; | 7 | struct regs_dump; |
7 | 8 | ||
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index eb5f18b75402..c6f9af78f6f5 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c | |||
@@ -270,12 +270,13 @@ static int kernel_get_module_dso(const char *module, struct dso **pdso) | |||
270 | int ret = 0; | 270 | int ret = 0; |
271 | 271 | ||
272 | if (module) { | 272 | if (module) { |
273 | list_for_each_entry(dso, &host_machine->dsos.head, node) { | 273 | char module_name[128]; |
274 | if (!dso->kernel) | 274 | |
275 | continue; | 275 | snprintf(module_name, sizeof(module_name), "[%s]", module); |
276 | if (strncmp(dso->short_name + 1, module, | 276 | map = map_groups__find_by_name(&host_machine->kmaps, MAP__FUNCTION, module_name); |
277 | dso->short_name_len - 2) == 0) | 277 | if (map) { |
278 | goto found; | 278 | dso = map->dso; |
279 | goto found; | ||
279 | } | 280 | } |
280 | pr_debug("Failed to find module %s.\n", module); | 281 | pr_debug("Failed to find module %s.\n", module); |
281 | return -ENOENT; | 282 | return -ENOENT; |
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 8a4537ee9bc3..fc3f7c922f99 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c | |||
@@ -1580,7 +1580,10 @@ static int __perf_session__process_events(struct perf_session *session, | |||
1580 | file_offset = page_offset; | 1580 | file_offset = page_offset; |
1581 | head = data_offset - page_offset; | 1581 | head = data_offset - page_offset; |
1582 | 1582 | ||
1583 | if (data_size && (data_offset + data_size < file_size)) | 1583 | if (data_size == 0) |
1584 | goto out; | ||
1585 | |||
1586 | if (data_offset + data_size < file_size) | ||
1584 | file_size = data_offset + data_size; | 1587 | file_size = data_offset + data_size; |
1585 | 1588 | ||
1586 | ui_progress__init(&prog, file_size, "Processing events..."); | 1589 | ui_progress__init(&prog, file_size, "Processing events..."); |
diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c index 415c359de465..2d065d065b67 100644 --- a/tools/perf/util/stat.c +++ b/tools/perf/util/stat.c | |||
@@ -196,7 +196,8 @@ static void zero_per_pkg(struct perf_evsel *counter) | |||
196 | memset(counter->per_pkg_mask, 0, MAX_NR_CPUS); | 196 | memset(counter->per_pkg_mask, 0, MAX_NR_CPUS); |
197 | } | 197 | } |
198 | 198 | ||
199 | static int check_per_pkg(struct perf_evsel *counter, int cpu, bool *skip) | 199 | static int check_per_pkg(struct perf_evsel *counter, |
200 | struct perf_counts_values *vals, int cpu, bool *skip) | ||
200 | { | 201 | { |
201 | unsigned long *mask = counter->per_pkg_mask; | 202 | unsigned long *mask = counter->per_pkg_mask; |
202 | struct cpu_map *cpus = perf_evsel__cpus(counter); | 203 | struct cpu_map *cpus = perf_evsel__cpus(counter); |
@@ -218,6 +219,17 @@ static int check_per_pkg(struct perf_evsel *counter, int cpu, bool *skip) | |||
218 | counter->per_pkg_mask = mask; | 219 | counter->per_pkg_mask = mask; |
219 | } | 220 | } |
220 | 221 | ||
222 | /* | ||
223 | * we do not consider an event that has not run as a good | ||
224 | * instance to mark a package as used (skip=1). Otherwise | ||
225 | * we may run into a situation where the first CPU in a package | ||
226 | * is not running anything, yet the second is, and this function | ||
227 | * would mark the package as used after the first CPU and would | ||
228 | * not read the values from the second CPU. | ||
229 | */ | ||
230 | if (!(vals->run && vals->ena)) | ||
231 | return 0; | ||
232 | |||
221 | s = cpu_map__get_socket(cpus, cpu); | 233 | s = cpu_map__get_socket(cpus, cpu); |
222 | if (s < 0) | 234 | if (s < 0) |
223 | return -1; | 235 | return -1; |
@@ -235,7 +247,7 @@ process_counter_values(struct perf_stat_config *config, struct perf_evsel *evsel | |||
235 | static struct perf_counts_values zero; | 247 | static struct perf_counts_values zero; |
236 | bool skip = false; | 248 | bool skip = false; |
237 | 249 | ||
238 | if (check_per_pkg(evsel, cpu, &skip)) { | 250 | if (check_per_pkg(evsel, count, cpu, &skip)) { |
239 | pr_err("failed to read per-pkg counter\n"); | 251 | pr_err("failed to read per-pkg counter\n"); |
240 | return -1; | 252 | return -1; |
241 | } | 253 | } |
diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c index 53bb5f59ec58..475d88d0a1c9 100644 --- a/tools/perf/util/symbol-elf.c +++ b/tools/perf/util/symbol-elf.c | |||
@@ -38,7 +38,7 @@ static inline char *bfd_demangle(void __maybe_unused *v, | |||
38 | #endif | 38 | #endif |
39 | 39 | ||
40 | #ifndef HAVE_ELF_GETPHDRNUM_SUPPORT | 40 | #ifndef HAVE_ELF_GETPHDRNUM_SUPPORT |
41 | int elf_getphdrnum(Elf *elf, size_t *dst) | 41 | static int elf_getphdrnum(Elf *elf, size_t *dst) |
42 | { | 42 | { |
43 | GElf_Ehdr gehdr; | 43 | GElf_Ehdr gehdr; |
44 | GElf_Ehdr *ehdr; | 44 | GElf_Ehdr *ehdr; |
@@ -1271,8 +1271,6 @@ out_close: | |||
1271 | static int kcore__init(struct kcore *kcore, char *filename, int elfclass, | 1271 | static int kcore__init(struct kcore *kcore, char *filename, int elfclass, |
1272 | bool temp) | 1272 | bool temp) |
1273 | { | 1273 | { |
1274 | GElf_Ehdr *ehdr; | ||
1275 | |||
1276 | kcore->elfclass = elfclass; | 1274 | kcore->elfclass = elfclass; |
1277 | 1275 | ||
1278 | if (temp) | 1276 | if (temp) |
@@ -1289,9 +1287,7 @@ static int kcore__init(struct kcore *kcore, char *filename, int elfclass, | |||
1289 | if (!gelf_newehdr(kcore->elf, elfclass)) | 1287 | if (!gelf_newehdr(kcore->elf, elfclass)) |
1290 | goto out_end; | 1288 | goto out_end; |
1291 | 1289 | ||
1292 | ehdr = gelf_getehdr(kcore->elf, &kcore->ehdr); | 1290 | memset(&kcore->ehdr, 0, sizeof(GElf_Ehdr)); |
1293 | if (!ehdr) | ||
1294 | goto out_end; | ||
1295 | 1291 | ||
1296 | return 0; | 1292 | return 0; |
1297 | 1293 | ||
@@ -1348,23 +1344,18 @@ static int kcore__copy_hdr(struct kcore *from, struct kcore *to, size_t count) | |||
1348 | static int kcore__add_phdr(struct kcore *kcore, int idx, off_t offset, | 1344 | static int kcore__add_phdr(struct kcore *kcore, int idx, off_t offset, |
1349 | u64 addr, u64 len) | 1345 | u64 addr, u64 len) |
1350 | { | 1346 | { |
1351 | GElf_Phdr gphdr; | 1347 | GElf_Phdr phdr = { |
1352 | GElf_Phdr *phdr; | 1348 | .p_type = PT_LOAD, |
1353 | 1349 | .p_flags = PF_R | PF_W | PF_X, | |
1354 | phdr = gelf_getphdr(kcore->elf, idx, &gphdr); | 1350 | .p_offset = offset, |
1355 | if (!phdr) | 1351 | .p_vaddr = addr, |
1356 | return -1; | 1352 | .p_paddr = 0, |
1357 | 1353 | .p_filesz = len, | |
1358 | phdr->p_type = PT_LOAD; | 1354 | .p_memsz = len, |
1359 | phdr->p_flags = PF_R | PF_W | PF_X; | 1355 | .p_align = page_size, |
1360 | phdr->p_offset = offset; | 1356 | }; |
1361 | phdr->p_vaddr = addr; | 1357 | |
1362 | phdr->p_paddr = 0; | 1358 | if (!gelf_update_phdr(kcore->elf, idx, &phdr)) |
1363 | phdr->p_filesz = len; | ||
1364 | phdr->p_memsz = len; | ||
1365 | phdr->p_align = page_size; | ||
1366 | |||
1367 | if (!gelf_update_phdr(kcore->elf, idx, phdr)) | ||
1368 | return -1; | 1359 | return -1; |
1369 | 1360 | ||
1370 | return 0; | 1361 | return 0; |
diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c index 7acafb3c5592..c2cd9bf2348b 100644 --- a/tools/perf/util/util.c +++ b/tools/perf/util/util.c | |||
@@ -709,7 +709,7 @@ bool find_process(const char *name) | |||
709 | 709 | ||
710 | dir = opendir(procfs__mountpoint()); | 710 | dir = opendir(procfs__mountpoint()); |
711 | if (!dir) | 711 | if (!dir) |
712 | return -1; | 712 | return false; |
713 | 713 | ||
714 | /* Walk through the directory. */ | 714 | /* Walk through the directory. */ |
715 | while (ret && (d = readdir(dir)) != NULL) { | 715 | while (ret && (d = readdir(dir)) != NULL) { |