aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/evlist.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util/evlist.c')
-rw-r--r--tools/perf/util/evlist.c73
1 files changed, 43 insertions, 30 deletions
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index b939221efd8d..dc6fa3fbb180 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -117,6 +117,8 @@ void perf_evlist__delete(struct perf_evlist *evlist)
117void perf_evlist__add(struct perf_evlist *evlist, struct perf_evsel *entry) 117void perf_evlist__add(struct perf_evlist *evlist, struct perf_evsel *entry)
118{ 118{
119 list_add_tail(&entry->node, &evlist->entries); 119 list_add_tail(&entry->node, &evlist->entries);
120 entry->idx = evlist->nr_entries;
121
120 if (!evlist->nr_entries++) 122 if (!evlist->nr_entries++)
121 perf_evlist__set_id_pos(evlist); 123 perf_evlist__set_id_pos(evlist);
122} 124}
@@ -165,7 +167,7 @@ int perf_evlist__add_default(struct perf_evlist *evlist)
165 167
166 event_attr_init(&attr); 168 event_attr_init(&attr);
167 169
168 evsel = perf_evsel__new(&attr, 0); 170 evsel = perf_evsel__new(&attr);
169 if (evsel == NULL) 171 if (evsel == NULL)
170 goto error; 172 goto error;
171 173
@@ -190,7 +192,7 @@ static int perf_evlist__add_attrs(struct perf_evlist *evlist,
190 size_t i; 192 size_t i;
191 193
192 for (i = 0; i < nr_attrs; i++) { 194 for (i = 0; i < nr_attrs; i++) {
193 evsel = perf_evsel__new(attrs + i, evlist->nr_entries + i); 195 evsel = perf_evsel__new_idx(attrs + i, evlist->nr_entries + i);
194 if (evsel == NULL) 196 if (evsel == NULL)
195 goto out_delete_partial_list; 197 goto out_delete_partial_list;
196 list_add_tail(&evsel->node, &head); 198 list_add_tail(&evsel->node, &head);
@@ -249,9 +251,8 @@ perf_evlist__find_tracepoint_by_name(struct perf_evlist *evlist,
249int perf_evlist__add_newtp(struct perf_evlist *evlist, 251int perf_evlist__add_newtp(struct perf_evlist *evlist,
250 const char *sys, const char *name, void *handler) 252 const char *sys, const char *name, void *handler)
251{ 253{
252 struct perf_evsel *evsel; 254 struct perf_evsel *evsel = perf_evsel__newtp(sys, name);
253 255
254 evsel = perf_evsel__newtp(sys, name, evlist->nr_entries);
255 if (evsel == NULL) 256 if (evsel == NULL)
256 return -1; 257 return -1;
257 258
@@ -704,12 +705,10 @@ static size_t perf_evlist__mmap_size(unsigned long pages)
704 return (pages + 1) * page_size; 705 return (pages + 1) * page_size;
705} 706}
706 707
707int perf_evlist__parse_mmap_pages(const struct option *opt, const char *str, 708static long parse_pages_arg(const char *str, unsigned long min,
708 int unset __maybe_unused) 709 unsigned long max)
709{ 710{
710 unsigned int *mmap_pages = opt->value;
711 unsigned long pages, val; 711 unsigned long pages, val;
712 size_t size;
713 static struct parse_tag tags[] = { 712 static struct parse_tag tags[] = {
714 { .tag = 'B', .mult = 1 }, 713 { .tag = 'B', .mult = 1 },
715 { .tag = 'K', .mult = 1 << 10 }, 714 { .tag = 'K', .mult = 1 << 10 },
@@ -718,33 +717,49 @@ int perf_evlist__parse_mmap_pages(const struct option *opt, const char *str,
718 { .tag = 0 }, 717 { .tag = 0 },
719 }; 718 };
720 719
720 if (str == NULL)
721 return -EINVAL;
722
721 val = parse_tag_value(str, tags); 723 val = parse_tag_value(str, tags);
722 if (val != (unsigned long) -1) { 724 if (val != (unsigned long) -1) {
723 /* we got file size value */ 725 /* we got file size value */
724 pages = PERF_ALIGN(val, page_size) / page_size; 726 pages = PERF_ALIGN(val, page_size) / page_size;
725 if (pages < (1UL << 31) && !is_power_of_2(pages)) {
726 pages = next_pow2(pages);
727 pr_info("rounding mmap pages size to %lu (%lu pages)\n",
728 pages * page_size, pages);
729 }
730 } else { 727 } else {
731 /* we got pages count value */ 728 /* we got pages count value */
732 char *eptr; 729 char *eptr;
733 pages = strtoul(str, &eptr, 10); 730 pages = strtoul(str, &eptr, 10);
734 if (*eptr != '\0') { 731 if (*eptr != '\0')
735 pr_err("failed to parse --mmap_pages/-m value\n"); 732 return -EINVAL;
736 return -1;
737 }
738 } 733 }
739 734
740 if (pages > UINT_MAX || pages > SIZE_MAX / page_size) { 735 if ((pages == 0) && (min == 0)) {
741 pr_err("--mmap_pages/-m value too big\n"); 736 /* leave number of pages at 0 */
742 return -1; 737 } else if (pages < (1UL << 31) && !is_power_of_2(pages)) {
738 /* round pages up to next power of 2 */
739 pages = next_pow2(pages);
740 pr_info("rounding mmap pages size to %lu bytes (%lu pages)\n",
741 pages * page_size, pages);
743 } 742 }
744 743
745 size = perf_evlist__mmap_size(pages); 744 if (pages > max)
746 if (!size) { 745 return -EINVAL;
747 pr_err("--mmap_pages/-m value must be a power of two."); 746
747 return pages;
748}
749
750int perf_evlist__parse_mmap_pages(const struct option *opt, const char *str,
751 int unset __maybe_unused)
752{
753 unsigned int *mmap_pages = opt->value;
754 unsigned long max = UINT_MAX;
755 long pages;
756
757 if (max < SIZE_MAX / page_size)
758 max = SIZE_MAX / page_size;
759
760 pages = parse_pages_arg(str, 1, max);
761 if (pages < 0) {
762 pr_err("Invalid argument for --mmap_pages/-m\n");
748 return -1; 763 return -1;
749 } 764 }
750 765
@@ -796,8 +811,7 @@ int perf_evlist__mmap(struct perf_evlist *evlist, unsigned int pages,
796 return perf_evlist__mmap_per_cpu(evlist, prot, mask); 811 return perf_evlist__mmap_per_cpu(evlist, prot, mask);
797} 812}
798 813
799int perf_evlist__create_maps(struct perf_evlist *evlist, 814int perf_evlist__create_maps(struct perf_evlist *evlist, struct target *target)
800 struct perf_target *target)
801{ 815{
802 evlist->threads = thread_map__new_str(target->pid, target->tid, 816 evlist->threads = thread_map__new_str(target->pid, target->tid,
803 target->uid); 817 target->uid);
@@ -805,9 +819,9 @@ int perf_evlist__create_maps(struct perf_evlist *evlist,
805 if (evlist->threads == NULL) 819 if (evlist->threads == NULL)
806 return -1; 820 return -1;
807 821
808 if (perf_target__has_task(target)) 822 if (target__has_task(target))
809 evlist->cpus = cpu_map__dummy_new(); 823 evlist->cpus = cpu_map__dummy_new();
810 else if (!perf_target__has_cpu(target) && !target->uses_mmap) 824 else if (!target__has_cpu(target) && !target->uses_mmap)
811 evlist->cpus = cpu_map__dummy_new(); 825 evlist->cpus = cpu_map__dummy_new();
812 else 826 else
813 evlist->cpus = cpu_map__new(target->cpu_list); 827 evlist->cpus = cpu_map__new(target->cpu_list);
@@ -1016,8 +1030,7 @@ out_err:
1016 return err; 1030 return err;
1017} 1031}
1018 1032
1019int perf_evlist__prepare_workload(struct perf_evlist *evlist, 1033int perf_evlist__prepare_workload(struct perf_evlist *evlist, struct target *target,
1020 struct perf_target *target,
1021 const char *argv[], bool pipe_output, 1034 const char *argv[], bool pipe_output,
1022 bool want_signal) 1035 bool want_signal)
1023{ 1036{
@@ -1069,7 +1082,7 @@ int perf_evlist__prepare_workload(struct perf_evlist *evlist,
1069 exit(-1); 1082 exit(-1);
1070 } 1083 }
1071 1084
1072 if (perf_target__none(target)) 1085 if (target__none(target))
1073 evlist->threads->map[0] = evlist->workload.pid; 1086 evlist->threads->map[0] = evlist->workload.pid;
1074 1087
1075 close(child_ready_pipe[1]); 1088 close(child_ready_pipe[1]);