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