diff options
author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2011-01-11 17:56:53 -0500 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2011-01-22 16:56:28 -0500 |
commit | 361c99a661a78ed22264649440e87fe4fe8da1f2 (patch) | |
tree | a60bc86f132608f2d41c800760b41f6f54f8e7af /tools | |
parent | 00e99a49f6f3a6b5a84ba8bf8f632c9b974bea7a (diff) |
perf evsel: Introduce perf_evlist
Killing two more perf wide global variables: nr_counters and evsel_list
as a list_head.
There are more operations that will need more fields in perf_evlist,
like the pollfd for polling all the fds in a list of evsel instances.
Use option->value to pass the evsel_list to parse_{events,filters}.
LKML-Reference: <new-submission>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Tom Zanussi <tzanussi@gmail.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools')
-rw-r--r-- | tools/perf/Makefile | 2 | ||||
-rw-r--r-- | tools/perf/builtin-record.c | 47 | ||||
-rw-r--r-- | tools/perf/builtin-stat.c | 34 | ||||
-rw-r--r-- | tools/perf/builtin-top.c | 60 | ||||
-rw-r--r-- | tools/perf/util/evlist.c | 53 | ||||
-rw-r--r-- | tools/perf/util/evlist.h | 19 | ||||
-rw-r--r-- | tools/perf/util/header.c | 17 | ||||
-rw-r--r-- | tools/perf/util/header.h | 7 | ||||
-rw-r--r-- | tools/perf/util/include/linux/list.h | 1 | ||||
-rw-r--r-- | tools/perf/util/parse-events.c | 51 | ||||
-rw-r--r-- | tools/perf/util/parse-events.h | 7 |
11 files changed, 180 insertions, 118 deletions
diff --git a/tools/perf/Makefile b/tools/perf/Makefile index 7141c42e1469..f20bc6f85611 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile | |||
@@ -402,6 +402,7 @@ LIB_H += util/debug.h | |||
402 | LIB_H += util/debugfs.h | 402 | LIB_H += util/debugfs.h |
403 | LIB_H += util/event.h | 403 | LIB_H += util/event.h |
404 | LIB_H += util/evsel.h | 404 | LIB_H += util/evsel.h |
405 | LIB_H += util/evlist.h | ||
405 | LIB_H += util/exec_cmd.h | 406 | LIB_H += util/exec_cmd.h |
406 | LIB_H += util/types.h | 407 | LIB_H += util/types.h |
407 | LIB_H += util/levenshtein.h | 408 | LIB_H += util/levenshtein.h |
@@ -440,6 +441,7 @@ LIB_OBJS += $(OUTPUT)util/ctype.o | |||
440 | LIB_OBJS += $(OUTPUT)util/debugfs.o | 441 | LIB_OBJS += $(OUTPUT)util/debugfs.o |
441 | LIB_OBJS += $(OUTPUT)util/environment.o | 442 | LIB_OBJS += $(OUTPUT)util/environment.o |
442 | LIB_OBJS += $(OUTPUT)util/event.o | 443 | LIB_OBJS += $(OUTPUT)util/event.o |
444 | LIB_OBJS += $(OUTPUT)util/evlist.o | ||
443 | LIB_OBJS += $(OUTPUT)util/evsel.o | 445 | LIB_OBJS += $(OUTPUT)util/evsel.o |
444 | LIB_OBJS += $(OUTPUT)util/exec_cmd.o | 446 | LIB_OBJS += $(OUTPUT)util/exec_cmd.o |
445 | LIB_OBJS += $(OUTPUT)util/help.o | 447 | LIB_OBJS += $(OUTPUT)util/help.o |
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index b2f729fdb317..252ace873d32 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c | |||
@@ -18,6 +18,7 @@ | |||
18 | 18 | ||
19 | #include "util/header.h" | 19 | #include "util/header.h" |
20 | #include "util/event.h" | 20 | #include "util/event.h" |
21 | #include "util/evlist.h" | ||
21 | #include "util/evsel.h" | 22 | #include "util/evsel.h" |
22 | #include "util/debug.h" | 23 | #include "util/debug.h" |
23 | #include "util/session.h" | 24 | #include "util/session.h" |
@@ -66,6 +67,7 @@ static bool sample_address = false; | |||
66 | static bool sample_time = false; | 67 | static bool sample_time = false; |
67 | static bool no_buildid = false; | 68 | static bool no_buildid = false; |
68 | static bool no_buildid_cache = false; | 69 | static bool no_buildid_cache = false; |
70 | static struct perf_evlist *evsel_list; | ||
69 | 71 | ||
70 | static long samples = 0; | 72 | static long samples = 0; |
71 | static u64 bytes_written = 0; | 73 | static u64 bytes_written = 0; |
@@ -229,7 +231,8 @@ static struct perf_header_attr *get_header_attr(struct perf_event_attr *a, int n | |||
229 | return h_attr; | 231 | return h_attr; |
230 | } | 232 | } |
231 | 233 | ||
232 | static void create_counter(struct perf_evsel *evsel, int cpu) | 234 | static void create_counter(struct perf_evlist *evlist, |
235 | struct perf_evsel *evsel, int cpu) | ||
233 | { | 236 | { |
234 | char *filter = evsel->filter; | 237 | char *filter = evsel->filter; |
235 | struct perf_event_attr *attr = &evsel->attr; | 238 | struct perf_event_attr *attr = &evsel->attr; |
@@ -263,7 +266,7 @@ static void create_counter(struct perf_evsel *evsel, int cpu) | |||
263 | 266 | ||
264 | attr->sample_type |= PERF_SAMPLE_IP | PERF_SAMPLE_TID; | 267 | attr->sample_type |= PERF_SAMPLE_IP | PERF_SAMPLE_TID; |
265 | 268 | ||
266 | if (nr_counters > 1) | 269 | if (evlist->nr_entries > 1) |
267 | attr->sample_type |= PERF_SAMPLE_ID; | 270 | attr->sample_type |= PERF_SAMPLE_ID; |
268 | 271 | ||
269 | /* | 272 | /* |
@@ -410,7 +413,7 @@ try_again: | |||
410 | 413 | ||
411 | if (evsel->idx || thread_index) { | 414 | if (evsel->idx || thread_index) { |
412 | struct perf_evsel *first; | 415 | struct perf_evsel *first; |
413 | first = list_entry(evsel_list.next, struct perf_evsel, node); | 416 | first = list_entry(evlist->entries.next, struct perf_evsel, node); |
414 | ret = ioctl(FD(evsel, nr_cpu, thread_index), | 417 | ret = ioctl(FD(evsel, nr_cpu, thread_index), |
415 | PERF_EVENT_IOC_SET_OUTPUT, | 418 | PERF_EVENT_IOC_SET_OUTPUT, |
416 | FD(first, nr_cpu, 0)); | 419 | FD(first, nr_cpu, 0)); |
@@ -449,14 +452,14 @@ try_again: | |||
449 | sample_type = attr->sample_type; | 452 | sample_type = attr->sample_type; |
450 | } | 453 | } |
451 | 454 | ||
452 | static void open_counters(int cpu) | 455 | static void open_counters(struct perf_evlist *evlist, int cpu) |
453 | { | 456 | { |
454 | struct perf_evsel *pos; | 457 | struct perf_evsel *pos; |
455 | 458 | ||
456 | group_fd = -1; | 459 | group_fd = -1; |
457 | 460 | ||
458 | list_for_each_entry(pos, &evsel_list, node) | 461 | list_for_each_entry(pos, &evlist->entries, node) |
459 | create_counter(pos, cpu); | 462 | create_counter(evlist, pos, cpu); |
460 | 463 | ||
461 | nr_cpu++; | 464 | nr_cpu++; |
462 | } | 465 | } |
@@ -481,9 +484,9 @@ static void atexit_header(void) | |||
481 | 484 | ||
482 | if (!no_buildid) | 485 | if (!no_buildid) |
483 | process_buildids(); | 486 | process_buildids(); |
484 | perf_header__write(&session->header, output, true); | 487 | perf_header__write(&session->header, evsel_list, output, true); |
485 | perf_session__delete(session); | 488 | perf_session__delete(session); |
486 | perf_evsel_list__delete(); | 489 | perf_evlist__delete(evsel_list); |
487 | symbol__exit(); | 490 | symbol__exit(); |
488 | } | 491 | } |
489 | } | 492 | } |
@@ -611,7 +614,7 @@ static int __cmd_record(int argc, const char **argv) | |||
611 | goto out_delete_session; | 614 | goto out_delete_session; |
612 | } | 615 | } |
613 | 616 | ||
614 | if (have_tracepoints(&evsel_list)) | 617 | if (have_tracepoints(&evsel_list->entries)) |
615 | perf_header__set_feat(&session->header, HEADER_TRACE_INFO); | 618 | perf_header__set_feat(&session->header, HEADER_TRACE_INFO); |
616 | 619 | ||
617 | /* | 620 | /* |
@@ -674,10 +677,10 @@ static int __cmd_record(int argc, const char **argv) | |||
674 | } | 677 | } |
675 | 678 | ||
676 | if (!system_wide && no_inherit && !cpu_list) { | 679 | if (!system_wide && no_inherit && !cpu_list) { |
677 | open_counters(-1); | 680 | open_counters(evsel_list, -1); |
678 | } else { | 681 | } else { |
679 | for (i = 0; i < cpus->nr; i++) | 682 | for (i = 0; i < cpus->nr; i++) |
680 | open_counters(cpus->map[i]); | 683 | open_counters(evsel_list, cpus->map[i]); |
681 | } | 684 | } |
682 | 685 | ||
683 | perf_session__set_sample_type(session, sample_type); | 686 | perf_session__set_sample_type(session, sample_type); |
@@ -687,7 +690,8 @@ static int __cmd_record(int argc, const char **argv) | |||
687 | if (err < 0) | 690 | if (err < 0) |
688 | return err; | 691 | return err; |
689 | } else if (file_new) { | 692 | } else if (file_new) { |
690 | err = perf_header__write(&session->header, output, false); | 693 | err = perf_header__write(&session->header, evsel_list, |
694 | output, false); | ||
691 | if (err < 0) | 695 | if (err < 0) |
692 | return err; | 696 | return err; |
693 | } | 697 | } |
@@ -712,7 +716,7 @@ static int __cmd_record(int argc, const char **argv) | |||
712 | return err; | 716 | return err; |
713 | } | 717 | } |
714 | 718 | ||
715 | if (have_tracepoints(&evsel_list)) { | 719 | if (have_tracepoints(&evsel_list->entries)) { |
716 | /* | 720 | /* |
717 | * FIXME err <= 0 here actually means that | 721 | * FIXME err <= 0 here actually means that |
718 | * there were no tracepoints so its not really | 722 | * there were no tracepoints so its not really |
@@ -721,7 +725,7 @@ static int __cmd_record(int argc, const char **argv) | |||
721 | * return this more properly and also | 725 | * return this more properly and also |
722 | * propagate errors that now are calling die() | 726 | * propagate errors that now are calling die() |
723 | */ | 727 | */ |
724 | err = event__synthesize_tracing_data(output, &evsel_list, | 728 | err = event__synthesize_tracing_data(output, evsel_list, |
725 | process_synthesized_event, | 729 | process_synthesized_event, |
726 | session); | 730 | session); |
727 | if (err <= 0) { | 731 | if (err <= 0) { |
@@ -797,7 +801,7 @@ static int __cmd_record(int argc, const char **argv) | |||
797 | for (i = 0; i < nr_cpu; i++) { | 801 | for (i = 0; i < nr_cpu; i++) { |
798 | struct perf_evsel *pos; | 802 | struct perf_evsel *pos; |
799 | 803 | ||
800 | list_for_each_entry(pos, &evsel_list, node) { | 804 | list_for_each_entry(pos, &evsel_list->entries, node) { |
801 | for (thread = 0; | 805 | for (thread = 0; |
802 | thread < threads->nr; | 806 | thread < threads->nr; |
803 | thread++) | 807 | thread++) |
@@ -838,10 +842,10 @@ static const char * const record_usage[] = { | |||
838 | static bool force, append_file; | 842 | static bool force, append_file; |
839 | 843 | ||
840 | const struct option record_options[] = { | 844 | const struct option record_options[] = { |
841 | OPT_CALLBACK('e', "event", NULL, "event", | 845 | OPT_CALLBACK('e', "event", &evsel_list, "event", |
842 | "event selector. use 'perf list' to list available events", | 846 | "event selector. use 'perf list' to list available events", |
843 | parse_events), | 847 | parse_events), |
844 | OPT_CALLBACK(0, "filter", NULL, "filter", | 848 | OPT_CALLBACK(0, "filter", &evsel_list, "filter", |
845 | "event filter", parse_filter), | 849 | "event filter", parse_filter), |
846 | OPT_INTEGER('p', "pid", &target_pid, | 850 | OPT_INTEGER('p', "pid", &target_pid, |
847 | "record events on existing process id"), | 851 | "record events on existing process id"), |
@@ -892,6 +896,10 @@ int cmd_record(int argc, const char **argv, const char *prefix __used) | |||
892 | int err = -ENOMEM; | 896 | int err = -ENOMEM; |
893 | struct perf_evsel *pos; | 897 | struct perf_evsel *pos; |
894 | 898 | ||
899 | evsel_list = perf_evlist__new(); | ||
900 | if (evsel_list == NULL) | ||
901 | return -ENOMEM; | ||
902 | |||
895 | argc = parse_options(argc, argv, record_options, record_usage, | 903 | argc = parse_options(argc, argv, record_options, record_usage, |
896 | PARSE_OPT_STOP_AT_NON_OPTION); | 904 | PARSE_OPT_STOP_AT_NON_OPTION); |
897 | if (!argc && target_pid == -1 && target_tid == -1 && | 905 | if (!argc && target_pid == -1 && target_tid == -1 && |
@@ -913,7 +921,8 @@ int cmd_record(int argc, const char **argv, const char *prefix __used) | |||
913 | if (no_buildid_cache || no_buildid) | 921 | if (no_buildid_cache || no_buildid) |
914 | disable_buildid_cache(); | 922 | disable_buildid_cache(); |
915 | 923 | ||
916 | if (list_empty(&evsel_list) && perf_evsel_list__create_default() < 0) { | 924 | if (evsel_list->nr_entries == 0 && |
925 | perf_evlist__add_default(evsel_list) < 0) { | ||
917 | pr_err("Not enough memory for event selector list\n"); | 926 | pr_err("Not enough memory for event selector list\n"); |
918 | goto out_symbol_exit; | 927 | goto out_symbol_exit; |
919 | } | 928 | } |
@@ -933,7 +942,7 @@ int cmd_record(int argc, const char **argv, const char *prefix __used) | |||
933 | return -1; | 942 | return -1; |
934 | } | 943 | } |
935 | 944 | ||
936 | list_for_each_entry(pos, &evsel_list, node) { | 945 | list_for_each_entry(pos, &evsel_list->entries, node) { |
937 | if (perf_evsel__alloc_fd(pos, cpus->nr, threads->nr) < 0) | 946 | if (perf_evsel__alloc_fd(pos, cpus->nr, threads->nr) < 0) |
938 | goto out_free_fd; | 947 | goto out_free_fd; |
939 | if (perf_header__push_event(pos->attr.config, event_name(pos))) | 948 | if (perf_header__push_event(pos->attr.config, event_name(pos))) |
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index a482a191a0ca..da9090245934 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c | |||
@@ -43,6 +43,7 @@ | |||
43 | #include "util/parse-options.h" | 43 | #include "util/parse-options.h" |
44 | #include "util/parse-events.h" | 44 | #include "util/parse-events.h" |
45 | #include "util/event.h" | 45 | #include "util/event.h" |
46 | #include "util/evlist.h" | ||
46 | #include "util/evsel.h" | 47 | #include "util/evsel.h" |
47 | #include "util/debug.h" | 48 | #include "util/debug.h" |
48 | #include "util/header.h" | 49 | #include "util/header.h" |
@@ -71,6 +72,8 @@ static struct perf_event_attr default_attrs[] = { | |||
71 | 72 | ||
72 | }; | 73 | }; |
73 | 74 | ||
75 | struct perf_evlist *evsel_list; | ||
76 | |||
74 | static bool system_wide = false; | 77 | static bool system_wide = false; |
75 | static struct cpu_map *cpus; | 78 | static struct cpu_map *cpus; |
76 | static int run_idx = 0; | 79 | static int run_idx = 0; |
@@ -309,7 +312,7 @@ static int run_perf_stat(int argc __used, const char **argv) | |||
309 | close(child_ready_pipe[0]); | 312 | close(child_ready_pipe[0]); |
310 | } | 313 | } |
311 | 314 | ||
312 | list_for_each_entry(counter, &evsel_list, node) { | 315 | list_for_each_entry(counter, &evsel_list->entries, node) { |
313 | if (create_perf_stat_counter(counter) < 0) { | 316 | if (create_perf_stat_counter(counter) < 0) { |
314 | if (errno == -EPERM || errno == -EACCES) { | 317 | if (errno == -EPERM || errno == -EACCES) { |
315 | error("You may not have permission to collect %sstats.\n" | 318 | error("You may not have permission to collect %sstats.\n" |
@@ -347,12 +350,12 @@ static int run_perf_stat(int argc __used, const char **argv) | |||
347 | update_stats(&walltime_nsecs_stats, t1 - t0); | 350 | update_stats(&walltime_nsecs_stats, t1 - t0); |
348 | 351 | ||
349 | if (no_aggr) { | 352 | if (no_aggr) { |
350 | list_for_each_entry(counter, &evsel_list, node) { | 353 | list_for_each_entry(counter, &evsel_list->entries, node) { |
351 | read_counter(counter); | 354 | read_counter(counter); |
352 | perf_evsel__close_fd(counter, cpus->nr, 1); | 355 | perf_evsel__close_fd(counter, cpus->nr, 1); |
353 | } | 356 | } |
354 | } else { | 357 | } else { |
355 | list_for_each_entry(counter, &evsel_list, node) { | 358 | list_for_each_entry(counter, &evsel_list->entries, node) { |
356 | read_counter_aggr(counter); | 359 | read_counter_aggr(counter); |
357 | perf_evsel__close_fd(counter, cpus->nr, threads->nr); | 360 | perf_evsel__close_fd(counter, cpus->nr, threads->nr); |
358 | } | 361 | } |
@@ -555,10 +558,10 @@ static void print_stat(int argc, const char **argv) | |||
555 | } | 558 | } |
556 | 559 | ||
557 | if (no_aggr) { | 560 | if (no_aggr) { |
558 | list_for_each_entry(counter, &evsel_list, node) | 561 | list_for_each_entry(counter, &evsel_list->entries, node) |
559 | print_counter(counter); | 562 | print_counter(counter); |
560 | } else { | 563 | } else { |
561 | list_for_each_entry(counter, &evsel_list, node) | 564 | list_for_each_entry(counter, &evsel_list->entries, node) |
562 | print_counter_aggr(counter); | 565 | print_counter_aggr(counter); |
563 | } | 566 | } |
564 | 567 | ||
@@ -610,7 +613,7 @@ static int stat__set_big_num(const struct option *opt __used, | |||
610 | } | 613 | } |
611 | 614 | ||
612 | static const struct option options[] = { | 615 | static const struct option options[] = { |
613 | OPT_CALLBACK('e', "event", NULL, "event", | 616 | OPT_CALLBACK('e', "event", &evsel_list, "event", |
614 | "event selector. use 'perf list' to list available events", | 617 | "event selector. use 'perf list' to list available events", |
615 | parse_events), | 618 | parse_events), |
616 | OPT_BOOLEAN('i', "no-inherit", &no_inherit, | 619 | OPT_BOOLEAN('i', "no-inherit", &no_inherit, |
@@ -648,6 +651,10 @@ int cmd_stat(int argc, const char **argv, const char *prefix __used) | |||
648 | 651 | ||
649 | setlocale(LC_ALL, ""); | 652 | setlocale(LC_ALL, ""); |
650 | 653 | ||
654 | evsel_list = perf_evlist__new(); | ||
655 | if (evsel_list == NULL) | ||
656 | return -ENOMEM; | ||
657 | |||
651 | argc = parse_options(argc, argv, options, stat_usage, | 658 | argc = parse_options(argc, argv, options, stat_usage, |
652 | PARSE_OPT_STOP_AT_NON_OPTION); | 659 | PARSE_OPT_STOP_AT_NON_OPTION); |
653 | 660 | ||
@@ -679,17 +686,14 @@ int cmd_stat(int argc, const char **argv, const char *prefix __used) | |||
679 | usage_with_options(stat_usage, options); | 686 | usage_with_options(stat_usage, options); |
680 | 687 | ||
681 | /* Set attrs and nr_counters if no event is selected and !null_run */ | 688 | /* Set attrs and nr_counters if no event is selected and !null_run */ |
682 | if (!null_run && !nr_counters) { | 689 | if (!null_run && !evsel_list->nr_entries) { |
683 | size_t c; | 690 | size_t c; |
684 | 691 | ||
685 | nr_counters = ARRAY_SIZE(default_attrs); | ||
686 | |||
687 | for (c = 0; c < ARRAY_SIZE(default_attrs); ++c) { | 692 | for (c = 0; c < ARRAY_SIZE(default_attrs); ++c) { |
688 | pos = perf_evsel__new(&default_attrs[c], | 693 | pos = perf_evsel__new(&default_attrs[c], c); |
689 | nr_counters); | ||
690 | if (pos == NULL) | 694 | if (pos == NULL) |
691 | goto out; | 695 | goto out; |
692 | list_add(&pos->node, &evsel_list); | 696 | perf_evlist__add(evsel_list, pos); |
693 | } | 697 | } |
694 | } | 698 | } |
695 | 699 | ||
@@ -713,7 +717,7 @@ int cmd_stat(int argc, const char **argv, const char *prefix __used) | |||
713 | return -1; | 717 | return -1; |
714 | } | 718 | } |
715 | 719 | ||
716 | list_for_each_entry(pos, &evsel_list, node) { | 720 | list_for_each_entry(pos, &evsel_list->entries, node) { |
717 | if (perf_evsel__alloc_stat_priv(pos) < 0 || | 721 | if (perf_evsel__alloc_stat_priv(pos) < 0 || |
718 | perf_evsel__alloc_counts(pos, cpus->nr) < 0 || | 722 | perf_evsel__alloc_counts(pos, cpus->nr) < 0 || |
719 | perf_evsel__alloc_fd(pos, cpus->nr, threads->nr) < 0) | 723 | perf_evsel__alloc_fd(pos, cpus->nr, threads->nr) < 0) |
@@ -741,9 +745,9 @@ int cmd_stat(int argc, const char **argv, const char *prefix __used) | |||
741 | if (status != -1) | 745 | if (status != -1) |
742 | print_stat(argc, argv); | 746 | print_stat(argc, argv); |
743 | out_free_fd: | 747 | out_free_fd: |
744 | list_for_each_entry(pos, &evsel_list, node) | 748 | list_for_each_entry(pos, &evsel_list->entries, node) |
745 | perf_evsel__free_stat_priv(pos); | 749 | perf_evsel__free_stat_priv(pos); |
746 | perf_evsel_list__delete(); | 750 | perf_evlist__delete(evsel_list); |
747 | out: | 751 | out: |
748 | thread_map__delete(threads); | 752 | thread_map__delete(threads); |
749 | threads = NULL; | 753 | threads = NULL; |
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index b6998e055767..216b62ed4b89 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include "perf.h" | 21 | #include "perf.h" |
22 | 22 | ||
23 | #include "util/color.h" | 23 | #include "util/color.h" |
24 | #include "util/evlist.h" | ||
24 | #include "util/evsel.h" | 25 | #include "util/evsel.h" |
25 | #include "util/session.h" | 26 | #include "util/session.h" |
26 | #include "util/symbol.h" | 27 | #include "util/symbol.h" |
@@ -60,6 +61,8 @@ | |||
60 | 61 | ||
61 | #define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y)) | 62 | #define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y)) |
62 | 63 | ||
64 | struct perf_evlist *evsel_list; | ||
65 | |||
63 | static bool system_wide = false; | 66 | static bool system_wide = false; |
64 | 67 | ||
65 | static int default_interval = 0; | 68 | static int default_interval = 0; |
@@ -267,7 +270,7 @@ static void __zero_source_counters(struct sym_entry *syme) | |||
267 | 270 | ||
268 | line = syme->src->lines; | 271 | line = syme->src->lines; |
269 | while (line) { | 272 | while (line) { |
270 | for (i = 0; i < nr_counters; i++) | 273 | for (i = 0; i < evsel_list->nr_entries; i++) |
271 | line->count[i] = 0; | 274 | line->count[i] = 0; |
272 | line = line->next; | 275 | line = line->next; |
273 | } | 276 | } |
@@ -414,7 +417,7 @@ static double sym_weight(const struct sym_entry *sym) | |||
414 | if (!display_weighted) | 417 | if (!display_weighted) |
415 | return weight; | 418 | return weight; |
416 | 419 | ||
417 | for (counter = 1; counter < nr_counters-1; counter++) | 420 | for (counter = 1; counter < evsel_list->nr_entries - 1; counter++) |
418 | weight *= sym->count[counter]; | 421 | weight *= sym->count[counter]; |
419 | 422 | ||
420 | weight /= (sym->count[counter] + 1); | 423 | weight /= (sym->count[counter] + 1); |
@@ -501,7 +504,7 @@ static void print_sym_table(void) | |||
501 | rb_insert_active_sym(&tmp, syme); | 504 | rb_insert_active_sym(&tmp, syme); |
502 | sum_ksamples += syme->snap_count; | 505 | sum_ksamples += syme->snap_count; |
503 | 506 | ||
504 | for (j = 0; j < nr_counters; j++) | 507 | for (j = 0; j < evsel_list->nr_entries; j++) |
505 | syme->count[j] = zero ? 0 : syme->count[j] * 7 / 8; | 508 | syme->count[j] = zero ? 0 : syme->count[j] * 7 / 8; |
506 | } else | 509 | } else |
507 | list_remove_active_sym(syme); | 510 | list_remove_active_sym(syme); |
@@ -535,9 +538,9 @@ static void print_sym_table(void) | |||
535 | esamples_percent); | 538 | esamples_percent); |
536 | } | 539 | } |
537 | 540 | ||
538 | if (nr_counters == 1 || !display_weighted) { | 541 | if (evsel_list->nr_entries == 1 || !display_weighted) { |
539 | struct perf_evsel *first; | 542 | struct perf_evsel *first; |
540 | first = list_entry(evsel_list.next, struct perf_evsel, node); | 543 | first = list_entry(evsel_list->entries.next, struct perf_evsel, node); |
541 | printf("%" PRIu64, (uint64_t)first->attr.sample_period); | 544 | printf("%" PRIu64, (uint64_t)first->attr.sample_period); |
542 | if (freq) | 545 | if (freq) |
543 | printf("Hz "); | 546 | printf("Hz "); |
@@ -547,7 +550,7 @@ static void print_sym_table(void) | |||
547 | 550 | ||
548 | if (!display_weighted) | 551 | if (!display_weighted) |
549 | printf("%s", event_name(sym_evsel)); | 552 | printf("%s", event_name(sym_evsel)); |
550 | else list_for_each_entry(counter, &evsel_list, node) { | 553 | else list_for_each_entry(counter, &evsel_list->entries, node) { |
551 | if (counter->idx) | 554 | if (counter->idx) |
552 | printf("/"); | 555 | printf("/"); |
553 | 556 | ||
@@ -606,7 +609,7 @@ static void print_sym_table(void) | |||
606 | sym_width = winsize.ws_col - dso_width - 29; | 609 | sym_width = winsize.ws_col - dso_width - 29; |
607 | } | 610 | } |
608 | putchar('\n'); | 611 | putchar('\n'); |
609 | if (nr_counters == 1) | 612 | if (evsel_list->nr_entries == 1) |
610 | printf(" samples pcnt"); | 613 | printf(" samples pcnt"); |
611 | else | 614 | else |
612 | printf(" weight samples pcnt"); | 615 | printf(" weight samples pcnt"); |
@@ -615,7 +618,7 @@ static void print_sym_table(void) | |||
615 | printf(" RIP "); | 618 | printf(" RIP "); |
616 | printf(" %-*.*s DSO\n", sym_width, sym_width, "function"); | 619 | printf(" %-*.*s DSO\n", sym_width, sym_width, "function"); |
617 | printf(" %s _______ _____", | 620 | printf(" %s _______ _____", |
618 | nr_counters == 1 ? " " : "______"); | 621 | evsel_list->nr_entries == 1 ? " " : "______"); |
619 | if (verbose) | 622 | if (verbose) |
620 | printf(" ________________"); | 623 | printf(" ________________"); |
621 | printf(" %-*.*s", sym_width, sym_width, graph_line); | 624 | printf(" %-*.*s", sym_width, sym_width, graph_line); |
@@ -634,7 +637,7 @@ static void print_sym_table(void) | |||
634 | pcnt = 100.0 - (100.0 * ((sum_ksamples - syme->snap_count) / | 637 | pcnt = 100.0 - (100.0 * ((sum_ksamples - syme->snap_count) / |
635 | sum_ksamples)); | 638 | sum_ksamples)); |
636 | 639 | ||
637 | if (nr_counters == 1 || !display_weighted) | 640 | if (evsel_list->nr_entries == 1 || !display_weighted) |
638 | printf("%20.2f ", syme->weight); | 641 | printf("%20.2f ", syme->weight); |
639 | else | 642 | else |
640 | printf("%9.1f %10ld ", syme->weight, syme->snap_count); | 643 | printf("%9.1f %10ld ", syme->weight, syme->snap_count); |
@@ -744,7 +747,7 @@ static void print_mapped_keys(void) | |||
744 | fprintf(stdout, "\t[d] display refresh delay. \t(%d)\n", delay_secs); | 747 | fprintf(stdout, "\t[d] display refresh delay. \t(%d)\n", delay_secs); |
745 | fprintf(stdout, "\t[e] display entries (lines). \t(%d)\n", print_entries); | 748 | fprintf(stdout, "\t[e] display entries (lines). \t(%d)\n", print_entries); |
746 | 749 | ||
747 | if (nr_counters > 1) | 750 | if (evsel_list->nr_entries > 1) |
748 | fprintf(stdout, "\t[E] active event counter. \t(%s)\n", event_name(sym_evsel)); | 751 | fprintf(stdout, "\t[E] active event counter. \t(%s)\n", event_name(sym_evsel)); |
749 | 752 | ||
750 | fprintf(stdout, "\t[f] profile display filter (count). \t(%d)\n", count_filter); | 753 | fprintf(stdout, "\t[f] profile display filter (count). \t(%d)\n", count_filter); |
@@ -753,7 +756,7 @@ static void print_mapped_keys(void) | |||
753 | fprintf(stdout, "\t[s] annotate symbol. \t(%s)\n", name?: "NULL"); | 756 | fprintf(stdout, "\t[s] annotate symbol. \t(%s)\n", name?: "NULL"); |
754 | fprintf(stdout, "\t[S] stop annotation.\n"); | 757 | fprintf(stdout, "\t[S] stop annotation.\n"); |
755 | 758 | ||
756 | if (nr_counters > 1) | 759 | if (evsel_list->nr_entries > 1) |
757 | fprintf(stdout, "\t[w] toggle display weighted/count[E]r. \t(%d)\n", display_weighted ? 1 : 0); | 760 | fprintf(stdout, "\t[w] toggle display weighted/count[E]r. \t(%d)\n", display_weighted ? 1 : 0); |
758 | 761 | ||
759 | fprintf(stdout, | 762 | fprintf(stdout, |
@@ -783,7 +786,7 @@ static int key_mapped(int c) | |||
783 | return 1; | 786 | return 1; |
784 | case 'E': | 787 | case 'E': |
785 | case 'w': | 788 | case 'w': |
786 | return nr_counters > 1 ? 1 : 0; | 789 | return evsel_list->nr_entries > 1 ? 1 : 0; |
787 | default: | 790 | default: |
788 | break; | 791 | break; |
789 | } | 792 | } |
@@ -831,22 +834,22 @@ static void handle_keypress(struct perf_session *session, int c) | |||
831 | signal(SIGWINCH, SIG_DFL); | 834 | signal(SIGWINCH, SIG_DFL); |
832 | break; | 835 | break; |
833 | case 'E': | 836 | case 'E': |
834 | if (nr_counters > 1) { | 837 | if (evsel_list->nr_entries > 1) { |
835 | fprintf(stderr, "\nAvailable events:"); | 838 | fprintf(stderr, "\nAvailable events:"); |
836 | 839 | ||
837 | list_for_each_entry(sym_evsel, &evsel_list, node) | 840 | list_for_each_entry(sym_evsel, &evsel_list->entries, node) |
838 | fprintf(stderr, "\n\t%d %s", sym_evsel->idx, event_name(sym_evsel)); | 841 | fprintf(stderr, "\n\t%d %s", sym_evsel->idx, event_name(sym_evsel)); |
839 | 842 | ||
840 | prompt_integer(&sym_counter, "Enter details event counter"); | 843 | prompt_integer(&sym_counter, "Enter details event counter"); |
841 | 844 | ||
842 | if (sym_counter >= nr_counters) { | 845 | if (sym_counter >= evsel_list->nr_entries) { |
843 | sym_evsel = list_entry(evsel_list.next, struct perf_evsel, node); | 846 | sym_evsel = list_entry(evsel_list->entries.next, struct perf_evsel, node); |
844 | sym_counter = 0; | 847 | sym_counter = 0; |
845 | fprintf(stderr, "Sorry, no such event, using %s.\n", event_name(sym_evsel)); | 848 | fprintf(stderr, "Sorry, no such event, using %s.\n", event_name(sym_evsel)); |
846 | sleep(1); | 849 | sleep(1); |
847 | break; | 850 | break; |
848 | } | 851 | } |
849 | list_for_each_entry(sym_evsel, &evsel_list, node) | 852 | list_for_each_entry(sym_evsel, &evsel_list->entries, node) |
850 | if (sym_evsel->idx == sym_counter) | 853 | if (sym_evsel->idx == sym_counter) |
851 | break; | 854 | break; |
852 | } else sym_counter = 0; | 855 | } else sym_counter = 0; |
@@ -1198,7 +1201,7 @@ static void perf_session__mmap_read(struct perf_session *self) | |||
1198 | int i, thread_index; | 1201 | int i, thread_index; |
1199 | 1202 | ||
1200 | for (i = 0; i < cpus->nr; i++) { | 1203 | for (i = 0; i < cpus->nr; i++) { |
1201 | list_for_each_entry(counter, &evsel_list, node) { | 1204 | list_for_each_entry(counter, &evsel_list->entries, node) { |
1202 | for (thread_index = 0; | 1205 | for (thread_index = 0; |
1203 | thread_index < threads->nr; | 1206 | thread_index < threads->nr; |
1204 | thread_index++) { | 1207 | thread_index++) { |
@@ -1312,7 +1315,7 @@ static int __cmd_top(void) | |||
1312 | 1315 | ||
1313 | for (i = 0; i < cpus->nr; i++) { | 1316 | for (i = 0; i < cpus->nr; i++) { |
1314 | group_fd = -1; | 1317 | group_fd = -1; |
1315 | list_for_each_entry(counter, &evsel_list, node) | 1318 | list_for_each_entry(counter, &evsel_list->entries, node) |
1316 | start_counter(i, counter); | 1319 | start_counter(i, counter); |
1317 | } | 1320 | } |
1318 | 1321 | ||
@@ -1354,7 +1357,7 @@ static const char * const top_usage[] = { | |||
1354 | }; | 1357 | }; |
1355 | 1358 | ||
1356 | static const struct option options[] = { | 1359 | static const struct option options[] = { |
1357 | OPT_CALLBACK('e', "event", NULL, "event", | 1360 | OPT_CALLBACK('e', "event", &evsel_list, "event", |
1358 | "event selector. use 'perf list' to list available events", | 1361 | "event selector. use 'perf list' to list available events", |
1359 | parse_events), | 1362 | parse_events), |
1360 | OPT_INTEGER('c', "count", &default_interval, | 1363 | OPT_INTEGER('c', "count", &default_interval, |
@@ -1404,6 +1407,10 @@ int cmd_top(int argc, const char **argv, const char *prefix __used) | |||
1404 | struct perf_evsel *pos; | 1407 | struct perf_evsel *pos; |
1405 | int status = -ENOMEM; | 1408 | int status = -ENOMEM; |
1406 | 1409 | ||
1410 | evsel_list = perf_evlist__new(); | ||
1411 | if (evsel_list == NULL) | ||
1412 | return -ENOMEM; | ||
1413 | |||
1407 | page_size = sysconf(_SC_PAGE_SIZE); | 1414 | page_size = sysconf(_SC_PAGE_SIZE); |
1408 | 1415 | ||
1409 | argc = parse_options(argc, argv, options, top_usage, 0); | 1416 | argc = parse_options(argc, argv, options, top_usage, 0); |
@@ -1431,7 +1438,8 @@ int cmd_top(int argc, const char **argv, const char *prefix __used) | |||
1431 | cpu_list = NULL; | 1438 | cpu_list = NULL; |
1432 | } | 1439 | } |
1433 | 1440 | ||
1434 | if (!nr_counters && perf_evsel_list__create_default() < 0) { | 1441 | if (!evsel_list->nr_entries && |
1442 | perf_evlist__add_default(evsel_list) < 0) { | ||
1435 | pr_err("Not enough memory for event selector list\n"); | 1443 | pr_err("Not enough memory for event selector list\n"); |
1436 | return -ENOMEM; | 1444 | return -ENOMEM; |
1437 | } | 1445 | } |
@@ -1459,7 +1467,7 @@ int cmd_top(int argc, const char **argv, const char *prefix __used) | |||
1459 | if (cpus == NULL) | 1467 | if (cpus == NULL) |
1460 | usage_with_options(top_usage, options); | 1468 | usage_with_options(top_usage, options); |
1461 | 1469 | ||
1462 | list_for_each_entry(pos, &evsel_list, node) { | 1470 | list_for_each_entry(pos, &evsel_list->entries, node) { |
1463 | if (perf_evsel__alloc_mmap_per_thread(pos, cpus->nr, threads->nr) < 0 || | 1471 | if (perf_evsel__alloc_mmap_per_thread(pos, cpus->nr, threads->nr) < 0 || |
1464 | perf_evsel__alloc_fd(pos, cpus->nr, threads->nr) < 0) | 1472 | perf_evsel__alloc_fd(pos, cpus->nr, threads->nr) < 0) |
1465 | goto out_free_fd; | 1473 | goto out_free_fd; |
@@ -1472,10 +1480,10 @@ int cmd_top(int argc, const char **argv, const char *prefix __used) | |||
1472 | pos->attr.sample_period = default_interval; | 1480 | pos->attr.sample_period = default_interval; |
1473 | } | 1481 | } |
1474 | 1482 | ||
1475 | sym_evsel = list_entry(evsel_list.next, struct perf_evsel, node); | 1483 | sym_evsel = list_entry(evsel_list->entries.next, struct perf_evsel, node); |
1476 | 1484 | ||
1477 | symbol_conf.priv_size = (sizeof(struct sym_entry) + | 1485 | symbol_conf.priv_size = (sizeof(struct sym_entry) + |
1478 | (nr_counters + 1) * sizeof(unsigned long)); | 1486 | (evsel_list->nr_entries + 1) * sizeof(unsigned long)); |
1479 | 1487 | ||
1480 | symbol_conf.try_vmlinux_path = (symbol_conf.vmlinux_name == NULL); | 1488 | symbol_conf.try_vmlinux_path = (symbol_conf.vmlinux_name == NULL); |
1481 | if (symbol__init() < 0) | 1489 | if (symbol__init() < 0) |
@@ -1489,9 +1497,9 @@ int cmd_top(int argc, const char **argv, const char *prefix __used) | |||
1489 | 1497 | ||
1490 | status = __cmd_top(); | 1498 | status = __cmd_top(); |
1491 | out_free_fd: | 1499 | out_free_fd: |
1492 | list_for_each_entry(pos, &evsel_list, node) | 1500 | list_for_each_entry(pos, &evsel_list->entries, node) |
1493 | perf_evsel__free_mmap(pos); | 1501 | perf_evsel__free_mmap(pos); |
1494 | perf_evsel_list__delete(); | 1502 | perf_evlist__delete(evsel_list); |
1495 | 1503 | ||
1496 | return status; | 1504 | return status; |
1497 | } | 1505 | } |
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c new file mode 100644 index 000000000000..7b4faec23737 --- /dev/null +++ b/tools/perf/util/evlist.c | |||
@@ -0,0 +1,53 @@ | |||
1 | #include "evlist.h" | ||
2 | #include "evsel.h" | ||
3 | #include "util.h" | ||
4 | |||
5 | struct perf_evlist *perf_evlist__new(void) | ||
6 | { | ||
7 | struct perf_evlist *evlist = zalloc(sizeof(*evlist)); | ||
8 | |||
9 | if (evlist != NULL) { | ||
10 | INIT_LIST_HEAD(&evlist->entries); | ||
11 | } | ||
12 | |||
13 | return evlist; | ||
14 | } | ||
15 | |||
16 | static void perf_evlist__purge(struct perf_evlist *evlist) | ||
17 | { | ||
18 | struct perf_evsel *pos, *n; | ||
19 | |||
20 | list_for_each_entry_safe(pos, n, &evlist->entries, node) { | ||
21 | list_del_init(&pos->node); | ||
22 | perf_evsel__delete(pos); | ||
23 | } | ||
24 | |||
25 | evlist->nr_entries = 0; | ||
26 | } | ||
27 | |||
28 | void perf_evlist__delete(struct perf_evlist *evlist) | ||
29 | { | ||
30 | perf_evlist__purge(evlist); | ||
31 | free(evlist); | ||
32 | } | ||
33 | |||
34 | void perf_evlist__add(struct perf_evlist *evlist, struct perf_evsel *entry) | ||
35 | { | ||
36 | list_add_tail(&entry->node, &evlist->entries); | ||
37 | ++evlist->nr_entries; | ||
38 | } | ||
39 | |||
40 | int perf_evlist__add_default(struct perf_evlist *evlist) | ||
41 | { | ||
42 | struct perf_event_attr attr = { | ||
43 | .type = PERF_TYPE_HARDWARE, | ||
44 | .config = PERF_COUNT_HW_CPU_CYCLES, | ||
45 | }; | ||
46 | struct perf_evsel *evsel = perf_evsel__new(&attr, 0); | ||
47 | |||
48 | if (evsel == NULL) | ||
49 | return -ENOMEM; | ||
50 | |||
51 | perf_evlist__add(evlist, evsel); | ||
52 | return 0; | ||
53 | } | ||
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h new file mode 100644 index 000000000000..48db91a8abf3 --- /dev/null +++ b/tools/perf/util/evlist.h | |||
@@ -0,0 +1,19 @@ | |||
1 | #ifndef __PERF_EVLIST_H | ||
2 | #define __PERF_EVLIST_H 1 | ||
3 | |||
4 | #include <linux/list.h> | ||
5 | |||
6 | struct perf_evlist { | ||
7 | struct list_head entries; | ||
8 | int nr_entries; | ||
9 | }; | ||
10 | |||
11 | struct perf_evsel; | ||
12 | |||
13 | struct perf_evlist *perf_evlist__new(void); | ||
14 | void perf_evlist__delete(struct perf_evlist *evlist); | ||
15 | |||
16 | void perf_evlist__add(struct perf_evlist *evlist, struct perf_evsel *entry); | ||
17 | int perf_evlist__add_default(struct perf_evlist *evlist); | ||
18 | |||
19 | #endif /* __PERF_EVLIST_H */ | ||
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index f6a929e74981..f0138d472339 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c | |||
@@ -8,6 +8,7 @@ | |||
8 | #include <linux/list.h> | 8 | #include <linux/list.h> |
9 | #include <linux/kernel.h> | 9 | #include <linux/kernel.h> |
10 | 10 | ||
11 | #include "evlist.h" | ||
11 | #include "util.h" | 12 | #include "util.h" |
12 | #include "header.h" | 13 | #include "header.h" |
13 | #include "../perf.h" | 14 | #include "../perf.h" |
@@ -428,7 +429,8 @@ static bool perf_session__read_build_ids(struct perf_session *self, bool with_hi | |||
428 | return ret; | 429 | return ret; |
429 | } | 430 | } |
430 | 431 | ||
431 | static int perf_header__adds_write(struct perf_header *self, int fd) | 432 | static int perf_header__adds_write(struct perf_header *self, |
433 | struct perf_evlist *evlist, int fd) | ||
432 | { | 434 | { |
433 | int nr_sections; | 435 | int nr_sections; |
434 | struct perf_session *session; | 436 | struct perf_session *session; |
@@ -463,7 +465,7 @@ static int perf_header__adds_write(struct perf_header *self, int fd) | |||
463 | 465 | ||
464 | /* Write trace info */ | 466 | /* Write trace info */ |
465 | trace_sec->offset = lseek(fd, 0, SEEK_CUR); | 467 | trace_sec->offset = lseek(fd, 0, SEEK_CUR); |
466 | read_tracing_data(fd, &evsel_list); | 468 | read_tracing_data(fd, &evlist->entries); |
467 | trace_sec->size = lseek(fd, 0, SEEK_CUR) - trace_sec->offset; | 469 | trace_sec->size = lseek(fd, 0, SEEK_CUR) - trace_sec->offset; |
468 | } | 470 | } |
469 | 471 | ||
@@ -513,7 +515,8 @@ int perf_header__write_pipe(int fd) | |||
513 | return 0; | 515 | return 0; |
514 | } | 516 | } |
515 | 517 | ||
516 | int perf_header__write(struct perf_header *self, int fd, bool at_exit) | 518 | int perf_header__write(struct perf_header *self, struct perf_evlist *evlist, |
519 | int fd, bool at_exit) | ||
517 | { | 520 | { |
518 | struct perf_file_header f_header; | 521 | struct perf_file_header f_header; |
519 | struct perf_file_attr f_attr; | 522 | struct perf_file_attr f_attr; |
@@ -566,7 +569,7 @@ int perf_header__write(struct perf_header *self, int fd, bool at_exit) | |||
566 | self->data_offset = lseek(fd, 0, SEEK_CUR); | 569 | self->data_offset = lseek(fd, 0, SEEK_CUR); |
567 | 570 | ||
568 | if (at_exit) { | 571 | if (at_exit) { |
569 | err = perf_header__adds_write(self, fd); | 572 | err = perf_header__adds_write(self, evlist, fd); |
570 | if (err < 0) | 573 | if (err < 0) |
571 | return err; | 574 | return err; |
572 | } | 575 | } |
@@ -1133,7 +1136,7 @@ int event__process_event_type(event_t *self, | |||
1133 | return 0; | 1136 | return 0; |
1134 | } | 1137 | } |
1135 | 1138 | ||
1136 | int event__synthesize_tracing_data(int fd, struct list_head *pattrs, | 1139 | int event__synthesize_tracing_data(int fd, struct perf_evlist *evlist, |
1137 | event__handler_t process, | 1140 | event__handler_t process, |
1138 | struct perf_session *session __unused) | 1141 | struct perf_session *session __unused) |
1139 | { | 1142 | { |
@@ -1144,7 +1147,7 @@ int event__synthesize_tracing_data(int fd, struct list_head *pattrs, | |||
1144 | memset(&ev, 0, sizeof(ev)); | 1147 | memset(&ev, 0, sizeof(ev)); |
1145 | 1148 | ||
1146 | ev.tracing_data.header.type = PERF_RECORD_HEADER_TRACING_DATA; | 1149 | ev.tracing_data.header.type = PERF_RECORD_HEADER_TRACING_DATA; |
1147 | size = read_tracing_data_size(fd, pattrs); | 1150 | size = read_tracing_data_size(fd, &evlist->entries); |
1148 | if (size <= 0) | 1151 | if (size <= 0) |
1149 | return size; | 1152 | return size; |
1150 | aligned_size = ALIGN(size, sizeof(u64)); | 1153 | aligned_size = ALIGN(size, sizeof(u64)); |
@@ -1154,7 +1157,7 @@ int event__synthesize_tracing_data(int fd, struct list_head *pattrs, | |||
1154 | 1157 | ||
1155 | process(&ev, NULL, session); | 1158 | process(&ev, NULL, session); |
1156 | 1159 | ||
1157 | err = read_tracing_data(fd, pattrs); | 1160 | err = read_tracing_data(fd, &evlist->entries); |
1158 | write_padded(fd, NULL, 0, padding); | 1161 | write_padded(fd, NULL, 0, padding); |
1159 | 1162 | ||
1160 | return aligned_size; | 1163 | return aligned_size; |
diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h index 33f16be7b72f..65afd7f74e0d 100644 --- a/tools/perf/util/header.h +++ b/tools/perf/util/header.h | |||
@@ -65,8 +65,11 @@ struct perf_header { | |||
65 | int perf_header__init(struct perf_header *self); | 65 | int perf_header__init(struct perf_header *self); |
66 | void perf_header__exit(struct perf_header *self); | 66 | void perf_header__exit(struct perf_header *self); |
67 | 67 | ||
68 | struct perf_evlist; | ||
69 | |||
68 | int perf_header__read(struct perf_session *session, int fd); | 70 | int perf_header__read(struct perf_session *session, int fd); |
69 | int perf_header__write(struct perf_header *self, int fd, bool at_exit); | 71 | int perf_header__write(struct perf_header *self, struct perf_evlist *evlist, |
72 | int fd, bool at_exit); | ||
70 | int perf_header__write_pipe(int fd); | 73 | int perf_header__write_pipe(int fd); |
71 | 74 | ||
72 | int perf_header__add_attr(struct perf_header *self, | 75 | int perf_header__add_attr(struct perf_header *self, |
@@ -113,7 +116,7 @@ int event__synthesize_event_types(event__handler_t process, | |||
113 | int event__process_event_type(event_t *self, | 116 | int event__process_event_type(event_t *self, |
114 | struct perf_session *session); | 117 | struct perf_session *session); |
115 | 118 | ||
116 | int event__synthesize_tracing_data(int fd, struct list_head *pattrs, | 119 | int event__synthesize_tracing_data(int fd, struct perf_evlist *evlist, |
117 | event__handler_t process, | 120 | event__handler_t process, |
118 | struct perf_session *session); | 121 | struct perf_session *session); |
119 | int event__process_tracing_data(event_t *self, | 122 | int event__process_tracing_data(event_t *self, |
diff --git a/tools/perf/util/include/linux/list.h b/tools/perf/util/include/linux/list.h index f5ca26e53fbb..356c7e467b83 100644 --- a/tools/perf/util/include/linux/list.h +++ b/tools/perf/util/include/linux/list.h | |||
@@ -1,3 +1,4 @@ | |||
1 | #include <linux/kernel.h> | ||
1 | #include "../../../../include/linux/list.h" | 2 | #include "../../../../include/linux/list.h" |
2 | 3 | ||
3 | #ifndef PERF_LIST_H | 4 | #ifndef PERF_LIST_H |
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 135f69baf966..d3086cecd2dd 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c | |||
@@ -1,6 +1,7 @@ | |||
1 | #include "../../../include/linux/hw_breakpoint.h" | 1 | #include "../../../include/linux/hw_breakpoint.h" |
2 | #include "util.h" | 2 | #include "util.h" |
3 | #include "../perf.h" | 3 | #include "../perf.h" |
4 | #include "evlist.h" | ||
4 | #include "evsel.h" | 5 | #include "evsel.h" |
5 | #include "parse-options.h" | 6 | #include "parse-options.h" |
6 | #include "parse-events.h" | 7 | #include "parse-events.h" |
@@ -11,10 +12,6 @@ | |||
11 | #include "header.h" | 12 | #include "header.h" |
12 | #include "debugfs.h" | 13 | #include "debugfs.h" |
13 | 14 | ||
14 | int nr_counters; | ||
15 | |||
16 | LIST_HEAD(evsel_list); | ||
17 | |||
18 | struct event_symbol { | 15 | struct event_symbol { |
19 | u8 type; | 16 | u8 type; |
20 | u64 config; | 17 | u64 config; |
@@ -778,8 +775,9 @@ modifier: | |||
778 | return ret; | 775 | return ret; |
779 | } | 776 | } |
780 | 777 | ||
781 | int parse_events(const struct option *opt __used, const char *str, int unset __used) | 778 | int parse_events(const struct option *opt, const char *str, int unset __used) |
782 | { | 779 | { |
780 | struct perf_evlist *evlist = *(struct perf_evlist **)opt->value; | ||
783 | struct perf_event_attr attr; | 781 | struct perf_event_attr attr; |
784 | enum event_result ret; | 782 | enum event_result ret; |
785 | 783 | ||
@@ -794,12 +792,10 @@ int parse_events(const struct option *opt __used, const char *str, int unset __u | |||
794 | 792 | ||
795 | if (ret != EVT_HANDLED_ALL) { | 793 | if (ret != EVT_HANDLED_ALL) { |
796 | struct perf_evsel *evsel; | 794 | struct perf_evsel *evsel; |
797 | evsel = perf_evsel__new(&attr, | 795 | evsel = perf_evsel__new(&attr, evlist->nr_entries); |
798 | nr_counters); | ||
799 | if (evsel == NULL) | 796 | if (evsel == NULL) |
800 | return -1; | 797 | return -1; |
801 | list_add_tail(&evsel->node, &evsel_list); | 798 | perf_evlist__add(evlist, evsel); |
802 | ++nr_counters; | ||
803 | } | 799 | } |
804 | 800 | ||
805 | if (*str == 0) | 801 | if (*str == 0) |
@@ -813,13 +809,14 @@ int parse_events(const struct option *opt __used, const char *str, int unset __u | |||
813 | return 0; | 809 | return 0; |
814 | } | 810 | } |
815 | 811 | ||
816 | int parse_filter(const struct option *opt __used, const char *str, | 812 | int parse_filter(const struct option *opt, const char *str, |
817 | int unset __used) | 813 | int unset __used) |
818 | { | 814 | { |
815 | struct perf_evlist *evlist = *(struct perf_evlist **)opt->value; | ||
819 | struct perf_evsel *last = NULL; | 816 | struct perf_evsel *last = NULL; |
820 | 817 | ||
821 | if (!list_empty(&evsel_list)) | 818 | if (evlist->nr_entries > 0) |
822 | last = list_entry(evsel_list.prev, struct perf_evsel, node); | 819 | last = list_entry(evlist->entries.prev, struct perf_evsel, node); |
823 | 820 | ||
824 | if (last == NULL || last->attr.type != PERF_TYPE_TRACEPOINT) { | 821 | if (last == NULL || last->attr.type != PERF_TYPE_TRACEPOINT) { |
825 | fprintf(stderr, | 822 | fprintf(stderr, |
@@ -981,33 +978,3 @@ void print_events(void) | |||
981 | 978 | ||
982 | exit(129); | 979 | exit(129); |
983 | } | 980 | } |
984 | |||
985 | int perf_evsel_list__create_default(void) | ||
986 | { | ||
987 | struct perf_evsel *evsel; | ||
988 | struct perf_event_attr attr; | ||
989 | |||
990 | memset(&attr, 0, sizeof(attr)); | ||
991 | attr.type = PERF_TYPE_HARDWARE; | ||
992 | attr.config = PERF_COUNT_HW_CPU_CYCLES; | ||
993 | |||
994 | evsel = perf_evsel__new(&attr, 0); | ||
995 | |||
996 | if (evsel == NULL) | ||
997 | return -ENOMEM; | ||
998 | |||
999 | list_add(&evsel->node, &evsel_list); | ||
1000 | ++nr_counters; | ||
1001 | return 0; | ||
1002 | } | ||
1003 | |||
1004 | void perf_evsel_list__delete(void) | ||
1005 | { | ||
1006 | struct perf_evsel *pos, *n; | ||
1007 | |||
1008 | list_for_each_entry_safe(pos, n, &evsel_list, node) { | ||
1009 | list_del_init(&pos->node); | ||
1010 | perf_evsel__delete(pos); | ||
1011 | } | ||
1012 | nr_counters = 0; | ||
1013 | } | ||
diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h index 458e3ecf17af..cf7e94abb676 100644 --- a/tools/perf/util/parse-events.h +++ b/tools/perf/util/parse-events.h | |||
@@ -9,11 +9,6 @@ | |||
9 | struct list_head; | 9 | struct list_head; |
10 | struct perf_evsel; | 10 | struct perf_evsel; |
11 | 11 | ||
12 | extern struct list_head evsel_list; | ||
13 | |||
14 | int perf_evsel_list__create_default(void); | ||
15 | void perf_evsel_list__delete(void); | ||
16 | |||
17 | struct option; | 12 | struct option; |
18 | 13 | ||
19 | struct tracepoint_path { | 14 | struct tracepoint_path { |
@@ -25,8 +20,6 @@ struct tracepoint_path { | |||
25 | extern struct tracepoint_path *tracepoint_id_to_path(u64 config); | 20 | extern struct tracepoint_path *tracepoint_id_to_path(u64 config); |
26 | extern bool have_tracepoints(struct list_head *evlist); | 21 | extern bool have_tracepoints(struct list_head *evlist); |
27 | 22 | ||
28 | extern int nr_counters; | ||
29 | |||
30 | const char *event_name(struct perf_evsel *event); | 23 | const char *event_name(struct perf_evsel *event); |
31 | extern const char *__event_name(int type, u64 config); | 24 | extern const char *__event_name(int type, u64 config); |
32 | 25 | ||