Lines Matching +full:convert +full:- +full:sample +full:- +full:format
1 // SPDX-License-Identifier: GPL-2.0-only
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>
23 #include "data-convert.h"
36 #include "util/sample.h"
39 #include <event-parse.h>
90 struct convert {
113 return -1;
149 struct bt_ctf_field_type *type = cw->data._name; \
166 struct bt_ctf_field_type *type = cw->data.string;
173 return -1;
194 unsigned long flags = field->flags;
197 return cw->data.string;
202 return cw->data.u64_hex;
206 if (field->size == 8)
207 return cw->data.s64;
209 return cw->data.s32;
212 if (field->size == 8)
213 return cw->data.u64;
215 return cw->data.u32;
223 * value_mask = (1 << (size * 8 - 1)) - 1.
248 if ((value_int & (~0ULL - value_mask)) == 0)
273 buffer = zalloc(i + (len - i) * 4 + 2);
276 return bt_ctf_field_string_set_value(field, "UNPRINTABLE-STRING");
296 struct perf_sample *sample,
302 const char *name = fmtf->name;
303 void *data = sample->raw_data;
304 unsigned long flags = fmtf->flags;
311 name = fmtf->alias;
312 offset = fmtf->offset;
313 len = fmtf->size;
320 tmp_val = tep_read_number(fmtf->event->tep,
326 offset += fmtf->offset + fmtf->size;
337 return -1;
340 len = fmtf->size / fmtf->arraylen;
341 n_items = fmtf->arraylen;
357 return -1;
366 fmtf->event->tep,
394 return -1;
402 return -1;
409 struct perf_sample *sample)
414 for (field = fields; field; field = field->next) {
415 ret = add_tracepoint_field_value(cw, event_class, event, sample,
418 return -1;
427 struct perf_sample *sample)
429 struct tep_format_field *common_fields = evsel->tp_format->format.common_fields;
430 struct tep_format_field *fields = evsel->tp_format->format.fields;
434 common_fields, sample);
437 fields, sample);
445 struct perf_sample *sample)
449 unsigned int raw_size = sample->raw_size;
456 raw_size, nr_elements * sizeof(u32) - raw_size);
462 ret = -1;
481 ret = -1;
496 ((u32 *)(sample->raw_data))[i]);
527 unsigned int nr_elements = callchain->nr;
536 ret = -1;
556 ret = -1;
571 ((u64 *)(callchain->ips))[i]);
598 struct perf_sample *sample)
600 u64 type = evsel->core.attr.sample_type;
605 * PERF_SAMPLE_TIME - not needed as we have it in
607 * PERF_SAMPLE_READ - TODO
608 * PERF_SAMPLE_RAW - tracepoint fields are handled separately
609 * PERF_SAMPLE_BRANCH_STACK - TODO
610 * PERF_SAMPLE_REGS_USER - TODO
611 * PERF_SAMPLE_STACK_USER - TODO
615 ret = value_set_u64_hex(cw, event, "perf_ip", sample->ip);
617 return -1;
621 ret = value_set_s32(cw, event, "perf_tid", sample->tid);
623 return -1;
625 ret = value_set_s32(cw, event, "perf_pid", sample->pid);
627 return -1;
632 ret = value_set_u64(cw, event, "perf_id", sample->id);
634 return -1;
638 ret = value_set_u64(cw, event, "perf_stream_id", sample->stream_id);
640 return -1;
644 ret = value_set_u64(cw, event, "perf_period", sample->period);
646 return -1;
650 ret = value_set_u64(cw, event, "perf_weight", sample->weight);
652 return -1;
657 sample->data_src);
659 return -1;
664 sample->transaction);
666 return -1;
677 err = bt_ctf_stream_flush(cs->stream);
679 pr_err("CTF stream %d flush failed\n", cs->cpu);
682 cs->cpu, cs->count);
684 cs->count = 0;
704 stream = bt_ctf_writer_create_stream(cw->writer, cw->stream_class);
731 cs->cpu = cpu;
732 cs->stream = stream;
748 bt_ctf_stream_put(cs->stream);
755 struct ctf_stream *cs = cw->stream[cpu];
759 cw->stream[cpu] = cs;
765 static int get_sample_cpu(struct ctf_writer *cw, struct perf_sample *sample,
770 if (evsel->core.attr.sample_type & PERF_SAMPLE_CPU)
771 cpu = sample->cpu;
773 if (cpu > cw->stream_cnt) {
775 cpu, cw->stream_cnt);
792 return cs->count >= STREAM_FLUSH_COUNT;
797 struct perf_sample *sample,
801 struct convert *c = container_of(tool, struct convert, tool);
802 struct evsel_priv *priv = evsel->priv;
803 struct ctf_writer *cw = &c->writer;
808 unsigned long type = evsel->core.attr.sample_type;
813 event_class = priv->event_class;
816 c->events_count++;
817 c->events_size += _event->header.size;
819 pr_time2(sample->time, "sample %" PRIu64 "\n", c->events_count);
824 return -1;
827 bt_ctf_clock_set_time(cw->clock, sample->time);
829 ret = add_generic_values(cw, event, evsel, sample);
831 return -1;
833 if (evsel->core.attr.type == PERF_TYPE_TRACEPOINT) {
835 evsel, sample);
837 return -1;
842 event, sample->callchain);
844 return -1;
848 ret = add_bpf_output_values(event_class, event, sample);
850 return -1;
853 cs = ctf_stream(cw, get_sample_cpu(cw, sample, evsel));
858 cs->count++;
859 bt_ctf_stream_append_event(cs->stream, event);
863 return cs ? 0 : -1;
868 ret = value_set_##_type(cw, event, #_field, _event->_name._field);\
870 return -1; \
876 struct perf_sample *sample, \
879 struct convert *c = container_of(tool, struct convert, tool);\
880 struct ctf_writer *cw = &c->writer; \
881 struct bt_ctf_event_class *event_class = cw->_name##_class;\
886 c->non_sample_count++; \
887 c->events_size += _event->header.size; \
891 return -1; \
894 bt_ctf_clock_set_time(cw->clock, sample->time); \
901 cs->count++; \
902 bt_ctf_stream_append_event(cs->stream, event); \
906 return perf_event__process_##_name(tool, _event, sample, machine);\
990 if (field->alias != field->name)
992 (char *)field->alias);
994 name = field->name;
998 name = change_name(name, field->name, -1);
1002 return -1;
1006 name = change_name(name, field->name, dup++);
1008 pr_err("Failed to create dup name for '%s'\n", field->name);
1009 return -1;
1015 field->alias = name;
1027 for (field = fields; field; field = field->next) {
1029 unsigned long flags = field->flags;
1031 pr2(" field '%s'\n", field->name);
1035 return -1;
1046 type = bt_ctf_field_type_array_create(type, field->arraylen);
1055 field->name, ret);
1056 return -1;
1067 struct tep_format_field *common_fields = evsel->tp_format->format.common_fields;
1068 struct tep_format_field *fields = evsel->tp_format->format.fields;
1081 struct bt_ctf_field_type *len_type = cw->data.u32;
1082 struct bt_ctf_field_type *seq_base_type = cw->data.u32_hex;
1092 return -1;
1100 u64 type = evsel->core.attr.sample_type;
1104 * PERF_SAMPLE_TIME - not needed as we have it in
1106 * PERF_SAMPLE_READ - TODO
1107 * PERF_SAMPLE_CALLCHAIN - TODO
1108 * PERF_SAMPLE_RAW - tracepoint fields and BPF output
1110 * PERF_SAMPLE_BRANCH_STACK - TODO
1111 * PERF_SAMPLE_REGS_USER - TODO
1112 * PERF_SAMPLE_STACK_USER - TODO
1120 return -1; \
1125 ADD_FIELD(event_class, cw->data.u64_hex, "perf_ip");
1128 ADD_FIELD(event_class, cw->data.s32, "perf_tid");
1129 ADD_FIELD(event_class, cw->data.s32, "perf_pid");
1134 ADD_FIELD(event_class, cw->data.u64, "perf_id");
1137 ADD_FIELD(event_class, cw->data.u64, "perf_stream_id");
1140 ADD_FIELD(event_class, cw->data.u64, "perf_period");
1143 ADD_FIELD(event_class, cw->data.u64, "perf_weight");
1146 ADD_FIELD(event_class, cw->data.u64, "perf_data_src");
1149 ADD_FIELD(event_class, cw->data.u64, "perf_transaction");
1152 ADD_FIELD(event_class, cw->data.u32, "perf_callchain_size");
1155 cw->data.u64_hex, "perf_callchain_size"),
1170 pr("Adding event '%s' (type %d)\n", name, evsel->core.attr.type);
1174 return -1;
1180 if (evsel->core.attr.type == PERF_TYPE_TRACEPOINT) {
1192 ret = bt_ctf_stream_class_add_event_class(cw->stream_class, event_class);
1202 priv->event_class = event_class;
1203 evsel->priv = priv;
1209 return -1;
1214 struct evlist *evlist = session->evlist;
1229 if (bt_ctf_event_class_add_field(event_class, cw->data.t, #n)) {\
1231 return -1; \
1244 return -1; \
1247 ret = bt_ctf_stream_class_add_event_class(cw->stream_class, event_class);\
1253 cw->_name##_class = event_class; \
1321 struct evlist *evlist = session->evlist;
1327 priv = evsel->priv;
1328 bt_ctf_event_class_put(priv->event_class);
1329 zfree(&evsel->priv);
1333 session->evlist = NULL;
1339 struct perf_header *ph = &session->header;
1346 ncpus = ph->env.nr_cpus_avail ?: MAX_CPUS;
1351 return -ENOMEM;
1354 cw->stream = stream;
1355 cw->stream_cnt = ncpus;
1363 for (cpu = 0; cpu < cw->stream_cnt; cpu++)
1364 ctf_stream__delete(cw->stream[cpu]);
1366 zfree(&cw->stream);
1372 struct perf_header *header = &session->header;
1373 struct bt_ctf_writer *writer = cw->writer;
1378 return -1; \
1381 ADD("host", header->env.hostname);
1383 ADD("release", header->env.os_release);
1384 ADD("version", header->env.version);
1385 ADD("machine", header->env.arch);
1397 struct bt_ctf_clock *clock = cw->clock;
1402 struct perf_env *env = &session->header.env;
1404 if (!env->clock.enabled) {
1405 pr_err("Can't provide --tod time, missing clock data. "
1406 "Please record with -k/--clockid option.\n");
1407 return -1;
1410 desc = clockid_name(env->clock.clockid);
1411 offset = env->clock.tod_ns - env->clock.clockid_ns;
1417 return -1; \
1452 pr2("Created type: INTEGER %d-bit %ssigned %s\n",
1465 for (i = 0; i < ARRAY_SIZE(cw->data.array); i++)
1466 bt_ctf_field_type_put(cw->data.array[i]);
1478 CREATE_INT_TYPE(cw->data.s64, 64, true, false);
1479 CREATE_INT_TYPE(cw->data.u64, 64, false, false);
1480 CREATE_INT_TYPE(cw->data.s32, 32, true, false);
1481 CREATE_INT_TYPE(cw->data.u32, 32, false, false);
1482 CREATE_INT_TYPE(cw->data.u32_hex, 32, false, true);
1483 CREATE_INT_TYPE(cw->data.u64_hex, 64, false, true);
1485 cw->data.string = bt_ctf_field_type_string_create();
1486 if (cw->data.string)
1492 return -1;
1499 bt_ctf_clock_put(cw->clock);
1501 bt_ctf_stream_class_put(cw->stream_class);
1502 bt_ctf_writer_put(cw->writer);
1522 cw->writer = writer;
1531 cw->clock = clock;
1545 cw->stream_class = stream_class;
1561 ret = bt_ctf_field_type_structure_add_field(pkt_ctx_type, cw->data.u32, "cpu_id");
1578 return -1;
1585 for (cpu = 0; cpu < cw->stream_cnt && !ret; cpu++)
1586 ret = ctf_stream__flush(cw->stream[cpu]);
1593 struct convert *c = cb;
1595 if (!strcmp(var, "convert.queue-size"))
1596 return perf_config_u64(&c->queue_size, var, value);
1608 .force = opts->force,
1610 struct convert c = {};
1615 c.tool.sample = process_sample_event;
1627 if (opts->all) {
1639 err = -1;
1646 if (ctf_writer__init(cw, path, session, opts->tod))
1650 ordered_events__set_alloc_size(&session->ordered_events,
1662 if (opts->all && setup_non_sample_events(cw, session))
1675 "[ perf data convert: Converted '%s' into CTF data '%s' ]\n",
1679 "[ perf data convert: Converted and wrote %.3f MB (%" PRIu64 " samples",
1686 fprintf(stderr, ", %" PRIu64 " non-samples) ]\n", c.non_sample_count);