hc
2023-12-09 b22da3d8526a935aa31e086e63f60ff3246cb61c
kernel/tools/perf/util/data-convert-bt.c
....@@ -1,16 +1,16 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * CTF writing support via babeltrace.
34 *
45 * Copyright (C) 2014, Jiri Olsa <jolsa@redhat.com>
56 * Copyright (C) 2014, Sebastian Andrzej Siewior <bigeasy@linutronix.de>
6
- *
7
- * Released under the GPL v2. (and only v2, not any later version)
87 */
98
109 #include <errno.h>
1110 #include <inttypes.h>
1211 #include <linux/compiler.h>
1312 #include <linux/kernel.h>
13
+#include <linux/zalloc.h>
1414 #include <babeltrace/ctf-writer/writer.h>
1515 #include <babeltrace/ctf-writer/clock.h>
1616 #include <babeltrace/ctf-writer/stream.h>
....@@ -23,14 +23,17 @@
2323 #include "asm/bug.h"
2424 #include "data-convert-bt.h"
2525 #include "session.h"
26
-#include "util.h"
2726 #include "debug.h"
2827 #include "tool.h"
2928 #include "evlist.h"
3029 #include "evsel.h"
3130 #include "machine.h"
3231 #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"
3437
3538 #define pr_N(n, fmt, ...) \
3639 eprintf(n, debug_data_convert, fmt, ##__VA_ARGS__)
....@@ -182,20 +185,20 @@
182185 }
183186
184187 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)
186189 {
187190 unsigned long flags = field->flags;
188191
189
- if (flags & FIELD_IS_STRING)
192
+ if (flags & TEP_FIELD_IS_STRING)
190193 return cw->data.string;
191194
192
- if (!(flags & FIELD_IS_SIGNED)) {
195
+ if (!(flags & TEP_FIELD_IS_SIGNED)) {
193196 /* 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)
195198 return cw->data.u64_hex;
196199 }
197200
198
- if (flags & FIELD_IS_SIGNED) {
201
+ if (flags & TEP_FIELD_IS_SIGNED) {
199202 if (field->size == 8)
200203 return cw->data.s64;
201204 else
....@@ -287,7 +290,7 @@
287290 struct bt_ctf_event_class *event_class,
288291 struct bt_ctf_event *event,
289292 struct perf_sample *sample,
290
- struct format_field *fmtf)
293
+ struct tep_format_field *fmtf)
291294 {
292295 struct bt_ctf_field_type *type;
293296 struct bt_ctf_field *array_field;
....@@ -304,20 +307,20 @@
304307 name = fmtf->alias;
305308 offset = fmtf->offset;
306309 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;
309312
310
- if (flags & FIELD_IS_DYNAMIC) {
313
+ if (flags & TEP_FIELD_IS_DYNAMIC) {
311314 unsigned long long tmp_val;
312315
313
- tmp_val = tep_read_number(fmtf->event->pevent,
316
+ tmp_val = tep_read_number(fmtf->event->tep,
314317 data + offset, len);
315318 offset = tmp_val;
316319 len = offset >> 16;
317320 offset &= 0xffff;
318321 }
319322
320
- if (flags & FIELD_IS_ARRAY) {
323
+ if (flags & TEP_FIELD_IS_ARRAY) {
321324
322325 type = bt_ctf_event_class_get_field_by_name(
323326 event_class, name);
....@@ -338,7 +341,7 @@
338341 type = get_tracepoint_field_type(cw, fmtf);
339342
340343 for (i = 0; i < n_items; i++) {
341
- if (flags & FIELD_IS_ARRAY)
344
+ if (flags & TEP_FIELD_IS_ARRAY)
342345 field = bt_ctf_field_array_get_field(array_field, i);
343346 else
344347 field = bt_ctf_field_create(type);
....@@ -348,16 +351,16 @@
348351 return -1;
349352 }
350353
351
- if (flags & FIELD_IS_STRING)
354
+ if (flags & TEP_FIELD_IS_STRING)
352355 ret = string_set_value(field, data + offset + i * len);
353356 else {
354357 unsigned long long value_int;
355358
356359 value_int = tep_read_number(
357
- fmtf->event->pevent,
360
+ fmtf->event->tep,
358361 data + offset + i * len, len);
359362
360
- if (!(flags & FIELD_IS_SIGNED))
363
+ if (!(flags & TEP_FIELD_IS_SIGNED))
361364 ret = bt_ctf_field_unsigned_integer_set_value(
362365 field, value_int);
363366 else
....@@ -369,7 +372,7 @@
369372 pr_err("failed to set file value %s\n", name);
370373 goto err_put_field;
371374 }
372
- if (!(flags & FIELD_IS_ARRAY)) {
375
+ if (!(flags & TEP_FIELD_IS_ARRAY)) {
373376 ret = bt_ctf_event_set_payload(event, name, field);
374377 if (ret) {
375378 pr_err("failed to set payload %s\n", name);
....@@ -378,7 +381,7 @@
378381 }
379382 bt_ctf_field_put(field);
380383 }
381
- if (flags & FIELD_IS_ARRAY) {
384
+ if (flags & TEP_FIELD_IS_ARRAY) {
382385 ret = bt_ctf_event_set_payload(event, name, array_field);
383386 if (ret) {
384387 pr_err("Failed add payload array %s\n", name);
....@@ -396,10 +399,10 @@
396399 static int add_tracepoint_fields_values(struct ctf_writer *cw,
397400 struct bt_ctf_event_class *event_class,
398401 struct bt_ctf_event *event,
399
- struct format_field *fields,
402
+ struct tep_format_field *fields,
400403 struct perf_sample *sample)
401404 {
402
- struct format_field *field;
405
+ struct tep_format_field *field;
403406 int ret;
404407
405408 for (field = fields; field; field = field->next) {
....@@ -414,11 +417,11 @@
414417 static int add_tracepoint_values(struct ctf_writer *cw,
415418 struct bt_ctf_event_class *event_class,
416419 struct bt_ctf_event *event,
417
- struct perf_evsel *evsel,
420
+ struct evsel *evsel,
418421 struct perf_sample *sample)
419422 {
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;
422425 int ret;
423426
424427 ret = add_tracepoint_fields_values(cw, event_class, event,
....@@ -585,10 +588,10 @@
585588
586589 static int add_generic_values(struct ctf_writer *cw,
587590 struct bt_ctf_event *event,
588
- struct perf_evsel *evsel,
591
+ struct evsel *evsel,
589592 struct perf_sample *sample)
590593 {
591
- u64 type = evsel->attr.sample_type;
594
+ u64 type = evsel->core.attr.sample_type;
592595 int ret;
593596
594597 /*
....@@ -754,11 +757,11 @@
754757 }
755758
756759 static int get_sample_cpu(struct ctf_writer *cw, struct perf_sample *sample,
757
- struct perf_evsel *evsel)
760
+ struct evsel *evsel)
758761 {
759762 int cpu = 0;
760763
761
- if (evsel->attr.sample_type & PERF_SAMPLE_CPU)
764
+ if (evsel->core.attr.sample_type & PERF_SAMPLE_CPU)
762765 cpu = sample->cpu;
763766
764767 if (cpu > cw->stream_cnt) {
....@@ -786,7 +789,7 @@
786789 static int process_sample_event(struct perf_tool *tool,
787790 union perf_event *_event,
788791 struct perf_sample *sample,
789
- struct perf_evsel *evsel,
792
+ struct evsel *evsel,
790793 struct machine *machine __maybe_unused)
791794 {
792795 struct convert *c = container_of(tool, struct convert, tool);
....@@ -796,7 +799,7 @@
796799 struct bt_ctf_event_class *event_class;
797800 struct bt_ctf_event *event;
798801 int ret;
799
- unsigned long type = evsel->attr.sample_type;
802
+ unsigned long type = evsel->core.attr.sample_type;
800803
801804 if (WARN_ONCE(!priv, "Failed to setup all events.\n"))
802805 return 0;
....@@ -821,7 +824,7 @@
821824 if (ret)
822825 return -1;
823826
824
- if (evsel->attr.type == PERF_TYPE_TRACEPOINT) {
827
+ if (evsel->core.attr.type == PERF_TYPE_TRACEPOINT) {
825828 ret = add_tracepoint_values(cw, event_class, event,
826829 evsel, sample);
827830 if (ret)
....@@ -835,7 +838,7 @@
835838 return -1;
836839 }
837840
838
- if (perf_evsel__is_bpf_output(evsel)) {
841
+ if (evsel__is_bpf_output(evsel)) {
839842 ret = add_bpf_output_values(event_class, event, sample);
840843 if (ret)
841844 return -1;
....@@ -970,7 +973,7 @@
970973
971974 static int event_class_add_field(struct bt_ctf_event_class *event_class,
972975 struct bt_ctf_field_type *type,
973
- struct format_field *field)
976
+ struct tep_format_field *field)
974977 {
975978 struct bt_ctf_field_type *t = NULL;
976979 char *name;
....@@ -1009,10 +1012,10 @@
10091012 }
10101013
10111014 static int add_tracepoint_fields_types(struct ctf_writer *cw,
1012
- struct format_field *fields,
1015
+ struct tep_format_field *fields,
10131016 struct bt_ctf_event_class *event_class)
10141017 {
1015
- struct format_field *field;
1018
+ struct tep_format_field *field;
10161019 int ret;
10171020
10181021 for (field = fields; field; field = field->next) {
....@@ -1030,15 +1033,15 @@
10301033 * type and don't care that it is an array. What we don't
10311034 * support is an array of strings.
10321035 */
1033
- if (flags & FIELD_IS_STRING)
1034
- flags &= ~FIELD_IS_ARRAY;
1036
+ if (flags & TEP_FIELD_IS_STRING)
1037
+ flags &= ~TEP_FIELD_IS_ARRAY;
10351038
1036
- if (flags & FIELD_IS_ARRAY)
1039
+ if (flags & TEP_FIELD_IS_ARRAY)
10371040 type = bt_ctf_field_type_array_create(type, field->arraylen);
10381041
10391042 ret = event_class_add_field(event_class, type, field);
10401043
1041
- if (flags & FIELD_IS_ARRAY)
1044
+ if (flags & TEP_FIELD_IS_ARRAY)
10421045 bt_ctf_field_type_put(type);
10431046
10441047 if (ret) {
....@@ -1052,11 +1055,11 @@
10521055 }
10531056
10541057 static int add_tracepoint_types(struct ctf_writer *cw,
1055
- struct perf_evsel *evsel,
1058
+ struct evsel *evsel,
10561059 struct bt_ctf_event_class *class)
10571060 {
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;
10601063 int ret;
10611064
10621065 ret = add_tracepoint_fields_types(cw, common_fields, class);
....@@ -1085,10 +1088,10 @@
10851088 return bt_ctf_event_class_add_field(class, seq_type, "raw_data");
10861089 }
10871090
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,
10891092 struct bt_ctf_event_class *event_class)
10901093 {
1091
- u64 type = evsel->attr.sample_type;
1094
+ u64 type = evsel->core.attr.sample_type;
10921095
10931096 /*
10941097 * missing:
....@@ -1151,14 +1154,14 @@
11511154 return 0;
11521155 }
11531156
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)
11551158 {
11561159 struct bt_ctf_event_class *event_class;
11571160 struct evsel_priv *priv;
1158
- const char *name = perf_evsel__name(evsel);
1161
+ const char *name = evsel__name(evsel);
11591162 int ret;
11601163
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);
11621165
11631166 event_class = bt_ctf_event_class_create(name);
11641167 if (!event_class)
....@@ -1168,13 +1171,13 @@
11681171 if (ret)
11691172 goto err;
11701173
1171
- if (evsel->attr.type == PERF_TYPE_TRACEPOINT) {
1174
+ if (evsel->core.attr.type == PERF_TYPE_TRACEPOINT) {
11721175 ret = add_tracepoint_types(cw, evsel, event_class);
11731176 if (ret)
11741177 goto err;
11751178 }
11761179
1177
- if (perf_evsel__is_bpf_output(evsel)) {
1180
+ if (evsel__is_bpf_output(evsel)) {
11781181 ret = add_bpf_output_types(cw, event_class);
11791182 if (ret)
11801183 goto err;
....@@ -1202,8 +1205,8 @@
12021205
12031206 static int setup_events(struct ctf_writer *cw, struct perf_session *session)
12041207 {
1205
- struct perf_evlist *evlist = session->evlist;
1206
- struct perf_evsel *evsel;
1208
+ struct evlist *evlist = session->evlist;
1209
+ struct evsel *evsel;
12071210 int ret;
12081211
12091212 evlist__for_each_entry(evlist, evsel) {
....@@ -1309,8 +1312,8 @@
13091312
13101313 static void cleanup_events(struct perf_session *session)
13111314 {
1312
- struct perf_evlist *evlist = session->evlist;
1313
- struct perf_evsel *evsel;
1315
+ struct evlist *evlist = session->evlist;
1316
+ struct evsel *evsel;
13141317
13151318 evlist__for_each_entry(evlist, evsel) {
13161319 struct evsel_priv *priv;
....@@ -1320,7 +1323,7 @@
13201323 zfree(&evsel->priv);
13211324 }
13221325
1323
- perf_evlist__delete(evlist);
1326
+ evlist__delete(evlist);
13241327 session->evlist = NULL;
13251328 }
13261329
....@@ -1354,7 +1357,7 @@
13541357 for (cpu = 0; cpu < cw->stream_cnt; cpu++)
13551358 ctf_stream__delete(cw->stream[cpu]);
13561359
1357
- free(cw->stream);
1360
+ zfree(&cw->stream);
13581361 }
13591362
13601363 static int ctf_writer__setup_env(struct ctf_writer *cw,
....@@ -1381,11 +1384,26 @@
13811384 return 0;
13821385 }
13831386
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)
13851390 {
13861391 struct bt_ctf_clock *clock = cw->clock;
1392
+ const char *desc = "perf clock";
1393
+ int64_t offset = 0;
13871394
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
+ }
13891407
13901408 #define SET(__n, __v) \
13911409 do { \
....@@ -1394,8 +1412,8 @@
13941412 } while (0)
13951413
13961414 SET(frequency, 1000000000);
1397
- SET(offset_s, 0);
1398
- SET(offset, 0);
1415
+ SET(offset, offset);
1416
+ SET(description, desc);
13991417 SET(precision, 10);
14001418 SET(is_absolute, 0);
14011419
....@@ -1481,7 +1499,8 @@
14811499 memset(cw, 0, sizeof(*cw));
14821500 }
14831501
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)
14851504 {
14861505 struct bt_ctf_writer *writer;
14871506 struct bt_ctf_stream_class *stream_class;
....@@ -1505,7 +1524,7 @@
15051524
15061525 cw->clock = clock;
15071526
1508
- if (ctf_writer__setup_clock(cw)) {
1527
+ if (ctf_writer__setup_clock(cw, session, tod)) {
15091528 pr("Failed to setup CTF clock.\n");
15101529 goto err_cleanup;
15111530 }
....@@ -1578,7 +1597,7 @@
15781597 {
15791598 struct perf_session *session;
15801599 struct perf_data data = {
1581
- .file.path = input,
1600
+ .path = input,
15821601 .mode = PERF_DATA_MODE_READ,
15831602 .force = opts->force,
15841603 };
....@@ -1613,15 +1632,15 @@
16131632 if (err)
16141633 return err;
16151634
1616
- /* CTF writer */
1617
- if (ctf_writer__init(cw, path))
1618
- return -1;
1619
-
16201635 err = -1;
16211636 /* perf.data session */
16221637 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;
16251644
16261645 if (c.queue_size) {
16271646 ordered_events__set_alloc_size(&session->ordered_events,
....@@ -1630,17 +1649,17 @@
16301649
16311650 /* CTF writer env/clock setup */
16321651 if (ctf_writer__setup_env(cw, session))
1633
- goto free_session;
1652
+ goto free_writer;
16341653
16351654 /* CTF events setup */
16361655 if (setup_events(cw, session))
1637
- goto free_session;
1656
+ goto free_writer;
16381657
16391658 if (opts->all && setup_non_sample_events(cw, session))
1640
- goto free_session;
1659
+ goto free_writer;
16411660
16421661 if (setup_streams(cw, session))
1643
- goto free_session;
1662
+ goto free_writer;
16441663
16451664 err = perf_session__process_events(session);
16461665 if (!err)
....@@ -1650,7 +1669,7 @@
16501669
16511670 fprintf(stderr,
16521671 "[ perf data convert: Converted '%s' into CTF data '%s' ]\n",
1653
- data.file.path, path);
1672
+ data.path, path);
16541673
16551674 fprintf(stderr,
16561675 "[ perf data convert: Converted and wrote %.3f MB (%" PRIu64 " samples",
....@@ -1668,10 +1687,10 @@
16681687
16691688 return err;
16701689
1671
-free_session:
1672
- perf_session__delete(session);
16731690 free_writer:
16741691 ctf_writer__cleanup(cw);
1692
+free_session:
1693
+ perf_session__delete(session);
16751694 pr_err("Error during conversion setup.\n");
16761695 return err;
16771696 }