diff options
-rw-r--r-- | tools/perf/builtin-record.c | 13 | ||||
-rw-r--r-- | tools/perf/builtin-stat.c | 13 | ||||
-rw-r--r-- | tools/perf/builtin-test.c | 8 | ||||
-rw-r--r-- | tools/perf/builtin-top.c | 12 | ||||
-rw-r--r-- | tools/perf/util/evlist.c | 20 | ||||
-rw-r--r-- | tools/perf/util/evlist.h | 3 | ||||
-rw-r--r-- | tools/perf/util/evsel.c | 51 | ||||
-rw-r--r-- | tools/perf/util/evsel.h | 11 | ||||
-rw-r--r-- | tools/perf/util/parse-events.c | 26 | ||||
-rw-r--r-- | tools/perf/util/parse-events.h | 1 | ||||
-rw-r--r-- | tools/perf/util/python.c | 7 |
11 files changed, 96 insertions, 69 deletions
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index 22dd05d3680c..f5b6137c0f7e 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c | |||
@@ -185,18 +185,18 @@ static bool perf_evlist__equal(struct perf_evlist *evlist, | |||
185 | 185 | ||
186 | static void perf_record__open(struct perf_record *rec) | 186 | static void perf_record__open(struct perf_record *rec) |
187 | { | 187 | { |
188 | struct perf_evsel *pos, *first; | 188 | struct perf_evsel *pos; |
189 | struct perf_evlist *evlist = rec->evlist; | 189 | struct perf_evlist *evlist = rec->evlist; |
190 | struct perf_session *session = rec->session; | 190 | struct perf_session *session = rec->session; |
191 | struct perf_record_opts *opts = &rec->opts; | 191 | struct perf_record_opts *opts = &rec->opts; |
192 | 192 | ||
193 | first = list_entry(evlist->entries.next, struct perf_evsel, node); | ||
194 | |||
195 | perf_evlist__config_attrs(evlist, opts); | 193 | perf_evlist__config_attrs(evlist, opts); |
196 | 194 | ||
195 | if (opts->group) | ||
196 | perf_evlist__group(evlist); | ||
197 | |||
197 | list_for_each_entry(pos, &evlist->entries, node) { | 198 | list_for_each_entry(pos, &evlist->entries, node) { |
198 | struct perf_event_attr *attr = &pos->attr; | 199 | struct perf_event_attr *attr = &pos->attr; |
199 | struct xyarray *group_fd = NULL; | ||
200 | /* | 200 | /* |
201 | * Check if parse_single_tracepoint_event has already asked for | 201 | * Check if parse_single_tracepoint_event has already asked for |
202 | * PERF_SAMPLE_TIME. | 202 | * PERF_SAMPLE_TIME. |
@@ -211,16 +211,13 @@ static void perf_record__open(struct perf_record *rec) | |||
211 | */ | 211 | */ |
212 | bool time_needed = attr->sample_type & PERF_SAMPLE_TIME; | 212 | bool time_needed = attr->sample_type & PERF_SAMPLE_TIME; |
213 | 213 | ||
214 | if (opts->group && pos != first) | ||
215 | group_fd = first->fd; | ||
216 | fallback_missing_features: | 214 | fallback_missing_features: |
217 | if (opts->exclude_guest_missing) | 215 | if (opts->exclude_guest_missing) |
218 | attr->exclude_guest = attr->exclude_host = 0; | 216 | attr->exclude_guest = attr->exclude_host = 0; |
219 | retry_sample_id: | 217 | retry_sample_id: |
220 | attr->sample_id_all = opts->sample_id_all_missing ? 0 : 1; | 218 | attr->sample_id_all = opts->sample_id_all_missing ? 0 : 1; |
221 | try_again: | 219 | try_again: |
222 | if (perf_evsel__open(pos, evlist->cpus, evlist->threads, | 220 | if (perf_evsel__open(pos, evlist->cpus, evlist->threads) < 0) { |
223 | opts->group, group_fd) < 0) { | ||
224 | int err = errno; | 221 | int err = errno; |
225 | 222 | ||
226 | if (err == EPERM || err == EACCES) { | 223 | if (err == EPERM || err == EACCES) { |
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 861f0aec77ae..23908a85bba9 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c | |||
@@ -281,13 +281,9 @@ static int create_perf_stat_counter(struct perf_evsel *evsel, | |||
281 | struct perf_evsel *first) | 281 | struct perf_evsel *first) |
282 | { | 282 | { |
283 | struct perf_event_attr *attr = &evsel->attr; | 283 | struct perf_event_attr *attr = &evsel->attr; |
284 | struct xyarray *group_fd = NULL; | ||
285 | bool exclude_guest_missing = false; | 284 | bool exclude_guest_missing = false; |
286 | int ret; | 285 | int ret; |
287 | 286 | ||
288 | if (group && evsel != first) | ||
289 | group_fd = first->fd; | ||
290 | |||
291 | if (scale) | 287 | if (scale) |
292 | attr->read_format = PERF_FORMAT_TOTAL_TIME_ENABLED | | 288 | attr->read_format = PERF_FORMAT_TOTAL_TIME_ENABLED | |
293 | PERF_FORMAT_TOTAL_TIME_RUNNING; | 289 | PERF_FORMAT_TOTAL_TIME_RUNNING; |
@@ -299,8 +295,7 @@ retry: | |||
299 | evsel->attr.exclude_guest = evsel->attr.exclude_host = 0; | 295 | evsel->attr.exclude_guest = evsel->attr.exclude_host = 0; |
300 | 296 | ||
301 | if (perf_target__has_cpu(&target)) { | 297 | if (perf_target__has_cpu(&target)) { |
302 | ret = perf_evsel__open_per_cpu(evsel, evsel_list->cpus, | 298 | ret = perf_evsel__open_per_cpu(evsel, evsel_list->cpus); |
303 | group, group_fd); | ||
304 | if (ret) | 299 | if (ret) |
305 | goto check_ret; | 300 | goto check_ret; |
306 | return 0; | 301 | return 0; |
@@ -311,8 +306,7 @@ retry: | |||
311 | attr->enable_on_exec = 1; | 306 | attr->enable_on_exec = 1; |
312 | } | 307 | } |
313 | 308 | ||
314 | ret = perf_evsel__open_per_thread(evsel, evsel_list->threads, | 309 | ret = perf_evsel__open_per_thread(evsel, evsel_list->threads); |
315 | group, group_fd); | ||
316 | if (!ret) | 310 | if (!ret) |
317 | return 0; | 311 | return 0; |
318 | /* fall through */ | 312 | /* fall through */ |
@@ -483,6 +477,9 @@ static int run_perf_stat(int argc __used, const char **argv) | |||
483 | close(child_ready_pipe[0]); | 477 | close(child_ready_pipe[0]); |
484 | } | 478 | } |
485 | 479 | ||
480 | if (group) | ||
481 | perf_evlist__group(evsel_list); | ||
482 | |||
486 | first = list_entry(evsel_list->entries.next, struct perf_evsel, node); | 483 | first = list_entry(evsel_list->entries.next, struct perf_evsel, node); |
487 | 484 | ||
488 | list_for_each_entry(counter, &evsel_list->entries, node) { | 485 | list_for_each_entry(counter, &evsel_list->entries, node) { |
diff --git a/tools/perf/builtin-test.c b/tools/perf/builtin-test.c index 1d592f5cbea9..9a479b68fc9b 100644 --- a/tools/perf/builtin-test.c +++ b/tools/perf/builtin-test.c | |||
@@ -294,7 +294,7 @@ static int test__open_syscall_event(void) | |||
294 | goto out_thread_map_delete; | 294 | goto out_thread_map_delete; |
295 | } | 295 | } |
296 | 296 | ||
297 | if (perf_evsel__open_per_thread(evsel, threads, false, NULL) < 0) { | 297 | if (perf_evsel__open_per_thread(evsel, threads) < 0) { |
298 | pr_debug("failed to open counter: %s, " | 298 | pr_debug("failed to open counter: %s, " |
299 | "tweak /proc/sys/kernel/perf_event_paranoid?\n", | 299 | "tweak /proc/sys/kernel/perf_event_paranoid?\n", |
300 | strerror(errno)); | 300 | strerror(errno)); |
@@ -369,7 +369,7 @@ static int test__open_syscall_event_on_all_cpus(void) | |||
369 | goto out_thread_map_delete; | 369 | goto out_thread_map_delete; |
370 | } | 370 | } |
371 | 371 | ||
372 | if (perf_evsel__open(evsel, cpus, threads, false, NULL) < 0) { | 372 | if (perf_evsel__open(evsel, cpus, threads) < 0) { |
373 | pr_debug("failed to open counter: %s, " | 373 | pr_debug("failed to open counter: %s, " |
374 | "tweak /proc/sys/kernel/perf_event_paranoid?\n", | 374 | "tweak /proc/sys/kernel/perf_event_paranoid?\n", |
375 | strerror(errno)); | 375 | strerror(errno)); |
@@ -533,7 +533,7 @@ static int test__basic_mmap(void) | |||
533 | 533 | ||
534 | perf_evlist__add(evlist, evsels[i]); | 534 | perf_evlist__add(evlist, evsels[i]); |
535 | 535 | ||
536 | if (perf_evsel__open(evsels[i], cpus, threads, false, NULL) < 0) { | 536 | if (perf_evsel__open(evsels[i], cpus, threads) < 0) { |
537 | pr_debug("failed to open counter: %s, " | 537 | pr_debug("failed to open counter: %s, " |
538 | "tweak /proc/sys/kernel/perf_event_paranoid?\n", | 538 | "tweak /proc/sys/kernel/perf_event_paranoid?\n", |
539 | strerror(errno)); | 539 | strerror(errno)); |
@@ -737,7 +737,7 @@ static int test__PERF_RECORD(void) | |||
737 | * Call sys_perf_event_open on all the fds on all the evsels, | 737 | * Call sys_perf_event_open on all the fds on all the evsels, |
738 | * grouping them if asked to. | 738 | * grouping them if asked to. |
739 | */ | 739 | */ |
740 | err = perf_evlist__open(evlist, opts.group); | 740 | err = perf_evlist__open(evlist); |
741 | if (err < 0) { | 741 | if (err < 0) { |
742 | pr_debug("perf_evlist__open: %s\n", strerror(errno)); | 742 | pr_debug("perf_evlist__open: %s\n", strerror(errno)); |
743 | goto out_delete_evlist; | 743 | goto out_delete_evlist; |
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index e45a1ba61722..392d2192b75e 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c | |||
@@ -886,17 +886,14 @@ static void perf_top__mmap_read(struct perf_top *top) | |||
886 | 886 | ||
887 | static void perf_top__start_counters(struct perf_top *top) | 887 | static void perf_top__start_counters(struct perf_top *top) |
888 | { | 888 | { |
889 | struct perf_evsel *counter, *first; | 889 | struct perf_evsel *counter; |
890 | struct perf_evlist *evlist = top->evlist; | 890 | struct perf_evlist *evlist = top->evlist; |
891 | 891 | ||
892 | first = list_entry(evlist->entries.next, struct perf_evsel, node); | 892 | if (top->group) |
893 | perf_evlist__group(evlist); | ||
893 | 894 | ||
894 | list_for_each_entry(counter, &evlist->entries, node) { | 895 | list_for_each_entry(counter, &evlist->entries, node) { |
895 | struct perf_event_attr *attr = &counter->attr; | 896 | struct perf_event_attr *attr = &counter->attr; |
896 | struct xyarray *group_fd = NULL; | ||
897 | |||
898 | if (top->group && counter != first) | ||
899 | group_fd = first->fd; | ||
900 | 897 | ||
901 | attr->sample_type = PERF_SAMPLE_IP | PERF_SAMPLE_TID; | 898 | attr->sample_type = PERF_SAMPLE_IP | PERF_SAMPLE_TID; |
902 | 899 | ||
@@ -927,8 +924,7 @@ retry_sample_id: | |||
927 | attr->sample_id_all = top->sample_id_all_missing ? 0 : 1; | 924 | attr->sample_id_all = top->sample_id_all_missing ? 0 : 1; |
928 | try_again: | 925 | try_again: |
929 | if (perf_evsel__open(counter, top->evlist->cpus, | 926 | if (perf_evsel__open(counter, top->evlist->cpus, |
930 | top->evlist->threads, top->group, | 927 | top->evlist->threads) < 0) { |
931 | group_fd) < 0) { | ||
932 | int err = errno; | 928 | int err = errno; |
933 | 929 | ||
934 | if (err == EPERM || err == EACCES) { | 930 | if (err == EPERM || err == EACCES) { |
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 9b38681add9e..feffee3f2bd8 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c | |||
@@ -108,6 +108,12 @@ void perf_evlist__splice_list_tail(struct perf_evlist *evlist, | |||
108 | evlist->nr_entries += nr_entries; | 108 | evlist->nr_entries += nr_entries; |
109 | } | 109 | } |
110 | 110 | ||
111 | void perf_evlist__group(struct perf_evlist *evlist) | ||
112 | { | ||
113 | if (evlist->nr_entries) | ||
114 | parse_events__set_leader(&evlist->entries); | ||
115 | } | ||
116 | |||
111 | int perf_evlist__add_default(struct perf_evlist *evlist) | 117 | int perf_evlist__add_default(struct perf_evlist *evlist) |
112 | { | 118 | { |
113 | struct perf_event_attr attr = { | 119 | struct perf_event_attr attr = { |
@@ -757,21 +763,13 @@ void perf_evlist__set_selected(struct perf_evlist *evlist, | |||
757 | evlist->selected = evsel; | 763 | evlist->selected = evsel; |
758 | } | 764 | } |
759 | 765 | ||
760 | int perf_evlist__open(struct perf_evlist *evlist, bool group) | 766 | int perf_evlist__open(struct perf_evlist *evlist) |
761 | { | 767 | { |
762 | struct perf_evsel *evsel, *first; | 768 | struct perf_evsel *evsel; |
763 | int err, ncpus, nthreads; | 769 | int err, ncpus, nthreads; |
764 | 770 | ||
765 | first = list_entry(evlist->entries.next, struct perf_evsel, node); | ||
766 | |||
767 | list_for_each_entry(evsel, &evlist->entries, node) { | 771 | list_for_each_entry(evsel, &evlist->entries, node) { |
768 | struct xyarray *group_fd = NULL; | 772 | err = perf_evsel__open(evsel, evlist->cpus, evlist->threads); |
769 | |||
770 | if (group && evsel != first) | ||
771 | group_fd = first->fd; | ||
772 | |||
773 | err = perf_evsel__open(evsel, evlist->cpus, evlist->threads, | ||
774 | group, group_fd); | ||
775 | if (err < 0) | 773 | if (err < 0) |
776 | goto out_err; | 774 | goto out_err; |
777 | } | 775 | } |
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index 528c1acd9298..a19ccd7b51fa 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h | |||
@@ -85,7 +85,7 @@ struct perf_evsel *perf_evlist__id2evsel(struct perf_evlist *evlist, u64 id); | |||
85 | 85 | ||
86 | union perf_event *perf_evlist__mmap_read(struct perf_evlist *self, int idx); | 86 | union perf_event *perf_evlist__mmap_read(struct perf_evlist *self, int idx); |
87 | 87 | ||
88 | int perf_evlist__open(struct perf_evlist *evlist, bool group); | 88 | int perf_evlist__open(struct perf_evlist *evlist); |
89 | 89 | ||
90 | void perf_evlist__config_attrs(struct perf_evlist *evlist, | 90 | void perf_evlist__config_attrs(struct perf_evlist *evlist, |
91 | struct perf_record_opts *opts); | 91 | struct perf_record_opts *opts); |
@@ -132,4 +132,5 @@ void perf_evlist__splice_list_tail(struct perf_evlist *evlist, | |||
132 | struct list_head *list, | 132 | struct list_head *list, |
133 | int nr_entries); | 133 | int nr_entries); |
134 | 134 | ||
135 | void perf_evlist__group(struct perf_evlist *evlist); | ||
135 | #endif /* __PERF_EVLIST_H */ | 136 | #endif /* __PERF_EVLIST_H */ |
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 9c54e8fc2dfc..f5b68e73d751 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c | |||
@@ -21,7 +21,6 @@ | |||
21 | #include "perf_regs.h" | 21 | #include "perf_regs.h" |
22 | 22 | ||
23 | #define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y)) | 23 | #define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y)) |
24 | #define GROUP_FD(group_fd, cpu) (*(int *)xyarray__entry(group_fd, cpu, 0)) | ||
25 | 24 | ||
26 | static int __perf_evsel__sample_size(u64 sample_type) | 25 | static int __perf_evsel__sample_size(u64 sample_type) |
27 | { | 26 | { |
@@ -493,6 +492,7 @@ void perf_evsel__delete(struct perf_evsel *evsel) | |||
493 | { | 492 | { |
494 | perf_evsel__exit(evsel); | 493 | perf_evsel__exit(evsel); |
495 | close_cgroup(evsel->cgrp); | 494 | close_cgroup(evsel->cgrp); |
495 | free(evsel->group_name); | ||
496 | free(evsel->name); | 496 | free(evsel->name); |
497 | free(evsel); | 497 | free(evsel); |
498 | } | 498 | } |
@@ -568,9 +568,28 @@ int __perf_evsel__read(struct perf_evsel *evsel, | |||
568 | return 0; | 568 | return 0; |
569 | } | 569 | } |
570 | 570 | ||
571 | static int get_group_fd(struct perf_evsel *evsel, int cpu, int thread) | ||
572 | { | ||
573 | struct perf_evsel *leader = evsel->leader; | ||
574 | int fd; | ||
575 | |||
576 | if (!leader) | ||
577 | return -1; | ||
578 | |||
579 | /* | ||
580 | * Leader must be already processed/open, | ||
581 | * if not it's a bug. | ||
582 | */ | ||
583 | BUG_ON(!leader->fd); | ||
584 | |||
585 | fd = FD(leader, cpu, thread); | ||
586 | BUG_ON(fd == -1); | ||
587 | |||
588 | return fd; | ||
589 | } | ||
590 | |||
571 | static int __perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus, | 591 | static int __perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus, |
572 | struct thread_map *threads, bool group, | 592 | struct thread_map *threads) |
573 | struct xyarray *group_fds) | ||
574 | { | 593 | { |
575 | int cpu, thread; | 594 | int cpu, thread; |
576 | unsigned long flags = 0; | 595 | unsigned long flags = 0; |
@@ -586,13 +605,15 @@ static int __perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus, | |||
586 | } | 605 | } |
587 | 606 | ||
588 | for (cpu = 0; cpu < cpus->nr; cpu++) { | 607 | for (cpu = 0; cpu < cpus->nr; cpu++) { |
589 | int group_fd = group_fds ? GROUP_FD(group_fds, cpu) : -1; | ||
590 | 608 | ||
591 | for (thread = 0; thread < threads->nr; thread++) { | 609 | for (thread = 0; thread < threads->nr; thread++) { |
610 | int group_fd; | ||
592 | 611 | ||
593 | if (!evsel->cgrp) | 612 | if (!evsel->cgrp) |
594 | pid = threads->map[thread]; | 613 | pid = threads->map[thread]; |
595 | 614 | ||
615 | group_fd = get_group_fd(evsel, cpu, thread); | ||
616 | |||
596 | FD(evsel, cpu, thread) = sys_perf_event_open(&evsel->attr, | 617 | FD(evsel, cpu, thread) = sys_perf_event_open(&evsel->attr, |
597 | pid, | 618 | pid, |
598 | cpus->map[cpu], | 619 | cpus->map[cpu], |
@@ -602,8 +623,9 @@ static int __perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus, | |||
602 | goto out_close; | 623 | goto out_close; |
603 | } | 624 | } |
604 | 625 | ||
605 | if (group && group_fd == -1) | 626 | pr_debug("event cpu %d, thread %d, fd %d, group %d\n", |
606 | group_fd = FD(evsel, cpu, thread); | 627 | cpu, pid, FD(evsel, cpu, thread), |
628 | group_fd); | ||
607 | } | 629 | } |
608 | } | 630 | } |
609 | 631 | ||
@@ -647,8 +669,7 @@ static struct { | |||
647 | }; | 669 | }; |
648 | 670 | ||
649 | int perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus, | 671 | int perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus, |
650 | struct thread_map *threads, bool group, | 672 | struct thread_map *threads) |
651 | struct xyarray *group_fd) | ||
652 | { | 673 | { |
653 | if (cpus == NULL) { | 674 | if (cpus == NULL) { |
654 | /* Work around old compiler warnings about strict aliasing */ | 675 | /* Work around old compiler warnings about strict aliasing */ |
@@ -658,23 +679,19 @@ int perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus, | |||
658 | if (threads == NULL) | 679 | if (threads == NULL) |
659 | threads = &empty_thread_map.map; | 680 | threads = &empty_thread_map.map; |
660 | 681 | ||
661 | return __perf_evsel__open(evsel, cpus, threads, group, group_fd); | 682 | return __perf_evsel__open(evsel, cpus, threads); |
662 | } | 683 | } |
663 | 684 | ||
664 | int perf_evsel__open_per_cpu(struct perf_evsel *evsel, | 685 | int perf_evsel__open_per_cpu(struct perf_evsel *evsel, |
665 | struct cpu_map *cpus, bool group, | 686 | struct cpu_map *cpus) |
666 | struct xyarray *group_fd) | ||
667 | { | 687 | { |
668 | return __perf_evsel__open(evsel, cpus, &empty_thread_map.map, group, | 688 | return __perf_evsel__open(evsel, cpus, &empty_thread_map.map); |
669 | group_fd); | ||
670 | } | 689 | } |
671 | 690 | ||
672 | int perf_evsel__open_per_thread(struct perf_evsel *evsel, | 691 | int perf_evsel__open_per_thread(struct perf_evsel *evsel, |
673 | struct thread_map *threads, bool group, | 692 | struct thread_map *threads) |
674 | struct xyarray *group_fd) | ||
675 | { | 693 | { |
676 | return __perf_evsel__open(evsel, &empty_cpu_map.map, threads, group, | 694 | return __perf_evsel__open(evsel, &empty_cpu_map.map, threads); |
677 | group_fd); | ||
678 | } | 695 | } |
679 | 696 | ||
680 | static int perf_event__parse_id_sample(const union perf_event *event, u64 type, | 697 | static int perf_event__parse_id_sample(const union perf_event *event, u64 type, |
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index 6a258c90e7ce..c411b421c888 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h | |||
@@ -70,6 +70,8 @@ struct perf_evsel { | |||
70 | bool supported; | 70 | bool supported; |
71 | /* parse modifier helper */ | 71 | /* parse modifier helper */ |
72 | int exclude_GH; | 72 | int exclude_GH; |
73 | struct perf_evsel *leader; | ||
74 | char *group_name; | ||
73 | }; | 75 | }; |
74 | 76 | ||
75 | struct cpu_map; | 77 | struct cpu_map; |
@@ -109,14 +111,11 @@ void perf_evsel__free_id(struct perf_evsel *evsel); | |||
109 | void perf_evsel__close_fd(struct perf_evsel *evsel, int ncpus, int nthreads); | 111 | void perf_evsel__close_fd(struct perf_evsel *evsel, int ncpus, int nthreads); |
110 | 112 | ||
111 | int perf_evsel__open_per_cpu(struct perf_evsel *evsel, | 113 | int perf_evsel__open_per_cpu(struct perf_evsel *evsel, |
112 | struct cpu_map *cpus, bool group, | 114 | struct cpu_map *cpus); |
113 | struct xyarray *group_fds); | ||
114 | int perf_evsel__open_per_thread(struct perf_evsel *evsel, | 115 | int perf_evsel__open_per_thread(struct perf_evsel *evsel, |
115 | struct thread_map *threads, bool group, | 116 | struct thread_map *threads); |
116 | struct xyarray *group_fds); | ||
117 | int perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus, | 117 | int perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus, |
118 | struct thread_map *threads, bool group, | 118 | struct thread_map *threads); |
119 | struct xyarray *group_fds); | ||
120 | void perf_evsel__close(struct perf_evsel *evsel, int ncpus, int nthreads); | 119 | void perf_evsel__close(struct perf_evsel *evsel, int ncpus, int nthreads); |
121 | 120 | ||
122 | #define perf_evsel__match(evsel, t, c) \ | 121 | #define perf_evsel__match(evsel, t, c) \ |
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 4364575ce6ac..f6453cd414ae 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c | |||
@@ -611,14 +611,32 @@ int parse_events_add_pmu(struct list_head **list, int *idx, | |||
611 | pmu_event_name(head_config)); | 611 | pmu_event_name(head_config)); |
612 | } | 612 | } |
613 | 613 | ||
614 | int parse_events__modifier_group(struct list_head *list __used, | 614 | struct perf_evsel *parse_events__set_leader(struct list_head *list) |
615 | char *event_mod __used) | ||
616 | { | 615 | { |
617 | return 0; | 616 | struct perf_evsel *evsel, *leader; |
617 | |||
618 | leader = list_entry(list->next, struct perf_evsel, node); | ||
619 | leader->leader = NULL; | ||
620 | |||
621 | list_for_each_entry(evsel, list, node) | ||
622 | if (evsel != leader) | ||
623 | evsel->leader = leader; | ||
624 | |||
625 | return leader; | ||
618 | } | 626 | } |
619 | 627 | ||
620 | void parse_events__group(char *name __used, struct list_head *list __used) | 628 | int parse_events__modifier_group(struct list_head *list, |
629 | char *event_mod) | ||
621 | { | 630 | { |
631 | return parse_events__modifier_event(list, event_mod, true); | ||
632 | } | ||
633 | |||
634 | void parse_events__group(char *name, struct list_head *list) | ||
635 | { | ||
636 | struct perf_evsel *leader; | ||
637 | |||
638 | leader = parse_events__set_leader(list); | ||
639 | leader->group_name = name ? strdup(name) : NULL; | ||
622 | } | 640 | } |
623 | 641 | ||
624 | void parse_events_update_lists(struct list_head *list_event, | 642 | void parse_events_update_lists(struct list_head *list_event, |
diff --git a/tools/perf/util/parse-events.h b/tools/perf/util/parse-events.h index 75a6800082a1..e1a184c9e358 100644 --- a/tools/perf/util/parse-events.h +++ b/tools/perf/util/parse-events.h | |||
@@ -92,6 +92,7 @@ int parse_events_add_breakpoint(struct list_head **list, int *idx, | |||
92 | void *ptr, char *type); | 92 | void *ptr, char *type); |
93 | int parse_events_add_pmu(struct list_head **list, int *idx, | 93 | int parse_events_add_pmu(struct list_head **list, int *idx, |
94 | char *pmu , struct list_head *head_config); | 94 | char *pmu , struct list_head *head_config); |
95 | struct perf_evsel *parse_events__set_leader(struct list_head *list); | ||
95 | void parse_events__group(char *name, struct list_head *list); | 96 | void parse_events__group(char *name, struct list_head *list); |
96 | void parse_events_update_lists(struct list_head *list_event, | 97 | void parse_events_update_lists(struct list_head *list_event, |
97 | struct list_head *list_all); | 98 | struct list_head *list_all); |
diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index 0688bfb6d280..f5bba4b8eb9e 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c | |||
@@ -627,7 +627,7 @@ static PyObject *pyrf_evsel__open(struct pyrf_evsel *pevsel, | |||
627 | * This will group just the fds for this single evsel, to group | 627 | * This will group just the fds for this single evsel, to group |
628 | * multiple events, use evlist.open(). | 628 | * multiple events, use evlist.open(). |
629 | */ | 629 | */ |
630 | if (perf_evsel__open(evsel, cpus, threads, group, NULL) < 0) { | 630 | if (perf_evsel__open(evsel, cpus, threads) < 0) { |
631 | PyErr_SetFromErrno(PyExc_OSError); | 631 | PyErr_SetFromErrno(PyExc_OSError); |
632 | return NULL; | 632 | return NULL; |
633 | } | 633 | } |
@@ -824,7 +824,10 @@ static PyObject *pyrf_evlist__open(struct pyrf_evlist *pevlist, | |||
824 | if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OOii", kwlist, &group)) | 824 | if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OOii", kwlist, &group)) |
825 | return NULL; | 825 | return NULL; |
826 | 826 | ||
827 | if (perf_evlist__open(evlist, group) < 0) { | 827 | if (group) |
828 | perf_evlist__group(evlist); | ||
829 | |||
830 | if (perf_evlist__open(evlist) < 0) { | ||
828 | PyErr_SetFromErrno(PyExc_OSError); | 831 | PyErr_SetFromErrno(PyExc_OSError); |
829 | return NULL; | 832 | return NULL; |
830 | } | 833 | } |