]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - tools/perf/util/data-convert-bt.c
thermal: add the note for set_trip_temp
[karo-tx-linux.git] / tools / perf / util / data-convert-bt.c
1 /*
2  * CTF writing support via babeltrace.
3  *
4  * Copyright (C) 2014, Jiri Olsa <jolsa@redhat.com>
5  * Copyright (C) 2014, Sebastian Andrzej Siewior <bigeasy@linutronix.de>
6  *
7  * Released under the GPL v2. (and only v2, not any later version)
8  */
9
10 #include <linux/compiler.h>
11 #include <babeltrace/ctf-writer/writer.h>
12 #include <babeltrace/ctf-writer/clock.h>
13 #include <babeltrace/ctf-writer/stream.h>
14 #include <babeltrace/ctf-writer/event.h>
15 #include <babeltrace/ctf-writer/event-types.h>
16 #include <babeltrace/ctf-writer/event-fields.h>
17 #include <babeltrace/ctf-ir/utils.h>
18 #include <babeltrace/ctf/events.h>
19 #include <traceevent/event-parse.h>
20 #include "asm/bug.h"
21 #include "data-convert-bt.h"
22 #include "session.h"
23 #include "util.h"
24 #include "debug.h"
25 #include "tool.h"
26 #include "evlist.h"
27 #include "evsel.h"
28 #include "machine.h"
29
30 #define pr_N(n, fmt, ...) \
31         eprintf(n, debug_data_convert, fmt, ##__VA_ARGS__)
32
33 #define pr(fmt, ...)  pr_N(1, pr_fmt(fmt), ##__VA_ARGS__)
34 #define pr2(fmt, ...) pr_N(2, pr_fmt(fmt), ##__VA_ARGS__)
35
36 #define pr_time2(t, fmt, ...) pr_time_N(2, debug_data_convert, t, pr_fmt(fmt), ##__VA_ARGS__)
37
38 struct evsel_priv {
39         struct bt_ctf_event_class *event_class;
40 };
41
42 #define MAX_CPUS        4096
43
44 struct ctf_stream {
45         struct bt_ctf_stream *stream;
46         int cpu;
47         u32 count;
48 };
49
50 struct ctf_writer {
51         /* writer primitives */
52         struct bt_ctf_writer             *writer;
53         struct ctf_stream               **stream;
54         int                               stream_cnt;
55         struct bt_ctf_stream_class       *stream_class;
56         struct bt_ctf_clock              *clock;
57
58         /* data types */
59         union {
60                 struct {
61                         struct bt_ctf_field_type        *s64;
62                         struct bt_ctf_field_type        *u64;
63                         struct bt_ctf_field_type        *s32;
64                         struct bt_ctf_field_type        *u32;
65                         struct bt_ctf_field_type        *string;
66                         struct bt_ctf_field_type        *u32_hex;
67                         struct bt_ctf_field_type        *u64_hex;
68                 };
69                 struct bt_ctf_field_type *array[6];
70         } data;
71 };
72
73 struct convert {
74         struct perf_tool        tool;
75         struct ctf_writer       writer;
76
77         u64                     events_size;
78         u64                     events_count;
79
80         /* Ordered events configured queue size. */
81         u64                     queue_size;
82 };
83
84 static int value_set(struct bt_ctf_field_type *type,
85                      struct bt_ctf_event *event,
86                      const char *name, u64 val)
87 {
88         struct bt_ctf_field *field;
89         bool sign = bt_ctf_field_type_integer_get_signed(type);
90         int ret;
91
92         field = bt_ctf_field_create(type);
93         if (!field) {
94                 pr_err("failed to create a field %s\n", name);
95                 return -1;
96         }
97
98         if (sign) {
99                 ret = bt_ctf_field_signed_integer_set_value(field, val);
100                 if (ret) {
101                         pr_err("failed to set field value %s\n", name);
102                         goto err;
103                 }
104         } else {
105                 ret = bt_ctf_field_unsigned_integer_set_value(field, val);
106                 if (ret) {
107                         pr_err("failed to set field value %s\n", name);
108                         goto err;
109                 }
110         }
111
112         ret = bt_ctf_event_set_payload(event, name, field);
113         if (ret) {
114                 pr_err("failed to set payload %s\n", name);
115                 goto err;
116         }
117
118         pr2("  SET [%s = %" PRIu64 "]\n", name, val);
119
120 err:
121         bt_ctf_field_put(field);
122         return ret;
123 }
124
125 #define __FUNC_VALUE_SET(_name, _val_type)                              \
126 static __maybe_unused int value_set_##_name(struct ctf_writer *cw,      \
127                              struct bt_ctf_event *event,                \
128                              const char *name,                          \
129                              _val_type val)                             \
130 {                                                                       \
131         struct bt_ctf_field_type *type = cw->data._name;                \
132         return value_set(type, event, name, (u64) val);                 \
133 }
134
135 #define FUNC_VALUE_SET(_name) __FUNC_VALUE_SET(_name, _name)
136
137 FUNC_VALUE_SET(s32)
138 FUNC_VALUE_SET(u32)
139 FUNC_VALUE_SET(s64)
140 FUNC_VALUE_SET(u64)
141 __FUNC_VALUE_SET(u64_hex, u64)
142
143 static struct bt_ctf_field_type*
144 get_tracepoint_field_type(struct ctf_writer *cw, struct format_field *field)
145 {
146         unsigned long flags = field->flags;
147
148         if (flags & FIELD_IS_STRING)
149                 return cw->data.string;
150
151         if (!(flags & FIELD_IS_SIGNED)) {
152                 /* unsigned long are mostly pointers */
153                 if (flags & FIELD_IS_LONG || flags & FIELD_IS_POINTER)
154                         return cw->data.u64_hex;
155         }
156
157         if (flags & FIELD_IS_SIGNED) {
158                 if (field->size == 8)
159                         return cw->data.s64;
160                 else
161                         return cw->data.s32;
162         }
163
164         if (field->size == 8)
165                 return cw->data.u64;
166         else
167                 return cw->data.u32;
168 }
169
170 static unsigned long long adjust_signedness(unsigned long long value_int, int size)
171 {
172         unsigned long long value_mask;
173
174         /*
175          * value_mask = (1 << (size * 8 - 1)) - 1.
176          * Directly set value_mask for code readers.
177          */
178         switch (size) {
179         case 1:
180                 value_mask = 0x7fULL;
181                 break;
182         case 2:
183                 value_mask = 0x7fffULL;
184                 break;
185         case 4:
186                 value_mask = 0x7fffffffULL;
187                 break;
188         case 8:
189                 /*
190                  * For 64 bit value, return it self. There is no need
191                  * to fill high bit.
192                  */
193                 /* Fall through */
194         default:
195                 /* BUG! */
196                 return value_int;
197         }
198
199         /* If it is a positive value, don't adjust. */
200         if ((value_int & (~0ULL - value_mask)) == 0)
201                 return value_int;
202
203         /* Fill upper part of value_int with 1 to make it a negative long long. */
204         return (value_int & value_mask) | ~value_mask;
205 }
206
207 static int add_tracepoint_field_value(struct ctf_writer *cw,
208                                       struct bt_ctf_event_class *event_class,
209                                       struct bt_ctf_event *event,
210                                       struct perf_sample *sample,
211                                       struct format_field *fmtf)
212 {
213         struct bt_ctf_field_type *type;
214         struct bt_ctf_field *array_field;
215         struct bt_ctf_field *field;
216         const char *name = fmtf->name;
217         void *data = sample->raw_data;
218         unsigned long flags = fmtf->flags;
219         unsigned int n_items;
220         unsigned int i;
221         unsigned int offset;
222         unsigned int len;
223         int ret;
224
225         name = fmtf->alias;
226         offset = fmtf->offset;
227         len = fmtf->size;
228         if (flags & FIELD_IS_STRING)
229                 flags &= ~FIELD_IS_ARRAY;
230
231         if (flags & FIELD_IS_DYNAMIC) {
232                 unsigned long long tmp_val;
233
234                 tmp_val = pevent_read_number(fmtf->event->pevent,
235                                 data + offset, len);
236                 offset = tmp_val;
237                 len = offset >> 16;
238                 offset &= 0xffff;
239         }
240
241         if (flags & FIELD_IS_ARRAY) {
242
243                 type = bt_ctf_event_class_get_field_by_name(
244                                 event_class, name);
245                 array_field = bt_ctf_field_create(type);
246                 bt_ctf_field_type_put(type);
247                 if (!array_field) {
248                         pr_err("Failed to create array type %s\n", name);
249                         return -1;
250                 }
251
252                 len = fmtf->size / fmtf->arraylen;
253                 n_items = fmtf->arraylen;
254         } else {
255                 n_items = 1;
256                 array_field = NULL;
257         }
258
259         type = get_tracepoint_field_type(cw, fmtf);
260
261         for (i = 0; i < n_items; i++) {
262                 if (flags & FIELD_IS_ARRAY)
263                         field = bt_ctf_field_array_get_field(array_field, i);
264                 else
265                         field = bt_ctf_field_create(type);
266
267                 if (!field) {
268                         pr_err("failed to create a field %s\n", name);
269                         return -1;
270                 }
271
272                 if (flags & FIELD_IS_STRING)
273                         ret = bt_ctf_field_string_set_value(field,
274                                         data + offset + i * len);
275                 else {
276                         unsigned long long value_int;
277
278                         value_int = pevent_read_number(
279                                         fmtf->event->pevent,
280                                         data + offset + i * len, len);
281
282                         if (!(flags & FIELD_IS_SIGNED))
283                                 ret = bt_ctf_field_unsigned_integer_set_value(
284                                                 field, value_int);
285                         else
286                                 ret = bt_ctf_field_signed_integer_set_value(
287                                                 field, adjust_signedness(value_int, len));
288                 }
289
290                 if (ret) {
291                         pr_err("failed to set file value %s\n", name);
292                         goto err_put_field;
293                 }
294                 if (!(flags & FIELD_IS_ARRAY)) {
295                         ret = bt_ctf_event_set_payload(event, name, field);
296                         if (ret) {
297                                 pr_err("failed to set payload %s\n", name);
298                                 goto err_put_field;
299                         }
300                 }
301                 bt_ctf_field_put(field);
302         }
303         if (flags & FIELD_IS_ARRAY) {
304                 ret = bt_ctf_event_set_payload(event, name, array_field);
305                 if (ret) {
306                         pr_err("Failed add payload array %s\n", name);
307                         return -1;
308                 }
309                 bt_ctf_field_put(array_field);
310         }
311         return 0;
312
313 err_put_field:
314         bt_ctf_field_put(field);
315         return -1;
316 }
317
318 static int add_tracepoint_fields_values(struct ctf_writer *cw,
319                                         struct bt_ctf_event_class *event_class,
320                                         struct bt_ctf_event *event,
321                                         struct format_field *fields,
322                                         struct perf_sample *sample)
323 {
324         struct format_field *field;
325         int ret;
326
327         for (field = fields; field; field = field->next) {
328                 ret = add_tracepoint_field_value(cw, event_class, event, sample,
329                                 field);
330                 if (ret)
331                         return -1;
332         }
333         return 0;
334 }
335
336 static int add_tracepoint_values(struct ctf_writer *cw,
337                                  struct bt_ctf_event_class *event_class,
338                                  struct bt_ctf_event *event,
339                                  struct perf_evsel *evsel,
340                                  struct perf_sample *sample)
341 {
342         struct format_field *common_fields = evsel->tp_format->format.common_fields;
343         struct format_field *fields        = evsel->tp_format->format.fields;
344         int ret;
345
346         ret = add_tracepoint_fields_values(cw, event_class, event,
347                                            common_fields, sample);
348         if (!ret)
349                 ret = add_tracepoint_fields_values(cw, event_class, event,
350                                                    fields, sample);
351
352         return ret;
353 }
354
355 static int
356 add_bpf_output_values(struct bt_ctf_event_class *event_class,
357                       struct bt_ctf_event *event,
358                       struct perf_sample *sample)
359 {
360         struct bt_ctf_field_type *len_type, *seq_type;
361         struct bt_ctf_field *len_field, *seq_field;
362         unsigned int raw_size = sample->raw_size;
363         unsigned int nr_elements = raw_size / sizeof(u32);
364         unsigned int i;
365         int ret;
366
367         if (nr_elements * sizeof(u32) != raw_size)
368                 pr_warning("Incorrect raw_size (%u) in bpf output event, skip %lu bytes\n",
369                            raw_size, nr_elements * sizeof(u32) - raw_size);
370
371         len_type = bt_ctf_event_class_get_field_by_name(event_class, "raw_len");
372         len_field = bt_ctf_field_create(len_type);
373         if (!len_field) {
374                 pr_err("failed to create 'raw_len' for bpf output event\n");
375                 ret = -1;
376                 goto put_len_type;
377         }
378
379         ret = bt_ctf_field_unsigned_integer_set_value(len_field, nr_elements);
380         if (ret) {
381                 pr_err("failed to set field value for raw_len\n");
382                 goto put_len_field;
383         }
384         ret = bt_ctf_event_set_payload(event, "raw_len", len_field);
385         if (ret) {
386                 pr_err("failed to set payload to raw_len\n");
387                 goto put_len_field;
388         }
389
390         seq_type = bt_ctf_event_class_get_field_by_name(event_class, "raw_data");
391         seq_field = bt_ctf_field_create(seq_type);
392         if (!seq_field) {
393                 pr_err("failed to create 'raw_data' for bpf output event\n");
394                 ret = -1;
395                 goto put_seq_type;
396         }
397
398         ret = bt_ctf_field_sequence_set_length(seq_field, len_field);
399         if (ret) {
400                 pr_err("failed to set length of 'raw_data'\n");
401                 goto put_seq_field;
402         }
403
404         for (i = 0; i < nr_elements; i++) {
405                 struct bt_ctf_field *elem_field =
406                         bt_ctf_field_sequence_get_field(seq_field, i);
407
408                 ret = bt_ctf_field_unsigned_integer_set_value(elem_field,
409                                 ((u32 *)(sample->raw_data))[i]);
410
411                 bt_ctf_field_put(elem_field);
412                 if (ret) {
413                         pr_err("failed to set raw_data[%d]\n", i);
414                         goto put_seq_field;
415                 }
416         }
417
418         ret = bt_ctf_event_set_payload(event, "raw_data", seq_field);
419         if (ret)
420                 pr_err("failed to set payload for raw_data\n");
421
422 put_seq_field:
423         bt_ctf_field_put(seq_field);
424 put_seq_type:
425         bt_ctf_field_type_put(seq_type);
426 put_len_field:
427         bt_ctf_field_put(len_field);
428 put_len_type:
429         bt_ctf_field_type_put(len_type);
430         return ret;
431 }
432
433 static int add_generic_values(struct ctf_writer *cw,
434                               struct bt_ctf_event *event,
435                               struct perf_evsel *evsel,
436                               struct perf_sample *sample)
437 {
438         u64 type = evsel->attr.sample_type;
439         int ret;
440
441         /*
442          * missing:
443          *   PERF_SAMPLE_TIME         - not needed as we have it in
444          *                              ctf event header
445          *   PERF_SAMPLE_READ         - TODO
446          *   PERF_SAMPLE_CALLCHAIN    - TODO
447          *   PERF_SAMPLE_RAW          - tracepoint fields are handled separately
448          *   PERF_SAMPLE_BRANCH_STACK - TODO
449          *   PERF_SAMPLE_REGS_USER    - TODO
450          *   PERF_SAMPLE_STACK_USER   - TODO
451          */
452
453         if (type & PERF_SAMPLE_IP) {
454                 ret = value_set_u64_hex(cw, event, "perf_ip", sample->ip);
455                 if (ret)
456                         return -1;
457         }
458
459         if (type & PERF_SAMPLE_TID) {
460                 ret = value_set_s32(cw, event, "perf_tid", sample->tid);
461                 if (ret)
462                         return -1;
463
464                 ret = value_set_s32(cw, event, "perf_pid", sample->pid);
465                 if (ret)
466                         return -1;
467         }
468
469         if ((type & PERF_SAMPLE_ID) ||
470             (type & PERF_SAMPLE_IDENTIFIER)) {
471                 ret = value_set_u64(cw, event, "perf_id", sample->id);
472                 if (ret)
473                         return -1;
474         }
475
476         if (type & PERF_SAMPLE_STREAM_ID) {
477                 ret = value_set_u64(cw, event, "perf_stream_id", sample->stream_id);
478                 if (ret)
479                         return -1;
480         }
481
482         if (type & PERF_SAMPLE_PERIOD) {
483                 ret = value_set_u64(cw, event, "perf_period", sample->period);
484                 if (ret)
485                         return -1;
486         }
487
488         if (type & PERF_SAMPLE_WEIGHT) {
489                 ret = value_set_u64(cw, event, "perf_weight", sample->weight);
490                 if (ret)
491                         return -1;
492         }
493
494         if (type & PERF_SAMPLE_DATA_SRC) {
495                 ret = value_set_u64(cw, event, "perf_data_src",
496                                 sample->data_src);
497                 if (ret)
498                         return -1;
499         }
500
501         if (type & PERF_SAMPLE_TRANSACTION) {
502                 ret = value_set_u64(cw, event, "perf_transaction",
503                                 sample->transaction);
504                 if (ret)
505                         return -1;
506         }
507
508         return 0;
509 }
510
511 static int ctf_stream__flush(struct ctf_stream *cs)
512 {
513         int err = 0;
514
515         if (cs) {
516                 err = bt_ctf_stream_flush(cs->stream);
517                 if (err)
518                         pr_err("CTF stream %d flush failed\n", cs->cpu);
519
520                 pr("Flush stream for cpu %d (%u samples)\n",
521                    cs->cpu, cs->count);
522
523                 cs->count = 0;
524         }
525
526         return err;
527 }
528
529 static struct ctf_stream *ctf_stream__create(struct ctf_writer *cw, int cpu)
530 {
531         struct ctf_stream *cs;
532         struct bt_ctf_field *pkt_ctx   = NULL;
533         struct bt_ctf_field *cpu_field = NULL;
534         struct bt_ctf_stream *stream   = NULL;
535         int ret;
536
537         cs = zalloc(sizeof(*cs));
538         if (!cs) {
539                 pr_err("Failed to allocate ctf stream\n");
540                 return NULL;
541         }
542
543         stream = bt_ctf_writer_create_stream(cw->writer, cw->stream_class);
544         if (!stream) {
545                 pr_err("Failed to create CTF stream\n");
546                 goto out;
547         }
548
549         pkt_ctx = bt_ctf_stream_get_packet_context(stream);
550         if (!pkt_ctx) {
551                 pr_err("Failed to obtain packet context\n");
552                 goto out;
553         }
554
555         cpu_field = bt_ctf_field_structure_get_field(pkt_ctx, "cpu_id");
556         bt_ctf_field_put(pkt_ctx);
557         if (!cpu_field) {
558                 pr_err("Failed to obtain cpu field\n");
559                 goto out;
560         }
561
562         ret = bt_ctf_field_unsigned_integer_set_value(cpu_field, (u32) cpu);
563         if (ret) {
564                 pr_err("Failed to update CPU number\n");
565                 goto out;
566         }
567
568         bt_ctf_field_put(cpu_field);
569
570         cs->cpu    = cpu;
571         cs->stream = stream;
572         return cs;
573
574 out:
575         if (cpu_field)
576                 bt_ctf_field_put(cpu_field);
577         if (stream)
578                 bt_ctf_stream_put(stream);
579
580         free(cs);
581         return NULL;
582 }
583
584 static void ctf_stream__delete(struct ctf_stream *cs)
585 {
586         if (cs) {
587                 bt_ctf_stream_put(cs->stream);
588                 free(cs);
589         }
590 }
591
592 static struct ctf_stream *ctf_stream(struct ctf_writer *cw, int cpu)
593 {
594         struct ctf_stream *cs = cw->stream[cpu];
595
596         if (!cs) {
597                 cs = ctf_stream__create(cw, cpu);
598                 cw->stream[cpu] = cs;
599         }
600
601         return cs;
602 }
603
604 static int get_sample_cpu(struct ctf_writer *cw, struct perf_sample *sample,
605                           struct perf_evsel *evsel)
606 {
607         int cpu = 0;
608
609         if (evsel->attr.sample_type & PERF_SAMPLE_CPU)
610                 cpu = sample->cpu;
611
612         if (cpu > cw->stream_cnt) {
613                 pr_err("Event was recorded for CPU %d, limit is at %d.\n",
614                         cpu, cw->stream_cnt);
615                 cpu = 0;
616         }
617
618         return cpu;
619 }
620
621 #define STREAM_FLUSH_COUNT 100000
622
623 /*
624  * Currently we have no other way to determine the
625  * time for the stream flush other than keep track
626  * of the number of events and check it against
627  * threshold.
628  */
629 static bool is_flush_needed(struct ctf_stream *cs)
630 {
631         return cs->count >= STREAM_FLUSH_COUNT;
632 }
633
634 static int process_sample_event(struct perf_tool *tool,
635                                 union perf_event *_event,
636                                 struct perf_sample *sample,
637                                 struct perf_evsel *evsel,
638                                 struct machine *machine __maybe_unused)
639 {
640         struct convert *c = container_of(tool, struct convert, tool);
641         struct evsel_priv *priv = evsel->priv;
642         struct ctf_writer *cw = &c->writer;
643         struct ctf_stream *cs;
644         struct bt_ctf_event_class *event_class;
645         struct bt_ctf_event *event;
646         int ret;
647
648         if (WARN_ONCE(!priv, "Failed to setup all events.\n"))
649                 return 0;
650
651         event_class = priv->event_class;
652
653         /* update stats */
654         c->events_count++;
655         c->events_size += _event->header.size;
656
657         pr_time2(sample->time, "sample %" PRIu64 "\n", c->events_count);
658
659         event = bt_ctf_event_create(event_class);
660         if (!event) {
661                 pr_err("Failed to create an CTF event\n");
662                 return -1;
663         }
664
665         bt_ctf_clock_set_time(cw->clock, sample->time);
666
667         ret = add_generic_values(cw, event, evsel, sample);
668         if (ret)
669                 return -1;
670
671         if (evsel->attr.type == PERF_TYPE_TRACEPOINT) {
672                 ret = add_tracepoint_values(cw, event_class, event,
673                                             evsel, sample);
674                 if (ret)
675                         return -1;
676         }
677
678         if (perf_evsel__is_bpf_output(evsel)) {
679                 ret = add_bpf_output_values(event_class, event, sample);
680                 if (ret)
681                         return -1;
682         }
683
684         cs = ctf_stream(cw, get_sample_cpu(cw, sample, evsel));
685         if (cs) {
686                 if (is_flush_needed(cs))
687                         ctf_stream__flush(cs);
688
689                 cs->count++;
690                 bt_ctf_stream_append_event(cs->stream, event);
691         }
692
693         bt_ctf_event_put(event);
694         return cs ? 0 : -1;
695 }
696
697 /* If dup < 0, add a prefix. Else, add _dupl_X suffix. */
698 static char *change_name(char *name, char *orig_name, int dup)
699 {
700         char *new_name = NULL;
701         size_t len;
702
703         if (!name)
704                 name = orig_name;
705
706         if (dup >= 10)
707                 goto out;
708         /*
709          * Add '_' prefix to potential keywork.  According to
710          * Mathieu Desnoyers (https://lkml.org/lkml/2015/1/23/652),
711          * futher CTF spec updating may require us to use '$'.
712          */
713         if (dup < 0)
714                 len = strlen(name) + sizeof("_");
715         else
716                 len = strlen(orig_name) + sizeof("_dupl_X");
717
718         new_name = malloc(len);
719         if (!new_name)
720                 goto out;
721
722         if (dup < 0)
723                 snprintf(new_name, len, "_%s", name);
724         else
725                 snprintf(new_name, len, "%s_dupl_%d", orig_name, dup);
726
727 out:
728         if (name != orig_name)
729                 free(name);
730         return new_name;
731 }
732
733 static int event_class_add_field(struct bt_ctf_event_class *event_class,
734                 struct bt_ctf_field_type *type,
735                 struct format_field *field)
736 {
737         struct bt_ctf_field_type *t = NULL;
738         char *name;
739         int dup = 1;
740         int ret;
741
742         /* alias was already assigned */
743         if (field->alias != field->name)
744                 return bt_ctf_event_class_add_field(event_class, type,
745                                 (char *)field->alias);
746
747         name = field->name;
748
749         /* If 'name' is a keywork, add prefix. */
750         if (bt_ctf_validate_identifier(name))
751                 name = change_name(name, field->name, -1);
752
753         if (!name) {
754                 pr_err("Failed to fix invalid identifier.");
755                 return -1;
756         }
757         while ((t = bt_ctf_event_class_get_field_by_name(event_class, name))) {
758                 bt_ctf_field_type_put(t);
759                 name = change_name(name, field->name, dup++);
760                 if (!name) {
761                         pr_err("Failed to create dup name for '%s'\n", field->name);
762                         return -1;
763                 }
764         }
765
766         ret = bt_ctf_event_class_add_field(event_class, type, name);
767         if (!ret)
768                 field->alias = name;
769
770         return ret;
771 }
772
773 static int add_tracepoint_fields_types(struct ctf_writer *cw,
774                                        struct format_field *fields,
775                                        struct bt_ctf_event_class *event_class)
776 {
777         struct format_field *field;
778         int ret;
779
780         for (field = fields; field; field = field->next) {
781                 struct bt_ctf_field_type *type;
782                 unsigned long flags = field->flags;
783
784                 pr2("  field '%s'\n", field->name);
785
786                 type = get_tracepoint_field_type(cw, field);
787                 if (!type)
788                         return -1;
789
790                 /*
791                  * A string is an array of chars. For this we use the string
792                  * type and don't care that it is an array. What we don't
793                  * support is an array of strings.
794                  */
795                 if (flags & FIELD_IS_STRING)
796                         flags &= ~FIELD_IS_ARRAY;
797
798                 if (flags & FIELD_IS_ARRAY)
799                         type = bt_ctf_field_type_array_create(type, field->arraylen);
800
801                 ret = event_class_add_field(event_class, type, field);
802
803                 if (flags & FIELD_IS_ARRAY)
804                         bt_ctf_field_type_put(type);
805
806                 if (ret) {
807                         pr_err("Failed to add field '%s': %d\n",
808                                         field->name, ret);
809                         return -1;
810                 }
811         }
812
813         return 0;
814 }
815
816 static int add_tracepoint_types(struct ctf_writer *cw,
817                                 struct perf_evsel *evsel,
818                                 struct bt_ctf_event_class *class)
819 {
820         struct format_field *common_fields = evsel->tp_format->format.common_fields;
821         struct format_field *fields        = evsel->tp_format->format.fields;
822         int ret;
823
824         ret = add_tracepoint_fields_types(cw, common_fields, class);
825         if (!ret)
826                 ret = add_tracepoint_fields_types(cw, fields, class);
827
828         return ret;
829 }
830
831 static int add_bpf_output_types(struct ctf_writer *cw,
832                                 struct bt_ctf_event_class *class)
833 {
834         struct bt_ctf_field_type *len_type = cw->data.u32;
835         struct bt_ctf_field_type *seq_base_type = cw->data.u32_hex;
836         struct bt_ctf_field_type *seq_type;
837         int ret;
838
839         ret = bt_ctf_event_class_add_field(class, len_type, "raw_len");
840         if (ret)
841                 return ret;
842
843         seq_type = bt_ctf_field_type_sequence_create(seq_base_type, "raw_len");
844         if (!seq_type)
845                 return -1;
846
847         return bt_ctf_event_class_add_field(class, seq_type, "raw_data");
848 }
849
850 static int add_generic_types(struct ctf_writer *cw, struct perf_evsel *evsel,
851                              struct bt_ctf_event_class *event_class)
852 {
853         u64 type = evsel->attr.sample_type;
854
855         /*
856          * missing:
857          *   PERF_SAMPLE_TIME         - not needed as we have it in
858          *                              ctf event header
859          *   PERF_SAMPLE_READ         - TODO
860          *   PERF_SAMPLE_CALLCHAIN    - TODO
861          *   PERF_SAMPLE_RAW          - tracepoint fields and BPF output
862          *                              are handled separately
863          *   PERF_SAMPLE_BRANCH_STACK - TODO
864          *   PERF_SAMPLE_REGS_USER    - TODO
865          *   PERF_SAMPLE_STACK_USER   - TODO
866          */
867
868 #define ADD_FIELD(cl, t, n)                                             \
869         do {                                                            \
870                 pr2("  field '%s'\n", n);                               \
871                 if (bt_ctf_event_class_add_field(cl, t, n)) {           \
872                         pr_err("Failed to add field '%s';\n", n);       \
873                         return -1;                                      \
874                 }                                                       \
875         } while (0)
876
877         if (type & PERF_SAMPLE_IP)
878                 ADD_FIELD(event_class, cw->data.u64_hex, "perf_ip");
879
880         if (type & PERF_SAMPLE_TID) {
881                 ADD_FIELD(event_class, cw->data.s32, "perf_tid");
882                 ADD_FIELD(event_class, cw->data.s32, "perf_pid");
883         }
884
885         if ((type & PERF_SAMPLE_ID) ||
886             (type & PERF_SAMPLE_IDENTIFIER))
887                 ADD_FIELD(event_class, cw->data.u64, "perf_id");
888
889         if (type & PERF_SAMPLE_STREAM_ID)
890                 ADD_FIELD(event_class, cw->data.u64, "perf_stream_id");
891
892         if (type & PERF_SAMPLE_PERIOD)
893                 ADD_FIELD(event_class, cw->data.u64, "perf_period");
894
895         if (type & PERF_SAMPLE_WEIGHT)
896                 ADD_FIELD(event_class, cw->data.u64, "perf_weight");
897
898         if (type & PERF_SAMPLE_DATA_SRC)
899                 ADD_FIELD(event_class, cw->data.u64, "perf_data_src");
900
901         if (type & PERF_SAMPLE_TRANSACTION)
902                 ADD_FIELD(event_class, cw->data.u64, "perf_transaction");
903
904 #undef ADD_FIELD
905         return 0;
906 }
907
908 static int add_event(struct ctf_writer *cw, struct perf_evsel *evsel)
909 {
910         struct bt_ctf_event_class *event_class;
911         struct evsel_priv *priv;
912         const char *name = perf_evsel__name(evsel);
913         int ret;
914
915         pr("Adding event '%s' (type %d)\n", name, evsel->attr.type);
916
917         event_class = bt_ctf_event_class_create(name);
918         if (!event_class)
919                 return -1;
920
921         ret = add_generic_types(cw, evsel, event_class);
922         if (ret)
923                 goto err;
924
925         if (evsel->attr.type == PERF_TYPE_TRACEPOINT) {
926                 ret = add_tracepoint_types(cw, evsel, event_class);
927                 if (ret)
928                         goto err;
929         }
930
931         if (perf_evsel__is_bpf_output(evsel)) {
932                 ret = add_bpf_output_types(cw, event_class);
933                 if (ret)
934                         goto err;
935         }
936
937         ret = bt_ctf_stream_class_add_event_class(cw->stream_class, event_class);
938         if (ret) {
939                 pr("Failed to add event class into stream.\n");
940                 goto err;
941         }
942
943         priv = malloc(sizeof(*priv));
944         if (!priv)
945                 goto err;
946
947         priv->event_class = event_class;
948         evsel->priv       = priv;
949         return 0;
950
951 err:
952         bt_ctf_event_class_put(event_class);
953         pr_err("Failed to add event '%s'.\n", name);
954         return -1;
955 }
956
957 static int setup_events(struct ctf_writer *cw, struct perf_session *session)
958 {
959         struct perf_evlist *evlist = session->evlist;
960         struct perf_evsel *evsel;
961         int ret;
962
963         evlist__for_each(evlist, evsel) {
964                 ret = add_event(cw, evsel);
965                 if (ret)
966                         return ret;
967         }
968         return 0;
969 }
970
971 static void cleanup_events(struct perf_session *session)
972 {
973         struct perf_evlist *evlist = session->evlist;
974         struct perf_evsel *evsel;
975
976         evlist__for_each(evlist, evsel) {
977                 struct evsel_priv *priv;
978
979                 priv = evsel->priv;
980                 bt_ctf_event_class_put(priv->event_class);
981                 zfree(&evsel->priv);
982         }
983
984         perf_evlist__delete(evlist);
985         session->evlist = NULL;
986 }
987
988 static int setup_streams(struct ctf_writer *cw, struct perf_session *session)
989 {
990         struct ctf_stream **stream;
991         struct perf_header *ph = &session->header;
992         int ncpus;
993
994         /*
995          * Try to get the number of cpus used in the data file,
996          * if not present fallback to the MAX_CPUS.
997          */
998         ncpus = ph->env.nr_cpus_avail ?: MAX_CPUS;
999
1000         stream = zalloc(sizeof(*stream) * ncpus);
1001         if (!stream) {
1002                 pr_err("Failed to allocate streams.\n");
1003                 return -ENOMEM;
1004         }
1005
1006         cw->stream     = stream;
1007         cw->stream_cnt = ncpus;
1008         return 0;
1009 }
1010
1011 static void free_streams(struct ctf_writer *cw)
1012 {
1013         int cpu;
1014
1015         for (cpu = 0; cpu < cw->stream_cnt; cpu++)
1016                 ctf_stream__delete(cw->stream[cpu]);
1017
1018         free(cw->stream);
1019 }
1020
1021 static int ctf_writer__setup_env(struct ctf_writer *cw,
1022                                  struct perf_session *session)
1023 {
1024         struct perf_header *header = &session->header;
1025         struct bt_ctf_writer *writer = cw->writer;
1026
1027 #define ADD(__n, __v)                                                   \
1028 do {                                                                    \
1029         if (bt_ctf_writer_add_environment_field(writer, __n, __v))      \
1030                 return -1;                                              \
1031 } while (0)
1032
1033         ADD("host",    header->env.hostname);
1034         ADD("sysname", "Linux");
1035         ADD("release", header->env.os_release);
1036         ADD("version", header->env.version);
1037         ADD("machine", header->env.arch);
1038         ADD("domain", "kernel");
1039         ADD("tracer_name", "perf");
1040
1041 #undef ADD
1042         return 0;
1043 }
1044
1045 static int ctf_writer__setup_clock(struct ctf_writer *cw)
1046 {
1047         struct bt_ctf_clock *clock = cw->clock;
1048
1049         bt_ctf_clock_set_description(clock, "perf clock");
1050
1051 #define SET(__n, __v)                           \
1052 do {                                            \
1053         if (bt_ctf_clock_set_##__n(clock, __v)) \
1054                 return -1;                      \
1055 } while (0)
1056
1057         SET(frequency,   1000000000);
1058         SET(offset_s,    0);
1059         SET(offset,      0);
1060         SET(precision,   10);
1061         SET(is_absolute, 0);
1062
1063 #undef SET
1064         return 0;
1065 }
1066
1067 static struct bt_ctf_field_type *create_int_type(int size, bool sign, bool hex)
1068 {
1069         struct bt_ctf_field_type *type;
1070
1071         type = bt_ctf_field_type_integer_create(size);
1072         if (!type)
1073                 return NULL;
1074
1075         if (sign &&
1076             bt_ctf_field_type_integer_set_signed(type, 1))
1077                 goto err;
1078
1079         if (hex &&
1080             bt_ctf_field_type_integer_set_base(type, BT_CTF_INTEGER_BASE_HEXADECIMAL))
1081                 goto err;
1082
1083 #if __BYTE_ORDER == __BIG_ENDIAN
1084         bt_ctf_field_type_set_byte_order(type, BT_CTF_BYTE_ORDER_BIG_ENDIAN);
1085 #else
1086         bt_ctf_field_type_set_byte_order(type, BT_CTF_BYTE_ORDER_LITTLE_ENDIAN);
1087 #endif
1088
1089         pr2("Created type: INTEGER %d-bit %ssigned %s\n",
1090             size, sign ? "un" : "", hex ? "hex" : "");
1091         return type;
1092
1093 err:
1094         bt_ctf_field_type_put(type);
1095         return NULL;
1096 }
1097
1098 static void ctf_writer__cleanup_data(struct ctf_writer *cw)
1099 {
1100         unsigned int i;
1101
1102         for (i = 0; i < ARRAY_SIZE(cw->data.array); i++)
1103                 bt_ctf_field_type_put(cw->data.array[i]);
1104 }
1105
1106 static int ctf_writer__init_data(struct ctf_writer *cw)
1107 {
1108 #define CREATE_INT_TYPE(type, size, sign, hex)          \
1109 do {                                                    \
1110         (type) = create_int_type(size, sign, hex);      \
1111         if (!(type))                                    \
1112                 goto err;                               \
1113 } while (0)
1114
1115         CREATE_INT_TYPE(cw->data.s64, 64, true,  false);
1116         CREATE_INT_TYPE(cw->data.u64, 64, false, false);
1117         CREATE_INT_TYPE(cw->data.s32, 32, true,  false);
1118         CREATE_INT_TYPE(cw->data.u32, 32, false, false);
1119         CREATE_INT_TYPE(cw->data.u32_hex, 32, false, true);
1120         CREATE_INT_TYPE(cw->data.u64_hex, 64, false, true);
1121
1122         cw->data.string  = bt_ctf_field_type_string_create();
1123         if (cw->data.string)
1124                 return 0;
1125
1126 err:
1127         ctf_writer__cleanup_data(cw);
1128         pr_err("Failed to create data types.\n");
1129         return -1;
1130 }
1131
1132 static void ctf_writer__cleanup(struct ctf_writer *cw)
1133 {
1134         ctf_writer__cleanup_data(cw);
1135
1136         bt_ctf_clock_put(cw->clock);
1137         free_streams(cw);
1138         bt_ctf_stream_class_put(cw->stream_class);
1139         bt_ctf_writer_put(cw->writer);
1140
1141         /* and NULL all the pointers */
1142         memset(cw, 0, sizeof(*cw));
1143 }
1144
1145 static int ctf_writer__init(struct ctf_writer *cw, const char *path)
1146 {
1147         struct bt_ctf_writer            *writer;
1148         struct bt_ctf_stream_class      *stream_class;
1149         struct bt_ctf_clock             *clock;
1150         struct bt_ctf_field_type        *pkt_ctx_type;
1151         int                             ret;
1152
1153         /* CTF writer */
1154         writer = bt_ctf_writer_create(path);
1155         if (!writer)
1156                 goto err;
1157
1158         cw->writer = writer;
1159
1160         /* CTF clock */
1161         clock = bt_ctf_clock_create("perf_clock");
1162         if (!clock) {
1163                 pr("Failed to create CTF clock.\n");
1164                 goto err_cleanup;
1165         }
1166
1167         cw->clock = clock;
1168
1169         if (ctf_writer__setup_clock(cw)) {
1170                 pr("Failed to setup CTF clock.\n");
1171                 goto err_cleanup;
1172         }
1173
1174         /* CTF stream class */
1175         stream_class = bt_ctf_stream_class_create("perf_stream");
1176         if (!stream_class) {
1177                 pr("Failed to create CTF stream class.\n");
1178                 goto err_cleanup;
1179         }
1180
1181         cw->stream_class = stream_class;
1182
1183         /* CTF clock stream setup */
1184         if (bt_ctf_stream_class_set_clock(stream_class, clock)) {
1185                 pr("Failed to assign CTF clock to stream class.\n");
1186                 goto err_cleanup;
1187         }
1188
1189         if (ctf_writer__init_data(cw))
1190                 goto err_cleanup;
1191
1192         /* Add cpu_id for packet context */
1193         pkt_ctx_type = bt_ctf_stream_class_get_packet_context_type(stream_class);
1194         if (!pkt_ctx_type)
1195                 goto err_cleanup;
1196
1197         ret = bt_ctf_field_type_structure_add_field(pkt_ctx_type, cw->data.u32, "cpu_id");
1198         bt_ctf_field_type_put(pkt_ctx_type);
1199         if (ret)
1200                 goto err_cleanup;
1201
1202         /* CTF clock writer setup */
1203         if (bt_ctf_writer_add_clock(writer, clock)) {
1204                 pr("Failed to assign CTF clock to writer.\n");
1205                 goto err_cleanup;
1206         }
1207
1208         return 0;
1209
1210 err_cleanup:
1211         ctf_writer__cleanup(cw);
1212 err:
1213         pr_err("Failed to setup CTF writer.\n");
1214         return -1;
1215 }
1216
1217 static int ctf_writer__flush_streams(struct ctf_writer *cw)
1218 {
1219         int cpu, ret = 0;
1220
1221         for (cpu = 0; cpu < cw->stream_cnt && !ret; cpu++)
1222                 ret = ctf_stream__flush(cw->stream[cpu]);
1223
1224         return ret;
1225 }
1226
1227 static int convert__config(const char *var, const char *value, void *cb)
1228 {
1229         struct convert *c = cb;
1230
1231         if (!strcmp(var, "convert.queue-size")) {
1232                 c->queue_size = perf_config_u64(var, value);
1233                 return 0;
1234         }
1235
1236         return 0;
1237 }
1238
1239 int bt_convert__perf2ctf(const char *input, const char *path, bool force)
1240 {
1241         struct perf_session *session;
1242         struct perf_data_file file = {
1243                 .path = input,
1244                 .mode = PERF_DATA_MODE_READ,
1245                 .force = force,
1246         };
1247         struct convert c = {
1248                 .tool = {
1249                         .sample          = process_sample_event,
1250                         .mmap            = perf_event__process_mmap,
1251                         .mmap2           = perf_event__process_mmap2,
1252                         .comm            = perf_event__process_comm,
1253                         .exit            = perf_event__process_exit,
1254                         .fork            = perf_event__process_fork,
1255                         .lost            = perf_event__process_lost,
1256                         .tracing_data    = perf_event__process_tracing_data,
1257                         .build_id        = perf_event__process_build_id,
1258                         .ordered_events  = true,
1259                         .ordering_requires_timestamps = true,
1260                 },
1261         };
1262         struct ctf_writer *cw = &c.writer;
1263         int err = -1;
1264
1265         perf_config(convert__config, &c);
1266
1267         /* CTF writer */
1268         if (ctf_writer__init(cw, path))
1269                 return -1;
1270
1271         /* perf.data session */
1272         session = perf_session__new(&file, 0, &c.tool);
1273         if (!session)
1274                 goto free_writer;
1275
1276         if (c.queue_size) {
1277                 ordered_events__set_alloc_size(&session->ordered_events,
1278                                                c.queue_size);
1279         }
1280
1281         /* CTF writer env/clock setup  */
1282         if (ctf_writer__setup_env(cw, session))
1283                 goto free_session;
1284
1285         /* CTF events setup */
1286         if (setup_events(cw, session))
1287                 goto free_session;
1288
1289         if (setup_streams(cw, session))
1290                 goto free_session;
1291
1292         err = perf_session__process_events(session);
1293         if (!err)
1294                 err = ctf_writer__flush_streams(cw);
1295         else
1296                 pr_err("Error during conversion.\n");
1297
1298         fprintf(stderr,
1299                 "[ perf data convert: Converted '%s' into CTF data '%s' ]\n",
1300                 file.path, path);
1301
1302         fprintf(stderr,
1303                 "[ perf data convert: Converted and wrote %.3f MB (%" PRIu64 " samples) ]\n",
1304                 (double) c.events_size / 1024.0 / 1024.0,
1305                 c.events_count);
1306
1307         cleanup_events(session);
1308         perf_session__delete(session);
1309         ctf_writer__cleanup(cw);
1310
1311         return err;
1312
1313 free_session:
1314         perf_session__delete(session);
1315 free_writer:
1316         ctf_writer__cleanup(cw);
1317         pr_err("Error during conversion setup.\n");
1318         return err;
1319 }