Merge branch 'tip/perf/urgent' of git://git.kernel.org/pub/scm/linux/kernel/git/roste...
[cascardo/linux.git] / tools / perf / util / evsel.c
1 /*
2  * Copyright (C) 2011, Red Hat Inc, Arnaldo Carvalho de Melo <acme@redhat.com>
3  *
4  * Parts came from builtin-{top,stat,record}.c, see those files for further
5  * copyright notes.
6  *
7  * Released under the GPL v2. (and only v2, not any later version)
8  */
9
10 #include <byteswap.h>
11 #include "asm/bug.h"
12 #include "evsel.h"
13 #include "evlist.h"
14 #include "util.h"
15 #include "cpumap.h"
16 #include "thread_map.h"
17 #include "target.h"
18
19 #define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y))
20 #define GROUP_FD(group_fd, cpu) (*(int *)xyarray__entry(group_fd, cpu, 0))
21
22 int __perf_evsel__sample_size(u64 sample_type)
23 {
24         u64 mask = sample_type & PERF_SAMPLE_MASK;
25         int size = 0;
26         int i;
27
28         for (i = 0; i < 64; i++) {
29                 if (mask & (1ULL << i))
30                         size++;
31         }
32
33         size *= sizeof(u64);
34
35         return size;
36 }
37
38 void hists__init(struct hists *hists)
39 {
40         memset(hists, 0, sizeof(*hists));
41         hists->entries_in_array[0] = hists->entries_in_array[1] = RB_ROOT;
42         hists->entries_in = &hists->entries_in_array[0];
43         hists->entries_collapsed = RB_ROOT;
44         hists->entries = RB_ROOT;
45         pthread_mutex_init(&hists->lock, NULL);
46 }
47
48 void perf_evsel__init(struct perf_evsel *evsel,
49                       struct perf_event_attr *attr, int idx)
50 {
51         evsel->idx         = idx;
52         evsel->attr        = *attr;
53         INIT_LIST_HEAD(&evsel->node);
54         hists__init(&evsel->hists);
55 }
56
57 struct perf_evsel *perf_evsel__new(struct perf_event_attr *attr, int idx)
58 {
59         struct perf_evsel *evsel = zalloc(sizeof(*evsel));
60
61         if (evsel != NULL)
62                 perf_evsel__init(evsel, attr, idx);
63
64         return evsel;
65 }
66
67 void perf_evsel__config(struct perf_evsel *evsel, struct perf_record_opts *opts,
68                         struct perf_evsel *first)
69 {
70         struct perf_event_attr *attr = &evsel->attr;
71         int track = !evsel->idx; /* only the first counter needs these */
72
73         attr->disabled = 1;
74         attr->sample_id_all = opts->sample_id_all_missing ? 0 : 1;
75         attr->inherit       = !opts->no_inherit;
76         attr->read_format   = PERF_FORMAT_TOTAL_TIME_ENABLED |
77                               PERF_FORMAT_TOTAL_TIME_RUNNING |
78                               PERF_FORMAT_ID;
79
80         attr->sample_type  |= PERF_SAMPLE_IP | PERF_SAMPLE_TID;
81
82         /*
83          * We default some events to a 1 default interval. But keep
84          * it a weak assumption overridable by the user.
85          */
86         if (!attr->sample_period || (opts->user_freq != UINT_MAX &&
87                                      opts->user_interval != ULLONG_MAX)) {
88                 if (opts->freq) {
89                         attr->sample_type       |= PERF_SAMPLE_PERIOD;
90                         attr->freq              = 1;
91                         attr->sample_freq       = opts->freq;
92                 } else {
93                         attr->sample_period = opts->default_interval;
94                 }
95         }
96
97         if (opts->no_samples)
98                 attr->sample_freq = 0;
99
100         if (opts->inherit_stat)
101                 attr->inherit_stat = 1;
102
103         if (opts->sample_address) {
104                 attr->sample_type       |= PERF_SAMPLE_ADDR;
105                 attr->mmap_data = track;
106         }
107
108         if (opts->call_graph)
109                 attr->sample_type       |= PERF_SAMPLE_CALLCHAIN;
110
111         if (perf_target__has_cpu(&opts->target))
112                 attr->sample_type       |= PERF_SAMPLE_CPU;
113
114         if (opts->period)
115                 attr->sample_type       |= PERF_SAMPLE_PERIOD;
116
117         if (!opts->sample_id_all_missing &&
118             (opts->sample_time || !opts->no_inherit ||
119              perf_target__has_cpu(&opts->target)))
120                 attr->sample_type       |= PERF_SAMPLE_TIME;
121
122         if (opts->raw_samples) {
123                 attr->sample_type       |= PERF_SAMPLE_TIME;
124                 attr->sample_type       |= PERF_SAMPLE_RAW;
125                 attr->sample_type       |= PERF_SAMPLE_CPU;
126         }
127
128         if (opts->no_delay) {
129                 attr->watermark = 0;
130                 attr->wakeup_events = 1;
131         }
132         if (opts->branch_stack) {
133                 attr->sample_type       |= PERF_SAMPLE_BRANCH_STACK;
134                 attr->branch_sample_type = opts->branch_stack;
135         }
136
137         attr->mmap = track;
138         attr->comm = track;
139
140         if (perf_target__none(&opts->target) &&
141             (!opts->group || evsel == first)) {
142                 attr->enable_on_exec = 1;
143         }
144 }
145
146 int perf_evsel__alloc_fd(struct perf_evsel *evsel, int ncpus, int nthreads)
147 {
148         int cpu, thread;
149         evsel->fd = xyarray__new(ncpus, nthreads, sizeof(int));
150
151         if (evsel->fd) {
152                 for (cpu = 0; cpu < ncpus; cpu++) {
153                         for (thread = 0; thread < nthreads; thread++) {
154                                 FD(evsel, cpu, thread) = -1;
155                         }
156                 }
157         }
158
159         return evsel->fd != NULL ? 0 : -ENOMEM;
160 }
161
162 int perf_evsel__alloc_id(struct perf_evsel *evsel, int ncpus, int nthreads)
163 {
164         evsel->sample_id = xyarray__new(ncpus, nthreads, sizeof(struct perf_sample_id));
165         if (evsel->sample_id == NULL)
166                 return -ENOMEM;
167
168         evsel->id = zalloc(ncpus * nthreads * sizeof(u64));
169         if (evsel->id == NULL) {
170                 xyarray__delete(evsel->sample_id);
171                 evsel->sample_id = NULL;
172                 return -ENOMEM;
173         }
174
175         return 0;
176 }
177
178 int perf_evsel__alloc_counts(struct perf_evsel *evsel, int ncpus)
179 {
180         evsel->counts = zalloc((sizeof(*evsel->counts) +
181                                 (ncpus * sizeof(struct perf_counts_values))));
182         return evsel->counts != NULL ? 0 : -ENOMEM;
183 }
184
185 void perf_evsel__free_fd(struct perf_evsel *evsel)
186 {
187         xyarray__delete(evsel->fd);
188         evsel->fd = NULL;
189 }
190
191 void perf_evsel__free_id(struct perf_evsel *evsel)
192 {
193         xyarray__delete(evsel->sample_id);
194         evsel->sample_id = NULL;
195         free(evsel->id);
196         evsel->id = NULL;
197 }
198
199 void perf_evsel__close_fd(struct perf_evsel *evsel, int ncpus, int nthreads)
200 {
201         int cpu, thread;
202
203         for (cpu = 0; cpu < ncpus; cpu++)
204                 for (thread = 0; thread < nthreads; ++thread) {
205                         close(FD(evsel, cpu, thread));
206                         FD(evsel, cpu, thread) = -1;
207                 }
208 }
209
210 void perf_evsel__exit(struct perf_evsel *evsel)
211 {
212         assert(list_empty(&evsel->node));
213         xyarray__delete(evsel->fd);
214         xyarray__delete(evsel->sample_id);
215         free(evsel->id);
216 }
217
218 void perf_evsel__delete(struct perf_evsel *evsel)
219 {
220         perf_evsel__exit(evsel);
221         close_cgroup(evsel->cgrp);
222         free(evsel->name);
223         free(evsel);
224 }
225
226 int __perf_evsel__read_on_cpu(struct perf_evsel *evsel,
227                               int cpu, int thread, bool scale)
228 {
229         struct perf_counts_values count;
230         size_t nv = scale ? 3 : 1;
231
232         if (FD(evsel, cpu, thread) < 0)
233                 return -EINVAL;
234
235         if (evsel->counts == NULL && perf_evsel__alloc_counts(evsel, cpu + 1) < 0)
236                 return -ENOMEM;
237
238         if (readn(FD(evsel, cpu, thread), &count, nv * sizeof(u64)) < 0)
239                 return -errno;
240
241         if (scale) {
242                 if (count.run == 0)
243                         count.val = 0;
244                 else if (count.run < count.ena)
245                         count.val = (u64)((double)count.val * count.ena / count.run + 0.5);
246         } else
247                 count.ena = count.run = 0;
248
249         evsel->counts->cpu[cpu] = count;
250         return 0;
251 }
252
253 int __perf_evsel__read(struct perf_evsel *evsel,
254                        int ncpus, int nthreads, bool scale)
255 {
256         size_t nv = scale ? 3 : 1;
257         int cpu, thread;
258         struct perf_counts_values *aggr = &evsel->counts->aggr, count;
259
260         aggr->val = aggr->ena = aggr->run = 0;
261
262         for (cpu = 0; cpu < ncpus; cpu++) {
263                 for (thread = 0; thread < nthreads; thread++) {
264                         if (FD(evsel, cpu, thread) < 0)
265                                 continue;
266
267                         if (readn(FD(evsel, cpu, thread),
268                                   &count, nv * sizeof(u64)) < 0)
269                                 return -errno;
270
271                         aggr->val += count.val;
272                         if (scale) {
273                                 aggr->ena += count.ena;
274                                 aggr->run += count.run;
275                         }
276                 }
277         }
278
279         evsel->counts->scaled = 0;
280         if (scale) {
281                 if (aggr->run == 0) {
282                         evsel->counts->scaled = -1;
283                         aggr->val = 0;
284                         return 0;
285                 }
286
287                 if (aggr->run < aggr->ena) {
288                         evsel->counts->scaled = 1;
289                         aggr->val = (u64)((double)aggr->val * aggr->ena / aggr->run + 0.5);
290                 }
291         } else
292                 aggr->ena = aggr->run = 0;
293
294         return 0;
295 }
296
297 static int __perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus,
298                               struct thread_map *threads, bool group,
299                               struct xyarray *group_fds)
300 {
301         int cpu, thread;
302         unsigned long flags = 0;
303         int pid = -1, err;
304
305         if (evsel->fd == NULL &&
306             perf_evsel__alloc_fd(evsel, cpus->nr, threads->nr) < 0)
307                 return -ENOMEM;
308
309         if (evsel->cgrp) {
310                 flags = PERF_FLAG_PID_CGROUP;
311                 pid = evsel->cgrp->fd;
312         }
313
314         for (cpu = 0; cpu < cpus->nr; cpu++) {
315                 int group_fd = group_fds ? GROUP_FD(group_fds, cpu) : -1;
316
317                 for (thread = 0; thread < threads->nr; thread++) {
318
319                         if (!evsel->cgrp)
320                                 pid = threads->map[thread];
321
322                         FD(evsel, cpu, thread) = sys_perf_event_open(&evsel->attr,
323                                                                      pid,
324                                                                      cpus->map[cpu],
325                                                                      group_fd, flags);
326                         if (FD(evsel, cpu, thread) < 0) {
327                                 err = -errno;
328                                 goto out_close;
329                         }
330
331                         if (group && group_fd == -1)
332                                 group_fd = FD(evsel, cpu, thread);
333                 }
334         }
335
336         return 0;
337
338 out_close:
339         do {
340                 while (--thread >= 0) {
341                         close(FD(evsel, cpu, thread));
342                         FD(evsel, cpu, thread) = -1;
343                 }
344                 thread = threads->nr;
345         } while (--cpu >= 0);
346         return err;
347 }
348
349 void perf_evsel__close(struct perf_evsel *evsel, int ncpus, int nthreads)
350 {
351         if (evsel->fd == NULL)
352                 return;
353
354         perf_evsel__close_fd(evsel, ncpus, nthreads);
355         perf_evsel__free_fd(evsel);
356         evsel->fd = NULL;
357 }
358
359 static struct {
360         struct cpu_map map;
361         int cpus[1];
362 } empty_cpu_map = {
363         .map.nr = 1,
364         .cpus   = { -1, },
365 };
366
367 static struct {
368         struct thread_map map;
369         int threads[1];
370 } empty_thread_map = {
371         .map.nr  = 1,
372         .threads = { -1, },
373 };
374
375 int perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus,
376                      struct thread_map *threads, bool group,
377                      struct xyarray *group_fd)
378 {
379         if (cpus == NULL) {
380                 /* Work around old compiler warnings about strict aliasing */
381                 cpus = &empty_cpu_map.map;
382         }
383
384         if (threads == NULL)
385                 threads = &empty_thread_map.map;
386
387         return __perf_evsel__open(evsel, cpus, threads, group, group_fd);
388 }
389
390 int perf_evsel__open_per_cpu(struct perf_evsel *evsel,
391                              struct cpu_map *cpus, bool group,
392                              struct xyarray *group_fd)
393 {
394         return __perf_evsel__open(evsel, cpus, &empty_thread_map.map, group,
395                                   group_fd);
396 }
397
398 int perf_evsel__open_per_thread(struct perf_evsel *evsel,
399                                 struct thread_map *threads, bool group,
400                                 struct xyarray *group_fd)
401 {
402         return __perf_evsel__open(evsel, &empty_cpu_map.map, threads, group,
403                                   group_fd);
404 }
405
406 static int perf_event__parse_id_sample(const union perf_event *event, u64 type,
407                                        struct perf_sample *sample)
408 {
409         const u64 *array = event->sample.array;
410
411         array += ((event->header.size -
412                    sizeof(event->header)) / sizeof(u64)) - 1;
413
414         if (type & PERF_SAMPLE_CPU) {
415                 u32 *p = (u32 *)array;
416                 sample->cpu = *p;
417                 array--;
418         }
419
420         if (type & PERF_SAMPLE_STREAM_ID) {
421                 sample->stream_id = *array;
422                 array--;
423         }
424
425         if (type & PERF_SAMPLE_ID) {
426                 sample->id = *array;
427                 array--;
428         }
429
430         if (type & PERF_SAMPLE_TIME) {
431                 sample->time = *array;
432                 array--;
433         }
434
435         if (type & PERF_SAMPLE_TID) {
436                 u32 *p = (u32 *)array;
437                 sample->pid = p[0];
438                 sample->tid = p[1];
439         }
440
441         return 0;
442 }
443
444 static bool sample_overlap(const union perf_event *event,
445                            const void *offset, u64 size)
446 {
447         const void *base = event;
448
449         if (offset + size > base + event->header.size)
450                 return true;
451
452         return false;
453 }
454
455 int perf_event__parse_sample(const union perf_event *event, u64 type,
456                              int sample_size, bool sample_id_all,
457                              struct perf_sample *data, bool swapped)
458 {
459         const u64 *array;
460
461         /*
462          * used for cross-endian analysis. See git commit 65014ab3
463          * for why this goofiness is needed.
464          */
465         union u64_swap u;
466
467         memset(data, 0, sizeof(*data));
468         data->cpu = data->pid = data->tid = -1;
469         data->stream_id = data->id = data->time = -1ULL;
470         data->period = 1;
471
472         if (event->header.type != PERF_RECORD_SAMPLE) {
473                 if (!sample_id_all)
474                         return 0;
475                 return perf_event__parse_id_sample(event, type, data);
476         }
477
478         array = event->sample.array;
479
480         if (sample_size + sizeof(event->header) > event->header.size)
481                 return -EFAULT;
482
483         if (type & PERF_SAMPLE_IP) {
484                 data->ip = event->ip.ip;
485                 array++;
486         }
487
488         if (type & PERF_SAMPLE_TID) {
489                 u.val64 = *array;
490                 if (swapped) {
491                         /* undo swap of u64, then swap on individual u32s */
492                         u.val64 = bswap_64(u.val64);
493                         u.val32[0] = bswap_32(u.val32[0]);
494                         u.val32[1] = bswap_32(u.val32[1]);
495                 }
496
497                 data->pid = u.val32[0];
498                 data->tid = u.val32[1];
499                 array++;
500         }
501
502         if (type & PERF_SAMPLE_TIME) {
503                 data->time = *array;
504                 array++;
505         }
506
507         data->addr = 0;
508         if (type & PERF_SAMPLE_ADDR) {
509                 data->addr = *array;
510                 array++;
511         }
512
513         data->id = -1ULL;
514         if (type & PERF_SAMPLE_ID) {
515                 data->id = *array;
516                 array++;
517         }
518
519         if (type & PERF_SAMPLE_STREAM_ID) {
520                 data->stream_id = *array;
521                 array++;
522         }
523
524         if (type & PERF_SAMPLE_CPU) {
525
526                 u.val64 = *array;
527                 if (swapped) {
528                         /* undo swap of u64, then swap on individual u32s */
529                         u.val64 = bswap_64(u.val64);
530                         u.val32[0] = bswap_32(u.val32[0]);
531                 }
532
533                 data->cpu = u.val32[0];
534                 array++;
535         }
536
537         if (type & PERF_SAMPLE_PERIOD) {
538                 data->period = *array;
539                 array++;
540         }
541
542         if (type & PERF_SAMPLE_READ) {
543                 fprintf(stderr, "PERF_SAMPLE_READ is unsupported for now\n");
544                 return -1;
545         }
546
547         if (type & PERF_SAMPLE_CALLCHAIN) {
548                 if (sample_overlap(event, array, sizeof(data->callchain->nr)))
549                         return -EFAULT;
550
551                 data->callchain = (struct ip_callchain *)array;
552
553                 if (sample_overlap(event, array, data->callchain->nr))
554                         return -EFAULT;
555
556                 array += 1 + data->callchain->nr;
557         }
558
559         if (type & PERF_SAMPLE_RAW) {
560                 const u64 *pdata;
561
562                 u.val64 = *array;
563                 if (WARN_ONCE(swapped,
564                               "Endianness of raw data not corrected!\n")) {
565                         /* undo swap of u64, then swap on individual u32s */
566                         u.val64 = bswap_64(u.val64);
567                         u.val32[0] = bswap_32(u.val32[0]);
568                         u.val32[1] = bswap_32(u.val32[1]);
569                 }
570
571                 if (sample_overlap(event, array, sizeof(u32)))
572                         return -EFAULT;
573
574                 data->raw_size = u.val32[0];
575                 pdata = (void *) array + sizeof(u32);
576
577                 if (sample_overlap(event, pdata, data->raw_size))
578                         return -EFAULT;
579
580                 data->raw_data = (void *) pdata;
581
582                 array = (void *)array + data->raw_size + sizeof(u32);
583         }
584
585         if (type & PERF_SAMPLE_BRANCH_STACK) {
586                 u64 sz;
587
588                 data->branch_stack = (struct branch_stack *)array;
589                 array++; /* nr */
590
591                 sz = data->branch_stack->nr * sizeof(struct branch_entry);
592                 sz /= sizeof(u64);
593                 array += sz;
594         }
595         return 0;
596 }
597
598 int perf_event__synthesize_sample(union perf_event *event, u64 type,
599                                   const struct perf_sample *sample,
600                                   bool swapped)
601 {
602         u64 *array;
603
604         /*
605          * used for cross-endian analysis. See git commit 65014ab3
606          * for why this goofiness is needed.
607          */
608         union u64_swap u;
609
610         array = event->sample.array;
611
612         if (type & PERF_SAMPLE_IP) {
613                 event->ip.ip = sample->ip;
614                 array++;
615         }
616
617         if (type & PERF_SAMPLE_TID) {
618                 u.val32[0] = sample->pid;
619                 u.val32[1] = sample->tid;
620                 if (swapped) {
621                         /*
622                          * Inverse of what is done in perf_event__parse_sample
623                          */
624                         u.val32[0] = bswap_32(u.val32[0]);
625                         u.val32[1] = bswap_32(u.val32[1]);
626                         u.val64 = bswap_64(u.val64);
627                 }
628
629                 *array = u.val64;
630                 array++;
631         }
632
633         if (type & PERF_SAMPLE_TIME) {
634                 *array = sample->time;
635                 array++;
636         }
637
638         if (type & PERF_SAMPLE_ADDR) {
639                 *array = sample->addr;
640                 array++;
641         }
642
643         if (type & PERF_SAMPLE_ID) {
644                 *array = sample->id;
645                 array++;
646         }
647
648         if (type & PERF_SAMPLE_STREAM_ID) {
649                 *array = sample->stream_id;
650                 array++;
651         }
652
653         if (type & PERF_SAMPLE_CPU) {
654                 u.val32[0] = sample->cpu;
655                 if (swapped) {
656                         /*
657                          * Inverse of what is done in perf_event__parse_sample
658                          */
659                         u.val32[0] = bswap_32(u.val32[0]);
660                         u.val64 = bswap_64(u.val64);
661                 }
662                 *array = u.val64;
663                 array++;
664         }
665
666         if (type & PERF_SAMPLE_PERIOD) {
667                 *array = sample->period;
668                 array++;
669         }
670
671         return 0;
672 }