aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2015-12-07 23:23:09 -0500
committerIngo Molnar <mingo@kernel.org>2015-12-07 23:23:09 -0500
commit803ca41856a26b98150a669290c50adc9bfc648e (patch)
tree53148198f44c9a68efd82fca60133d0ba4903406
parentf1ad44884a4c421ceaa9a4a8242aeeee6f686670 (diff)
parentcfef25b8daf7e4b49c84e174a904af9d89dc7c46 (diff)
Merge tag 'perf-core-for-mingo' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core
Pull perf/core improvements and fixes from Arnaldo Carvalho de Melo: User visible changes: - Fixes and improvements for supporting annotating ARM binaries, support ARM call and jump instructions, more work needed to have arch specific stuff separated into tools/perf/arch/*/annotate/ (Russell King) - Fix several 'perf test' entries broken by recent perf/core changes (Jiri Olsa) Infrastructure changes: - Consolidate perf_ev{list,sel}__{enable,disable}() calls (Jiri Olsa) - Pass correct string to dso__adjust_kmod_long_name() (Wang Nan) Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r--tools/perf/builtin-stat.c44
-rw-r--r--tools/perf/tests/code-reading.c14
-rw-r--r--tools/perf/tests/dwarf-unwind.c8
-rw-r--r--tools/perf/tests/evsel-roundtrip-name.c3
-rw-r--r--tools/perf/tests/hists_common.c5
-rw-r--r--tools/perf/tests/mmap-thread-lookup.c6
-rw-r--r--tools/perf/util/annotate.c23
-rw-r--r--tools/perf/util/evlist.c32
-rw-r--r--tools/perf/util/evsel.c15
-rw-r--r--tools/perf/util/evsel.h3
-rw-r--r--tools/perf/util/machine.c2
11 files changed, 95 insertions, 60 deletions
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index df2fbf046ee2..e74712dee242 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -168,15 +168,25 @@ static int create_perf_stat_counter(struct perf_evsel *evsel)
168 attr->sample_period = 0; 168 attr->sample_period = 0;
169 attr->sample_type = 0; 169 attr->sample_type = 0;
170 170
171 if (target__has_cpu(&target)) 171 /*
172 return perf_evsel__open_per_cpu(evsel, perf_evsel__cpus(evsel)); 172 * Disabling all counters initially, they will be enabled
173 173 * either manually by us or by kernel via enable_on_exec
174 if (!target__has_task(&target) && perf_evsel__is_group_leader(evsel)) { 174 * set later.
175 */
176 if (perf_evsel__is_group_leader(evsel)) {
175 attr->disabled = 1; 177 attr->disabled = 1;
176 if (!initial_delay) 178
179 /*
180 * In case of initial_delay we enable tracee
181 * events manually.
182 */
183 if (target__none(&target) && !initial_delay)
177 attr->enable_on_exec = 1; 184 attr->enable_on_exec = 1;
178 } 185 }
179 186
187 if (target__has_cpu(&target))
188 return perf_evsel__open_per_cpu(evsel, perf_evsel__cpus(evsel));
189
180 return perf_evsel__open_per_thread(evsel, evsel_list->threads); 190 return perf_evsel__open_per_thread(evsel, evsel_list->threads);
181} 191}
182 192
@@ -251,18 +261,18 @@ static void process_interval(void)
251 print_counters(&rs, 0, NULL); 261 print_counters(&rs, 0, NULL);
252} 262}
253 263
254static void handle_initial_delay(void) 264static void enable_counters(void)
255{ 265{
256 struct perf_evsel *counter; 266 if (initial_delay)
257
258 if (initial_delay) {
259 const int ncpus = cpu_map__nr(evsel_list->cpus),
260 nthreads = thread_map__nr(evsel_list->threads);
261
262 usleep(initial_delay * 1000); 267 usleep(initial_delay * 1000);
263 evlist__for_each(evsel_list, counter) 268
264 perf_evsel__enable(counter, ncpus, nthreads); 269 /*
265 } 270 * We need to enable counters only if:
271 * - we don't have tracee (attaching to task or cpu)
272 * - we have initial delay configured
273 */
274 if (!target__none(&target) || initial_delay)
275 perf_evlist__enable(evsel_list);
266} 276}
267 277
268static volatile int workload_exec_errno; 278static volatile int workload_exec_errno;
@@ -359,7 +369,7 @@ static int __run_perf_stat(int argc, const char **argv)
359 369
360 if (forks) { 370 if (forks) {
361 perf_evlist__start_workload(evsel_list); 371 perf_evlist__start_workload(evsel_list);
362 handle_initial_delay(); 372 enable_counters();
363 373
364 if (interval) { 374 if (interval) {
365 while (!waitpid(child_pid, &status, WNOHANG)) { 375 while (!waitpid(child_pid, &status, WNOHANG)) {
@@ -378,7 +388,7 @@ static int __run_perf_stat(int argc, const char **argv)
378 if (WIFSIGNALED(status)) 388 if (WIFSIGNALED(status))
379 psignal(WTERMSIG(status), argv[0]); 389 psignal(WTERMSIG(status), argv[0]);
380 } else { 390 } else {
381 handle_initial_delay(); 391 enable_counters();
382 while (!done) { 392 while (!done) {
383 nanosleep(&ts, NULL); 393 nanosleep(&ts, NULL);
384 if (interval) 394 if (interval)
diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c
index 4417b6a079f0..313a48c6b2bc 100644
--- a/tools/perf/tests/code-reading.c
+++ b/tools/perf/tests/code-reading.c
@@ -433,7 +433,6 @@ enum {
433 433
434static int do_test_code_reading(bool try_kcore) 434static int do_test_code_reading(bool try_kcore)
435{ 435{
436 struct machines machines;
437 struct machine *machine; 436 struct machine *machine;
438 struct thread *thread; 437 struct thread *thread;
439 struct record_opts opts = { 438 struct record_opts opts = {
@@ -459,8 +458,7 @@ static int do_test_code_reading(bool try_kcore)
459 458
460 pid = getpid(); 459 pid = getpid();
461 460
462 machines__init(&machines); 461 machine = machine__new_host();
463 machine = &machines.host;
464 462
465 ret = machine__create_kernel_maps(machine); 463 ret = machine__create_kernel_maps(machine);
466 if (ret < 0) { 464 if (ret < 0) {
@@ -549,6 +547,13 @@ static int do_test_code_reading(bool try_kcore)
549 if (ret < 0) { 547 if (ret < 0) {
550 if (!excl_kernel) { 548 if (!excl_kernel) {
551 excl_kernel = true; 549 excl_kernel = true;
550 /*
551 * Both cpus and threads are now owned by evlist
552 * and will be freed by following perf_evlist__set_maps
553 * call. Getting refference to keep them alive.
554 */
555 cpu_map__get(cpus);
556 thread_map__get(threads);
552 perf_evlist__set_maps(evlist, NULL, NULL); 557 perf_evlist__set_maps(evlist, NULL, NULL);
553 perf_evlist__delete(evlist); 558 perf_evlist__delete(evlist);
554 evlist = NULL; 559 evlist = NULL;
@@ -594,9 +599,8 @@ out_err:
594 cpu_map__put(cpus); 599 cpu_map__put(cpus);
595 thread_map__put(threads); 600 thread_map__put(threads);
596 } 601 }
597 machines__destroy_kernel_maps(&machines);
598 machine__delete_threads(machine); 602 machine__delete_threads(machine);
599 machines__exit(&machines); 603 machine__delete(machine);
600 604
601 return err; 605 return err;
602} 606}
diff --git a/tools/perf/tests/dwarf-unwind.c b/tools/perf/tests/dwarf-unwind.c
index 3cce13b19cbb..1c5c0221cea2 100644
--- a/tools/perf/tests/dwarf-unwind.c
+++ b/tools/perf/tests/dwarf-unwind.c
@@ -160,14 +160,11 @@ static int krava_1(struct thread *thread)
160 160
161int test__dwarf_unwind(int subtest __maybe_unused) 161int test__dwarf_unwind(int subtest __maybe_unused)
162{ 162{
163 struct machines machines;
164 struct machine *machine; 163 struct machine *machine;
165 struct thread *thread; 164 struct thread *thread;
166 int err = -1; 165 int err = -1;
167 166
168 machines__init(&machines); 167 machine = machine__new_host();
169
170 machine = machines__find(&machines, HOST_KERNEL_ID);
171 if (!machine) { 168 if (!machine) {
172 pr_err("Could not get machine\n"); 169 pr_err("Could not get machine\n");
173 return -1; 170 return -1;
@@ -199,7 +196,6 @@ int test__dwarf_unwind(int subtest __maybe_unused)
199 196
200 out: 197 out:
201 machine__delete_threads(machine); 198 machine__delete_threads(machine);
202 machine__exit(machine); 199 machine__delete(machine);
203 machines__exit(&machines);
204 return err; 200 return err;
205} 201}
diff --git a/tools/perf/tests/evsel-roundtrip-name.c b/tools/perf/tests/evsel-roundtrip-name.c
index 1da92e1159ee..2de4a4f2c3ed 100644
--- a/tools/perf/tests/evsel-roundtrip-name.c
+++ b/tools/perf/tests/evsel-roundtrip-name.c
@@ -103,7 +103,8 @@ int test__perf_evsel__roundtrip_name_test(int subtest __maybe_unused)
103 if (err) 103 if (err)
104 ret = err; 104 ret = err;
105 105
106 err = perf_evsel__name_array_test(perf_evsel__sw_names); 106 err = __perf_evsel__name_array_test(perf_evsel__sw_names,
107 PERF_COUNT_SW_DUMMY + 1);
107 if (err) 108 if (err)
108 ret = err; 109 ret = err;
109 110
diff --git a/tools/perf/tests/hists_common.c b/tools/perf/tests/hists_common.c
index ce80b274b097..46f453b1de60 100644
--- a/tools/perf/tests/hists_common.c
+++ b/tools/perf/tests/hists_common.c
@@ -87,6 +87,11 @@ struct machine *setup_fake_machine(struct machines *machines)
87 return NULL; 87 return NULL;
88 } 88 }
89 89
90 if (machine__create_kernel_maps(machine)) {
91 pr_debug("Not enough memory for machine setup\n");
92 goto out;
93 }
94
90 for (i = 0; i < ARRAY_SIZE(fake_threads); i++) { 95 for (i = 0; i < ARRAY_SIZE(fake_threads); i++) {
91 struct thread *thread; 96 struct thread *thread;
92 97
diff --git a/tools/perf/tests/mmap-thread-lookup.c b/tools/perf/tests/mmap-thread-lookup.c
index 6cdb97579c45..0c5ce44f723f 100644
--- a/tools/perf/tests/mmap-thread-lookup.c
+++ b/tools/perf/tests/mmap-thread-lookup.c
@@ -149,7 +149,6 @@ static int synth_process(struct machine *machine)
149 149
150static int mmap_events(synth_cb synth) 150static int mmap_events(synth_cb synth)
151{ 151{
152 struct machines machines;
153 struct machine *machine; 152 struct machine *machine;
154 int err, i; 153 int err, i;
155 154
@@ -162,8 +161,7 @@ static int mmap_events(synth_cb synth)
162 */ 161 */
163 TEST_ASSERT_VAL("failed to create threads", !threads_create()); 162 TEST_ASSERT_VAL("failed to create threads", !threads_create());
164 163
165 machines__init(&machines); 164 machine = machine__new_host();
166 machine = &machines.host;
167 165
168 dump_trace = verbose > 1 ? 1 : 0; 166 dump_trace = verbose > 1 ? 1 : 0;
169 167
@@ -203,7 +201,7 @@ static int mmap_events(synth_cb synth)
203 } 201 }
204 202
205 machine__delete_threads(machine); 203 machine__delete_threads(machine);
206 machines__exit(&machines); 204 machine__delete(machine);
207 return err; 205 return err;
208} 206}
209 207
diff --git a/tools/perf/util/annotate.c b/tools/perf/util/annotate.c
index 1dd1949b0e79..b795b6994144 100644
--- a/tools/perf/util/annotate.c
+++ b/tools/perf/util/annotate.c
@@ -65,6 +65,11 @@ static int call__parse(struct ins_operands *ops)
65 65
66 name++; 66 name++;
67 67
68#ifdef __arm__
69 if (strchr(name, '+'))
70 return -1;
71#endif
72
68 tok = strchr(name, '>'); 73 tok = strchr(name, '>');
69 if (tok == NULL) 74 if (tok == NULL)
70 return -1; 75 return -1;
@@ -246,7 +251,11 @@ static int mov__parse(struct ins_operands *ops)
246 return -1; 251 return -1;
247 252
248 target = ++s; 253 target = ++s;
254#ifdef __arm__
255 comment = strchr(s, ';');
256#else
249 comment = strchr(s, '#'); 257 comment = strchr(s, '#');
258#endif
250 259
251 if (comment != NULL) 260 if (comment != NULL)
252 s = comment - 1; 261 s = comment - 1;
@@ -354,6 +363,20 @@ static struct ins instructions[] = {
354 { .name = "addq", .ops = &mov_ops, }, 363 { .name = "addq", .ops = &mov_ops, },
355 { .name = "addw", .ops = &mov_ops, }, 364 { .name = "addw", .ops = &mov_ops, },
356 { .name = "and", .ops = &mov_ops, }, 365 { .name = "and", .ops = &mov_ops, },
366#ifdef __arm__
367 { .name = "b", .ops = &jump_ops, }, // might also be a call
368 { .name = "bcc", .ops = &jump_ops, },
369 { .name = "bcs", .ops = &jump_ops, },
370 { .name = "beq", .ops = &jump_ops, },
371 { .name = "bge", .ops = &jump_ops, },
372 { .name = "bgt", .ops = &jump_ops, },
373 { .name = "bhi", .ops = &jump_ops, },
374 { .name = "bl", .ops = &call_ops, },
375 { .name = "blt", .ops = &jump_ops, },
376 { .name = "bls", .ops = &jump_ops, },
377 { .name = "blx", .ops = &call_ops, },
378 { .name = "bne", .ops = &jump_ops, },
379#endif
357 { .name = "bts", .ops = &mov_ops, }, 380 { .name = "bts", .ops = &mov_ops, },
358 { .name = "call", .ops = &call_ops, }, 381 { .name = "call", .ops = &call_ops, },
359 { .name = "callq", .ops = &call_ops, }, 382 { .name = "callq", .ops = &call_ops, },
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index d1392194a9a9..d1b6c206bb93 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -336,20 +336,12 @@ static int perf_evlist__nr_threads(struct perf_evlist *evlist,
336 336
337void perf_evlist__disable(struct perf_evlist *evlist) 337void perf_evlist__disable(struct perf_evlist *evlist)
338{ 338{
339 int cpu, thread;
340 struct perf_evsel *pos; 339 struct perf_evsel *pos;
341 int nr_cpus = cpu_map__nr(evlist->cpus);
342 int nr_threads;
343 340
344 for (cpu = 0; cpu < nr_cpus; cpu++) { 341 evlist__for_each(evlist, pos) {
345 evlist__for_each(evlist, pos) { 342 if (!perf_evsel__is_group_leader(pos) || !pos->fd)
346 if (!perf_evsel__is_group_leader(pos) || !pos->fd) 343 continue;
347 continue; 344 perf_evsel__disable(pos);
348 nr_threads = perf_evlist__nr_threads(evlist, pos);
349 for (thread = 0; thread < nr_threads; thread++)
350 ioctl(FD(pos, cpu, thread),
351 PERF_EVENT_IOC_DISABLE, 0);
352 }
353 } 345 }
354 346
355 evlist->enabled = false; 347 evlist->enabled = false;
@@ -357,20 +349,12 @@ void perf_evlist__disable(struct perf_evlist *evlist)
357 349
358void perf_evlist__enable(struct perf_evlist *evlist) 350void perf_evlist__enable(struct perf_evlist *evlist)
359{ 351{
360 int cpu, thread;
361 struct perf_evsel *pos; 352 struct perf_evsel *pos;
362 int nr_cpus = cpu_map__nr(evlist->cpus);
363 int nr_threads;
364 353
365 for (cpu = 0; cpu < nr_cpus; cpu++) { 354 evlist__for_each(evlist, pos) {
366 evlist__for_each(evlist, pos) { 355 if (!perf_evsel__is_group_leader(pos) || !pos->fd)
367 if (!perf_evsel__is_group_leader(pos) || !pos->fd) 356 continue;
368 continue; 357 perf_evsel__enable(pos);
369 nr_threads = perf_evlist__nr_threads(evlist, pos);
370 for (thread = 0; thread < nr_threads; thread++)
371 ioctl(FD(pos, cpu, thread),
372 PERF_EVENT_IOC_ENABLE, 0);
373 }
374 } 358 }
375 359
376 evlist->enabled = true; 360 evlist->enabled = true;
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 0a1f4d9e52fc..47f033089349 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -981,13 +981,26 @@ int perf_evsel__append_filter(struct perf_evsel *evsel,
981 return -1; 981 return -1;
982} 982}
983 983
984int perf_evsel__enable(struct perf_evsel *evsel, int ncpus, int nthreads) 984int perf_evsel__enable(struct perf_evsel *evsel)
985{ 985{
986 int nthreads = thread_map__nr(evsel->threads);
987 int ncpus = cpu_map__nr(evsel->cpus);
988
986 return perf_evsel__run_ioctl(evsel, ncpus, nthreads, 989 return perf_evsel__run_ioctl(evsel, ncpus, nthreads,
987 PERF_EVENT_IOC_ENABLE, 990 PERF_EVENT_IOC_ENABLE,
988 0); 991 0);
989} 992}
990 993
994int perf_evsel__disable(struct perf_evsel *evsel)
995{
996 int nthreads = thread_map__nr(evsel->threads);
997 int ncpus = cpu_map__nr(evsel->cpus);
998
999 return perf_evsel__run_ioctl(evsel, ncpus, nthreads,
1000 PERF_EVENT_IOC_DISABLE,
1001 0);
1002}
1003
991int perf_evsel__alloc_id(struct perf_evsel *evsel, int ncpus, int nthreads) 1004int perf_evsel__alloc_id(struct perf_evsel *evsel, int ncpus, int nthreads)
992{ 1005{
993 if (ncpus == 0 || nthreads == 0) 1006 if (ncpus == 0 || nthreads == 0)
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index 0e49bd742c63..5ded1fc0341e 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -227,7 +227,8 @@ int perf_evsel__append_filter(struct perf_evsel *evsel,
227 const char *op, const char *filter); 227 const char *op, const char *filter);
228int perf_evsel__apply_filter(struct perf_evsel *evsel, int ncpus, int nthreads, 228int perf_evsel__apply_filter(struct perf_evsel *evsel, int ncpus, int nthreads,
229 const char *filter); 229 const char *filter);
230int perf_evsel__enable(struct perf_evsel *evsel, int ncpus, int nthreads); 230int perf_evsel__enable(struct perf_evsel *evsel);
231int perf_evsel__disable(struct perf_evsel *evsel);
231 232
232int perf_evsel__open_per_cpu(struct perf_evsel *evsel, 233int perf_evsel__open_per_cpu(struct perf_evsel *evsel,
233 struct cpu_map *cpus); 234 struct cpu_map *cpus);
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index 95a7f6087346..bfc289c73c22 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -576,7 +576,7 @@ static void dso__adjust_kmod_long_name(struct dso *dso, const char *filename)
576 if (!dup_filename) 576 if (!dup_filename)
577 return; 577 return;
578 578
579 dso__set_long_name(dso, filename, true); 579 dso__set_long_name(dso, dup_filename, true);
580} 580}
581 581
582struct map *machine__findnew_module_map(struct machine *machine, u64 start, 582struct map *machine__findnew_module_map(struct machine *machine, u64 start,