linux/tools/perf/util/data-convert-bt.c
<<
>>
Prefs
   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 <babeltrace/ctf-writer/writer.h>
  14#include <babeltrace/ctf-writer/clock.h>
  15#include <babeltrace/ctf-writer/stream.h>
  16#include <babeltrace/ctf-writer/event.h>
  17#include <babeltrace/ctf-writer/event-types.h>
  18#include <babeltrace/ctf-writer/event-fields.h>
  19#include <babeltrace/ctf-ir/utils.h>
  20#include <babeltrace/ctf/events.h>
  21#include <traceevent/event-parse.h>
  22#include "asm/bug.h"
  23#include "data-convert-bt.h"
  24#include "session.h"
  25#include "util.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 "sane_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
  42struct evsel_priv {
  43        struct bt_ctf_event_class *event_class;
  44};
  45
  46#define MAX_CPUS        4096
  47
  48struct ctf_stream {
  49        struct bt_ctf_stream *stream;
  50        int cpu;
  51        u32 count;
  52};
  53
  54struct 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
  82struct 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
  94static 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
 130err:
 131        bt_ctf_field_put(field);
 132        return ret;
 133}
 134
 135#define __FUNC_VALUE_SET(_name, _val_type)                              \
 136static __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
 147FUNC_VALUE_SET(s32)
 148FUNC_VALUE_SET(u32)
 149FUNC_VALUE_SET(s64)
 150FUNC_VALUE_SET(u64)
 151__FUNC_VALUE_SET(u64_hex, u64)
 152
 153static int string_set_value(struct bt_ctf_field *field, const char *string);
 154static __maybe_unused int
 155value_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
 178err_put_field:
 179        bt_ctf_field_put(field);
 180        return ret;
 181}
 182
 183static struct bt_ctf_field_type*
 184get_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
 210static 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
 247static 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
 285static 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
 390err_put_field:
 391        bt_ctf_field_put(field);
 392        return -1;
 393}
 394
 395static 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
 413static 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
 432static int
 433add_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
 499put_seq_field:
 500        bt_ctf_field_put(seq_field);
 501put_seq_type:
 502        bt_ctf_field_type_put(seq_type);
 503put_len_field:
 504        bt_ctf_field_put(len_field);
 505put_len_type:
 506        bt_ctf_field_type_put(len_type);
 507        return ret;
 508}
 509
 510static int
 511add_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
 574put_seq_field:
 575        bt_ctf_field_put(seq_field);
 576put_seq_type:
 577        bt_ctf_field_type_put(seq_type);
 578put_len_field:
 579        bt_ctf_field_put(len_field);
 580put_len_type:
 581        bt_ctf_field_type_put(len_type);
 582        return ret;
 583}
 584
 585static 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
 662static 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
 680static 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
 725out:
 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
 735static 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
 743static 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
 755static 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 */
 780static bool is_flush_needed(struct ctf_stream *cs)
 781{
 782        return cs->count >= STREAM_FLUSH_COUNT;
 783}
 784
 785static 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)    \
 857do {                                                    \
 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)  \
 864static 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. */
 935static 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
 964out:
 965        if (name != orig_name)
 966                free(name);
 967        return new_name;
 968}
 969
 970static 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
1010static 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
1053static 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
1068static 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
1087static 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
1153static 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
1196err:
1197        bt_ctf_event_class_put(event_class);
1198        pr_err("Failed to add event '%s'.\n", name);
1199        return -1;
1200}
1201
1202static 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)          \
1226static 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
1286static 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
1309static 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
1326static 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
1349static 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        free(cw->stream);
1357}
1358
1359static 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)                                                   \
1366do {                                                                    \
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
1383static 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)                           \
1390do {                                            \
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
1405static 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
1431err:
1432        bt_ctf_field_type_put(type);
1433        return NULL;
1434}
1435
1436static 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
1444static int ctf_writer__init_data(struct ctf_writer *cw)
1445{
1446#define CREATE_INT_TYPE(type, size, sign, hex)          \
1447do {                                                    \
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
1464err:
1465        ctf_writer__cleanup_data(cw);
1466        pr_err("Failed to create data types.\n");
1467        return -1;
1468}
1469
1470static 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
1483static 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
1548err_cleanup:
1549        ctf_writer__cleanup(cw);
1550err:
1551        pr_err("Failed to setup CTF writer.\n");
1552        return -1;
1553}
1554
1555static 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
1565static 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
1575int 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
1670free_session:
1671        perf_session__delete(session);
1672free_writer:
1673        ctf_writer__cleanup(cw);
1674        pr_err("Error during conversion setup.\n");
1675        return err;
1676}
1677