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