.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * CTF writing support via babeltrace. |
---|
3 | 4 | * |
---|
4 | 5 | * Copyright (C) 2014, Jiri Olsa <jolsa@redhat.com> |
---|
5 | 6 | * Copyright (C) 2014, Sebastian Andrzej Siewior <bigeasy@linutronix.de> |
---|
6 | | - * |
---|
7 | | - * Released under the GPL v2. (and only v2, not any later version) |
---|
8 | 7 | */ |
---|
9 | 8 | |
---|
10 | 9 | #include <errno.h> |
---|
11 | 10 | #include <inttypes.h> |
---|
12 | 11 | #include <linux/compiler.h> |
---|
13 | 12 | #include <linux/kernel.h> |
---|
| 13 | +#include <linux/zalloc.h> |
---|
14 | 14 | #include <babeltrace/ctf-writer/writer.h> |
---|
15 | 15 | #include <babeltrace/ctf-writer/clock.h> |
---|
16 | 16 | #include <babeltrace/ctf-writer/stream.h> |
---|
.. | .. |
---|
23 | 23 | #include "asm/bug.h" |
---|
24 | 24 | #include "data-convert-bt.h" |
---|
25 | 25 | #include "session.h" |
---|
26 | | -#include "util.h" |
---|
27 | 26 | #include "debug.h" |
---|
28 | 27 | #include "tool.h" |
---|
29 | 28 | #include "evlist.h" |
---|
30 | 29 | #include "evsel.h" |
---|
31 | 30 | #include "machine.h" |
---|
32 | 31 | #include "config.h" |
---|
33 | | -#include "sane_ctype.h" |
---|
| 32 | +#include <linux/ctype.h> |
---|
| 33 | +#include <linux/err.h> |
---|
| 34 | +#include <linux/time64.h> |
---|
| 35 | +#include "util.h" |
---|
| 36 | +#include "clockid.h" |
---|
34 | 37 | |
---|
35 | 38 | #define pr_N(n, fmt, ...) \ |
---|
36 | 39 | eprintf(n, debug_data_convert, fmt, ##__VA_ARGS__) |
---|
.. | .. |
---|
182 | 185 | } |
---|
183 | 186 | |
---|
184 | 187 | static struct bt_ctf_field_type* |
---|
185 | | -get_tracepoint_field_type(struct ctf_writer *cw, struct format_field *field) |
---|
| 188 | +get_tracepoint_field_type(struct ctf_writer *cw, struct tep_format_field *field) |
---|
186 | 189 | { |
---|
187 | 190 | unsigned long flags = field->flags; |
---|
188 | 191 | |
---|
189 | | - if (flags & FIELD_IS_STRING) |
---|
| 192 | + if (flags & TEP_FIELD_IS_STRING) |
---|
190 | 193 | return cw->data.string; |
---|
191 | 194 | |
---|
192 | | - if (!(flags & FIELD_IS_SIGNED)) { |
---|
| 195 | + if (!(flags & TEP_FIELD_IS_SIGNED)) { |
---|
193 | 196 | /* unsigned long are mostly pointers */ |
---|
194 | | - if (flags & FIELD_IS_LONG || flags & FIELD_IS_POINTER) |
---|
| 197 | + if (flags & TEP_FIELD_IS_LONG || flags & TEP_FIELD_IS_POINTER) |
---|
195 | 198 | return cw->data.u64_hex; |
---|
196 | 199 | } |
---|
197 | 200 | |
---|
198 | | - if (flags & FIELD_IS_SIGNED) { |
---|
| 201 | + if (flags & TEP_FIELD_IS_SIGNED) { |
---|
199 | 202 | if (field->size == 8) |
---|
200 | 203 | return cw->data.s64; |
---|
201 | 204 | else |
---|
.. | .. |
---|
287 | 290 | struct bt_ctf_event_class *event_class, |
---|
288 | 291 | struct bt_ctf_event *event, |
---|
289 | 292 | struct perf_sample *sample, |
---|
290 | | - struct format_field *fmtf) |
---|
| 293 | + struct tep_format_field *fmtf) |
---|
291 | 294 | { |
---|
292 | 295 | struct bt_ctf_field_type *type; |
---|
293 | 296 | struct bt_ctf_field *array_field; |
---|
.. | .. |
---|
304 | 307 | name = fmtf->alias; |
---|
305 | 308 | offset = fmtf->offset; |
---|
306 | 309 | len = fmtf->size; |
---|
307 | | - if (flags & FIELD_IS_STRING) |
---|
308 | | - flags &= ~FIELD_IS_ARRAY; |
---|
| 310 | + if (flags & TEP_FIELD_IS_STRING) |
---|
| 311 | + flags &= ~TEP_FIELD_IS_ARRAY; |
---|
309 | 312 | |
---|
310 | | - if (flags & FIELD_IS_DYNAMIC) { |
---|
| 313 | + if (flags & TEP_FIELD_IS_DYNAMIC) { |
---|
311 | 314 | unsigned long long tmp_val; |
---|
312 | 315 | |
---|
313 | | - tmp_val = tep_read_number(fmtf->event->pevent, |
---|
| 316 | + tmp_val = tep_read_number(fmtf->event->tep, |
---|
314 | 317 | data + offset, len); |
---|
315 | 318 | offset = tmp_val; |
---|
316 | 319 | len = offset >> 16; |
---|
317 | 320 | offset &= 0xffff; |
---|
318 | 321 | } |
---|
319 | 322 | |
---|
320 | | - if (flags & FIELD_IS_ARRAY) { |
---|
| 323 | + if (flags & TEP_FIELD_IS_ARRAY) { |
---|
321 | 324 | |
---|
322 | 325 | type = bt_ctf_event_class_get_field_by_name( |
---|
323 | 326 | event_class, name); |
---|
.. | .. |
---|
338 | 341 | type = get_tracepoint_field_type(cw, fmtf); |
---|
339 | 342 | |
---|
340 | 343 | for (i = 0; i < n_items; i++) { |
---|
341 | | - if (flags & FIELD_IS_ARRAY) |
---|
| 344 | + if (flags & TEP_FIELD_IS_ARRAY) |
---|
342 | 345 | field = bt_ctf_field_array_get_field(array_field, i); |
---|
343 | 346 | else |
---|
344 | 347 | field = bt_ctf_field_create(type); |
---|
.. | .. |
---|
348 | 351 | return -1; |
---|
349 | 352 | } |
---|
350 | 353 | |
---|
351 | | - if (flags & FIELD_IS_STRING) |
---|
| 354 | + if (flags & TEP_FIELD_IS_STRING) |
---|
352 | 355 | ret = string_set_value(field, data + offset + i * len); |
---|
353 | 356 | else { |
---|
354 | 357 | unsigned long long value_int; |
---|
355 | 358 | |
---|
356 | 359 | value_int = tep_read_number( |
---|
357 | | - fmtf->event->pevent, |
---|
| 360 | + fmtf->event->tep, |
---|
358 | 361 | data + offset + i * len, len); |
---|
359 | 362 | |
---|
360 | | - if (!(flags & FIELD_IS_SIGNED)) |
---|
| 363 | + if (!(flags & TEP_FIELD_IS_SIGNED)) |
---|
361 | 364 | ret = bt_ctf_field_unsigned_integer_set_value( |
---|
362 | 365 | field, value_int); |
---|
363 | 366 | else |
---|
.. | .. |
---|
369 | 372 | pr_err("failed to set file value %s\n", name); |
---|
370 | 373 | goto err_put_field; |
---|
371 | 374 | } |
---|
372 | | - if (!(flags & FIELD_IS_ARRAY)) { |
---|
| 375 | + if (!(flags & TEP_FIELD_IS_ARRAY)) { |
---|
373 | 376 | ret = bt_ctf_event_set_payload(event, name, field); |
---|
374 | 377 | if (ret) { |
---|
375 | 378 | pr_err("failed to set payload %s\n", name); |
---|
.. | .. |
---|
378 | 381 | } |
---|
379 | 382 | bt_ctf_field_put(field); |
---|
380 | 383 | } |
---|
381 | | - if (flags & FIELD_IS_ARRAY) { |
---|
| 384 | + if (flags & TEP_FIELD_IS_ARRAY) { |
---|
382 | 385 | ret = bt_ctf_event_set_payload(event, name, array_field); |
---|
383 | 386 | if (ret) { |
---|
384 | 387 | pr_err("Failed add payload array %s\n", name); |
---|
.. | .. |
---|
396 | 399 | static int add_tracepoint_fields_values(struct ctf_writer *cw, |
---|
397 | 400 | struct bt_ctf_event_class *event_class, |
---|
398 | 401 | struct bt_ctf_event *event, |
---|
399 | | - struct format_field *fields, |
---|
| 402 | + struct tep_format_field *fields, |
---|
400 | 403 | struct perf_sample *sample) |
---|
401 | 404 | { |
---|
402 | | - struct format_field *field; |
---|
| 405 | + struct tep_format_field *field; |
---|
403 | 406 | int ret; |
---|
404 | 407 | |
---|
405 | 408 | for (field = fields; field; field = field->next) { |
---|
.. | .. |
---|
414 | 417 | static int add_tracepoint_values(struct ctf_writer *cw, |
---|
415 | 418 | struct bt_ctf_event_class *event_class, |
---|
416 | 419 | struct bt_ctf_event *event, |
---|
417 | | - struct perf_evsel *evsel, |
---|
| 420 | + struct evsel *evsel, |
---|
418 | 421 | struct perf_sample *sample) |
---|
419 | 422 | { |
---|
420 | | - struct format_field *common_fields = evsel->tp_format->format.common_fields; |
---|
421 | | - struct format_field *fields = evsel->tp_format->format.fields; |
---|
| 423 | + struct tep_format_field *common_fields = evsel->tp_format->format.common_fields; |
---|
| 424 | + struct tep_format_field *fields = evsel->tp_format->format.fields; |
---|
422 | 425 | int ret; |
---|
423 | 426 | |
---|
424 | 427 | ret = add_tracepoint_fields_values(cw, event_class, event, |
---|
.. | .. |
---|
585 | 588 | |
---|
586 | 589 | static int add_generic_values(struct ctf_writer *cw, |
---|
587 | 590 | struct bt_ctf_event *event, |
---|
588 | | - struct perf_evsel *evsel, |
---|
| 591 | + struct evsel *evsel, |
---|
589 | 592 | struct perf_sample *sample) |
---|
590 | 593 | { |
---|
591 | | - u64 type = evsel->attr.sample_type; |
---|
| 594 | + u64 type = evsel->core.attr.sample_type; |
---|
592 | 595 | int ret; |
---|
593 | 596 | |
---|
594 | 597 | /* |
---|
.. | .. |
---|
754 | 757 | } |
---|
755 | 758 | |
---|
756 | 759 | static int get_sample_cpu(struct ctf_writer *cw, struct perf_sample *sample, |
---|
757 | | - struct perf_evsel *evsel) |
---|
| 760 | + struct evsel *evsel) |
---|
758 | 761 | { |
---|
759 | 762 | int cpu = 0; |
---|
760 | 763 | |
---|
761 | | - if (evsel->attr.sample_type & PERF_SAMPLE_CPU) |
---|
| 764 | + if (evsel->core.attr.sample_type & PERF_SAMPLE_CPU) |
---|
762 | 765 | cpu = sample->cpu; |
---|
763 | 766 | |
---|
764 | 767 | if (cpu > cw->stream_cnt) { |
---|
.. | .. |
---|
786 | 789 | static int process_sample_event(struct perf_tool *tool, |
---|
787 | 790 | union perf_event *_event, |
---|
788 | 791 | struct perf_sample *sample, |
---|
789 | | - struct perf_evsel *evsel, |
---|
| 792 | + struct evsel *evsel, |
---|
790 | 793 | struct machine *machine __maybe_unused) |
---|
791 | 794 | { |
---|
792 | 795 | struct convert *c = container_of(tool, struct convert, tool); |
---|
.. | .. |
---|
796 | 799 | struct bt_ctf_event_class *event_class; |
---|
797 | 800 | struct bt_ctf_event *event; |
---|
798 | 801 | int ret; |
---|
799 | | - unsigned long type = evsel->attr.sample_type; |
---|
| 802 | + unsigned long type = evsel->core.attr.sample_type; |
---|
800 | 803 | |
---|
801 | 804 | if (WARN_ONCE(!priv, "Failed to setup all events.\n")) |
---|
802 | 805 | return 0; |
---|
.. | .. |
---|
821 | 824 | if (ret) |
---|
822 | 825 | return -1; |
---|
823 | 826 | |
---|
824 | | - if (evsel->attr.type == PERF_TYPE_TRACEPOINT) { |
---|
| 827 | + if (evsel->core.attr.type == PERF_TYPE_TRACEPOINT) { |
---|
825 | 828 | ret = add_tracepoint_values(cw, event_class, event, |
---|
826 | 829 | evsel, sample); |
---|
827 | 830 | if (ret) |
---|
.. | .. |
---|
835 | 838 | return -1; |
---|
836 | 839 | } |
---|
837 | 840 | |
---|
838 | | - if (perf_evsel__is_bpf_output(evsel)) { |
---|
| 841 | + if (evsel__is_bpf_output(evsel)) { |
---|
839 | 842 | ret = add_bpf_output_values(event_class, event, sample); |
---|
840 | 843 | if (ret) |
---|
841 | 844 | return -1; |
---|
.. | .. |
---|
970 | 973 | |
---|
971 | 974 | static int event_class_add_field(struct bt_ctf_event_class *event_class, |
---|
972 | 975 | struct bt_ctf_field_type *type, |
---|
973 | | - struct format_field *field) |
---|
| 976 | + struct tep_format_field *field) |
---|
974 | 977 | { |
---|
975 | 978 | struct bt_ctf_field_type *t = NULL; |
---|
976 | 979 | char *name; |
---|
.. | .. |
---|
1009 | 1012 | } |
---|
1010 | 1013 | |
---|
1011 | 1014 | static int add_tracepoint_fields_types(struct ctf_writer *cw, |
---|
1012 | | - struct format_field *fields, |
---|
| 1015 | + struct tep_format_field *fields, |
---|
1013 | 1016 | struct bt_ctf_event_class *event_class) |
---|
1014 | 1017 | { |
---|
1015 | | - struct format_field *field; |
---|
| 1018 | + struct tep_format_field *field; |
---|
1016 | 1019 | int ret; |
---|
1017 | 1020 | |
---|
1018 | 1021 | for (field = fields; field; field = field->next) { |
---|
.. | .. |
---|
1030 | 1033 | * type and don't care that it is an array. What we don't |
---|
1031 | 1034 | * support is an array of strings. |
---|
1032 | 1035 | */ |
---|
1033 | | - if (flags & FIELD_IS_STRING) |
---|
1034 | | - flags &= ~FIELD_IS_ARRAY; |
---|
| 1036 | + if (flags & TEP_FIELD_IS_STRING) |
---|
| 1037 | + flags &= ~TEP_FIELD_IS_ARRAY; |
---|
1035 | 1038 | |
---|
1036 | | - if (flags & FIELD_IS_ARRAY) |
---|
| 1039 | + if (flags & TEP_FIELD_IS_ARRAY) |
---|
1037 | 1040 | type = bt_ctf_field_type_array_create(type, field->arraylen); |
---|
1038 | 1041 | |
---|
1039 | 1042 | ret = event_class_add_field(event_class, type, field); |
---|
1040 | 1043 | |
---|
1041 | | - if (flags & FIELD_IS_ARRAY) |
---|
| 1044 | + if (flags & TEP_FIELD_IS_ARRAY) |
---|
1042 | 1045 | bt_ctf_field_type_put(type); |
---|
1043 | 1046 | |
---|
1044 | 1047 | if (ret) { |
---|
.. | .. |
---|
1052 | 1055 | } |
---|
1053 | 1056 | |
---|
1054 | 1057 | static int add_tracepoint_types(struct ctf_writer *cw, |
---|
1055 | | - struct perf_evsel *evsel, |
---|
| 1058 | + struct evsel *evsel, |
---|
1056 | 1059 | struct bt_ctf_event_class *class) |
---|
1057 | 1060 | { |
---|
1058 | | - struct format_field *common_fields = evsel->tp_format->format.common_fields; |
---|
1059 | | - struct format_field *fields = evsel->tp_format->format.fields; |
---|
| 1061 | + struct tep_format_field *common_fields = evsel->tp_format->format.common_fields; |
---|
| 1062 | + struct tep_format_field *fields = evsel->tp_format->format.fields; |
---|
1060 | 1063 | int ret; |
---|
1061 | 1064 | |
---|
1062 | 1065 | ret = add_tracepoint_fields_types(cw, common_fields, class); |
---|
.. | .. |
---|
1085 | 1088 | return bt_ctf_event_class_add_field(class, seq_type, "raw_data"); |
---|
1086 | 1089 | } |
---|
1087 | 1090 | |
---|
1088 | | -static int add_generic_types(struct ctf_writer *cw, struct perf_evsel *evsel, |
---|
| 1091 | +static int add_generic_types(struct ctf_writer *cw, struct evsel *evsel, |
---|
1089 | 1092 | struct bt_ctf_event_class *event_class) |
---|
1090 | 1093 | { |
---|
1091 | | - u64 type = evsel->attr.sample_type; |
---|
| 1094 | + u64 type = evsel->core.attr.sample_type; |
---|
1092 | 1095 | |
---|
1093 | 1096 | /* |
---|
1094 | 1097 | * missing: |
---|
.. | .. |
---|
1151 | 1154 | return 0; |
---|
1152 | 1155 | } |
---|
1153 | 1156 | |
---|
1154 | | -static int add_event(struct ctf_writer *cw, struct perf_evsel *evsel) |
---|
| 1157 | +static int add_event(struct ctf_writer *cw, struct evsel *evsel) |
---|
1155 | 1158 | { |
---|
1156 | 1159 | struct bt_ctf_event_class *event_class; |
---|
1157 | 1160 | struct evsel_priv *priv; |
---|
1158 | | - const char *name = perf_evsel__name(evsel); |
---|
| 1161 | + const char *name = evsel__name(evsel); |
---|
1159 | 1162 | int ret; |
---|
1160 | 1163 | |
---|
1161 | | - pr("Adding event '%s' (type %d)\n", name, evsel->attr.type); |
---|
| 1164 | + pr("Adding event '%s' (type %d)\n", name, evsel->core.attr.type); |
---|
1162 | 1165 | |
---|
1163 | 1166 | event_class = bt_ctf_event_class_create(name); |
---|
1164 | 1167 | if (!event_class) |
---|
.. | .. |
---|
1168 | 1171 | if (ret) |
---|
1169 | 1172 | goto err; |
---|
1170 | 1173 | |
---|
1171 | | - if (evsel->attr.type == PERF_TYPE_TRACEPOINT) { |
---|
| 1174 | + if (evsel->core.attr.type == PERF_TYPE_TRACEPOINT) { |
---|
1172 | 1175 | ret = add_tracepoint_types(cw, evsel, event_class); |
---|
1173 | 1176 | if (ret) |
---|
1174 | 1177 | goto err; |
---|
1175 | 1178 | } |
---|
1176 | 1179 | |
---|
1177 | | - if (perf_evsel__is_bpf_output(evsel)) { |
---|
| 1180 | + if (evsel__is_bpf_output(evsel)) { |
---|
1178 | 1181 | ret = add_bpf_output_types(cw, event_class); |
---|
1179 | 1182 | if (ret) |
---|
1180 | 1183 | goto err; |
---|
.. | .. |
---|
1202 | 1205 | |
---|
1203 | 1206 | static int setup_events(struct ctf_writer *cw, struct perf_session *session) |
---|
1204 | 1207 | { |
---|
1205 | | - struct perf_evlist *evlist = session->evlist; |
---|
1206 | | - struct perf_evsel *evsel; |
---|
| 1208 | + struct evlist *evlist = session->evlist; |
---|
| 1209 | + struct evsel *evsel; |
---|
1207 | 1210 | int ret; |
---|
1208 | 1211 | |
---|
1209 | 1212 | evlist__for_each_entry(evlist, evsel) { |
---|
.. | .. |
---|
1309 | 1312 | |
---|
1310 | 1313 | static void cleanup_events(struct perf_session *session) |
---|
1311 | 1314 | { |
---|
1312 | | - struct perf_evlist *evlist = session->evlist; |
---|
1313 | | - struct perf_evsel *evsel; |
---|
| 1315 | + struct evlist *evlist = session->evlist; |
---|
| 1316 | + struct evsel *evsel; |
---|
1314 | 1317 | |
---|
1315 | 1318 | evlist__for_each_entry(evlist, evsel) { |
---|
1316 | 1319 | struct evsel_priv *priv; |
---|
.. | .. |
---|
1320 | 1323 | zfree(&evsel->priv); |
---|
1321 | 1324 | } |
---|
1322 | 1325 | |
---|
1323 | | - perf_evlist__delete(evlist); |
---|
| 1326 | + evlist__delete(evlist); |
---|
1324 | 1327 | session->evlist = NULL; |
---|
1325 | 1328 | } |
---|
1326 | 1329 | |
---|
.. | .. |
---|
1354 | 1357 | for (cpu = 0; cpu < cw->stream_cnt; cpu++) |
---|
1355 | 1358 | ctf_stream__delete(cw->stream[cpu]); |
---|
1356 | 1359 | |
---|
1357 | | - free(cw->stream); |
---|
| 1360 | + zfree(&cw->stream); |
---|
1358 | 1361 | } |
---|
1359 | 1362 | |
---|
1360 | 1363 | static int ctf_writer__setup_env(struct ctf_writer *cw, |
---|
.. | .. |
---|
1381 | 1384 | return 0; |
---|
1382 | 1385 | } |
---|
1383 | 1386 | |
---|
1384 | | -static int ctf_writer__setup_clock(struct ctf_writer *cw) |
---|
| 1387 | +static int ctf_writer__setup_clock(struct ctf_writer *cw, |
---|
| 1388 | + struct perf_session *session, |
---|
| 1389 | + bool tod) |
---|
1385 | 1390 | { |
---|
1386 | 1391 | struct bt_ctf_clock *clock = cw->clock; |
---|
| 1392 | + const char *desc = "perf clock"; |
---|
| 1393 | + int64_t offset = 0; |
---|
1387 | 1394 | |
---|
1388 | | - bt_ctf_clock_set_description(clock, "perf clock"); |
---|
| 1395 | + if (tod) { |
---|
| 1396 | + struct perf_env *env = &session->header.env; |
---|
| 1397 | + |
---|
| 1398 | + if (!env->clock.enabled) { |
---|
| 1399 | + pr_err("Can't provide --tod time, missing clock data. " |
---|
| 1400 | + "Please record with -k/--clockid option.\n"); |
---|
| 1401 | + return -1; |
---|
| 1402 | + } |
---|
| 1403 | + |
---|
| 1404 | + desc = clockid_name(env->clock.clockid); |
---|
| 1405 | + offset = env->clock.tod_ns - env->clock.clockid_ns; |
---|
| 1406 | + } |
---|
1389 | 1407 | |
---|
1390 | 1408 | #define SET(__n, __v) \ |
---|
1391 | 1409 | do { \ |
---|
.. | .. |
---|
1394 | 1412 | } while (0) |
---|
1395 | 1413 | |
---|
1396 | 1414 | SET(frequency, 1000000000); |
---|
1397 | | - SET(offset_s, 0); |
---|
1398 | | - SET(offset, 0); |
---|
| 1415 | + SET(offset, offset); |
---|
| 1416 | + SET(description, desc); |
---|
1399 | 1417 | SET(precision, 10); |
---|
1400 | 1418 | SET(is_absolute, 0); |
---|
1401 | 1419 | |
---|
.. | .. |
---|
1481 | 1499 | memset(cw, 0, sizeof(*cw)); |
---|
1482 | 1500 | } |
---|
1483 | 1501 | |
---|
1484 | | -static int ctf_writer__init(struct ctf_writer *cw, const char *path) |
---|
| 1502 | +static int ctf_writer__init(struct ctf_writer *cw, const char *path, |
---|
| 1503 | + struct perf_session *session, bool tod) |
---|
1485 | 1504 | { |
---|
1486 | 1505 | struct bt_ctf_writer *writer; |
---|
1487 | 1506 | struct bt_ctf_stream_class *stream_class; |
---|
.. | .. |
---|
1505 | 1524 | |
---|
1506 | 1525 | cw->clock = clock; |
---|
1507 | 1526 | |
---|
1508 | | - if (ctf_writer__setup_clock(cw)) { |
---|
| 1527 | + if (ctf_writer__setup_clock(cw, session, tod)) { |
---|
1509 | 1528 | pr("Failed to setup CTF clock.\n"); |
---|
1510 | 1529 | goto err_cleanup; |
---|
1511 | 1530 | } |
---|
.. | .. |
---|
1578 | 1597 | { |
---|
1579 | 1598 | struct perf_session *session; |
---|
1580 | 1599 | struct perf_data data = { |
---|
1581 | | - .file.path = input, |
---|
| 1600 | + .path = input, |
---|
1582 | 1601 | .mode = PERF_DATA_MODE_READ, |
---|
1583 | 1602 | .force = opts->force, |
---|
1584 | 1603 | }; |
---|
.. | .. |
---|
1613 | 1632 | if (err) |
---|
1614 | 1633 | return err; |
---|
1615 | 1634 | |
---|
1616 | | - /* CTF writer */ |
---|
1617 | | - if (ctf_writer__init(cw, path)) |
---|
1618 | | - return -1; |
---|
1619 | | - |
---|
1620 | 1635 | err = -1; |
---|
1621 | 1636 | /* perf.data session */ |
---|
1622 | 1637 | session = perf_session__new(&data, 0, &c.tool); |
---|
1623 | | - if (!session) |
---|
1624 | | - goto free_writer; |
---|
| 1638 | + if (IS_ERR(session)) |
---|
| 1639 | + return PTR_ERR(session); |
---|
| 1640 | + |
---|
| 1641 | + /* CTF writer */ |
---|
| 1642 | + if (ctf_writer__init(cw, path, session, opts->tod)) |
---|
| 1643 | + goto free_session; |
---|
1625 | 1644 | |
---|
1626 | 1645 | if (c.queue_size) { |
---|
1627 | 1646 | ordered_events__set_alloc_size(&session->ordered_events, |
---|
.. | .. |
---|
1630 | 1649 | |
---|
1631 | 1650 | /* CTF writer env/clock setup */ |
---|
1632 | 1651 | if (ctf_writer__setup_env(cw, session)) |
---|
1633 | | - goto free_session; |
---|
| 1652 | + goto free_writer; |
---|
1634 | 1653 | |
---|
1635 | 1654 | /* CTF events setup */ |
---|
1636 | 1655 | if (setup_events(cw, session)) |
---|
1637 | | - goto free_session; |
---|
| 1656 | + goto free_writer; |
---|
1638 | 1657 | |
---|
1639 | 1658 | if (opts->all && setup_non_sample_events(cw, session)) |
---|
1640 | | - goto free_session; |
---|
| 1659 | + goto free_writer; |
---|
1641 | 1660 | |
---|
1642 | 1661 | if (setup_streams(cw, session)) |
---|
1643 | | - goto free_session; |
---|
| 1662 | + goto free_writer; |
---|
1644 | 1663 | |
---|
1645 | 1664 | err = perf_session__process_events(session); |
---|
1646 | 1665 | if (!err) |
---|
.. | .. |
---|
1650 | 1669 | |
---|
1651 | 1670 | fprintf(stderr, |
---|
1652 | 1671 | "[ perf data convert: Converted '%s' into CTF data '%s' ]\n", |
---|
1653 | | - data.file.path, path); |
---|
| 1672 | + data.path, path); |
---|
1654 | 1673 | |
---|
1655 | 1674 | fprintf(stderr, |
---|
1656 | 1675 | "[ perf data convert: Converted and wrote %.3f MB (%" PRIu64 " samples", |
---|
.. | .. |
---|
1668 | 1687 | |
---|
1669 | 1688 | return err; |
---|
1670 | 1689 | |
---|
1671 | | -free_session: |
---|
1672 | | - perf_session__delete(session); |
---|
1673 | 1690 | free_writer: |
---|
1674 | 1691 | ctf_writer__cleanup(cw); |
---|
| 1692 | +free_session: |
---|
| 1693 | + perf_session__delete(session); |
---|
1675 | 1694 | pr_err("Error during conversion setup.\n"); |
---|
1676 | 1695 | return err; |
---|
1677 | 1696 | } |
---|