summaryrefslogtreecommitdiff
path: root/tools/perf/util/data-convert-bt.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util/data-convert-bt.c')
-rw-r--r--tools/perf/util/data-convert-bt.c133
1 files changed, 78 insertions, 55 deletions
diff --git a/tools/perf/util/data-convert-bt.c b/tools/perf/util/data-convert-bt.c
index 5f36fc6a5578..3d2e437e1354 100644
--- a/tools/perf/util/data-convert-bt.c
+++ b/tools/perf/util/data-convert-bt.c
@@ -19,9 +19,8 @@
#include <babeltrace/ctf-writer/event-fields.h>
#include <babeltrace/ctf-ir/utils.h>
#include <babeltrace/ctf/events.h>
-#include <traceevent/event-parse.h>
#include "asm/bug.h"
-#include "data-convert-bt.h"
+#include "data-convert.h"
#include "session.h"
#include "debug.h"
#include "tool.h"
@@ -31,6 +30,14 @@
#include "config.h"
#include <linux/ctype.h>
#include <linux/err.h>
+#include <linux/time64.h>
+#include "util.h"
+#include "clockid.h"
+#include "util/sample.h"
+
+#ifdef HAVE_LIBTRACEEVENT
+#include <event-parse.h>
+#endif
#define pr_N(n, fmt, ...) \
eprintf(n, debug_data_convert, fmt, ##__VA_ARGS__)
@@ -315,6 +322,8 @@ static int add_tracepoint_field_value(struct ctf_writer *cw,
offset = tmp_val;
len = offset >> 16;
offset &= 0xffff;
+ if (tep_field_is_relative(flags))
+ offset += fmtf->offset + fmtf->size;
}
if (flags & TEP_FIELD_IS_ARRAY) {
@@ -417,8 +426,9 @@ static int add_tracepoint_values(struct ctf_writer *cw,
struct evsel *evsel,
struct perf_sample *sample)
{
- struct tep_format_field *common_fields = evsel->tp_format->format.common_fields;
- struct tep_format_field *fields = evsel->tp_format->format.fields;
+ const struct tep_event *tp_format = evsel__tp_format(evsel);
+ struct tep_format_field *common_fields = tp_format->format.common_fields;
+ struct tep_format_field *fields = tp_format->format.fields;
int ret;
ret = add_tracepoint_fields_values(cw, event_class, event,
@@ -783,7 +793,7 @@ static bool is_flush_needed(struct ctf_stream *cs)
return cs->count >= STREAM_FLUSH_COUNT;
}
-static int process_sample_event(struct perf_tool *tool,
+static int process_sample_event(const struct perf_tool *tool,
union perf_event *_event,
struct perf_sample *sample,
struct evsel *evsel,
@@ -862,7 +872,7 @@ do { \
} while(0)
#define __FUNC_PROCESS_NON_SAMPLE(_name, body) \
-static int process_##_name##_event(struct perf_tool *tool, \
+static int process_##_name##_event(const struct perf_tool *tool, \
union perf_event *_event, \
struct perf_sample *sample, \
struct machine *machine) \
@@ -945,8 +955,8 @@ static char *change_name(char *name, char *orig_name, int dup)
goto out;
/*
* Add '_' prefix to potential keywork. According to
- * Mathieu Desnoyers (https://lkml.org/lkml/2015/1/23/652),
- * futher CTF spec updating may require us to use '$'.
+ * Mathieu Desnoyers (https://lore.kernel.org/lkml/1074266107.40857.1422045946295.JavaMail.zimbra@efficios.com),
+ * further CTF spec updating may require us to use '$'.
*/
if (dup < 0)
len = strlen(name) + sizeof("_");
@@ -1055,8 +1065,9 @@ static int add_tracepoint_types(struct ctf_writer *cw,
struct evsel *evsel,
struct bt_ctf_event_class *class)
{
- struct tep_format_field *common_fields = evsel->tp_format->format.common_fields;
- struct tep_format_field *fields = evsel->tp_format->format.fields;
+ const struct tep_event *tp_format = evsel__tp_format(evsel);
+ struct tep_format_field *common_fields = tp_format ? tp_format->format.common_fields : NULL;
+ struct tep_format_field *fields = tp_format ? tp_format->format.fields : NULL;
int ret;
ret = add_tracepoint_fields_types(cw, common_fields, class);
@@ -1327,14 +1338,14 @@ static void cleanup_events(struct perf_session *session)
static int setup_streams(struct ctf_writer *cw, struct perf_session *session)
{
struct ctf_stream **stream;
- struct perf_header *ph = &session->header;
+ struct perf_env *env = perf_session__env(session);
int ncpus;
/*
* Try to get the number of cpus used in the data file,
* if not present fallback to the MAX_CPUS.
*/
- ncpus = ph->env.nr_cpus_avail ?: MAX_CPUS;
+ ncpus = env->nr_cpus_avail ?: MAX_CPUS;
stream = zalloc(sizeof(*stream) * ncpus);
if (!stream) {
@@ -1360,7 +1371,7 @@ static void free_streams(struct ctf_writer *cw)
static int ctf_writer__setup_env(struct ctf_writer *cw,
struct perf_session *session)
{
- struct perf_header *header = &session->header;
+ struct perf_env *env = perf_session__env(session);
struct bt_ctf_writer *writer = cw->writer;
#define ADD(__n, __v) \
@@ -1369,11 +1380,11 @@ do { \
return -1; \
} while (0)
- ADD("host", header->env.hostname);
+ ADD("host", env->hostname);
ADD("sysname", "Linux");
- ADD("release", header->env.os_release);
- ADD("version", header->env.version);
- ADD("machine", header->env.arch);
+ ADD("release", env->os_release);
+ ADD("version", env->version);
+ ADD("machine", env->arch);
ADD("domain", "kernel");
ADD("tracer_name", "perf");
@@ -1381,11 +1392,26 @@ do { \
return 0;
}
-static int ctf_writer__setup_clock(struct ctf_writer *cw)
+static int ctf_writer__setup_clock(struct ctf_writer *cw,
+ struct perf_session *session,
+ bool tod)
{
struct bt_ctf_clock *clock = cw->clock;
+ const char *desc = "perf clock";
+ int64_t offset = 0;
+
+ if (tod) {
+ struct perf_env *env = perf_session__env(session);
+
+ if (!env->clock.enabled) {
+ pr_err("Can't provide --tod time, missing clock data. "
+ "Please record with -k/--clockid option.\n");
+ return -1;
+ }
- bt_ctf_clock_set_description(clock, "perf clock");
+ desc = clockid_name(env->clock.clockid);
+ offset = env->clock.tod_ns - env->clock.clockid_ns;
+ }
#define SET(__n, __v) \
do { \
@@ -1394,8 +1420,8 @@ do { \
} while (0)
SET(frequency, 1000000000);
- SET(offset_s, 0);
- SET(offset, 0);
+ SET(offset, offset);
+ SET(description, desc);
SET(precision, 10);
SET(is_absolute, 0);
@@ -1419,7 +1445,7 @@ static struct bt_ctf_field_type *create_int_type(int size, bool sign, bool hex)
bt_ctf_field_type_integer_set_base(type, BT_CTF_INTEGER_BASE_HEXADECIMAL))
goto err;
-#if __BYTE_ORDER == __BIG_ENDIAN
+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
bt_ctf_field_type_set_byte_order(type, BT_CTF_BYTE_ORDER_BIG_ENDIAN);
#else
bt_ctf_field_type_set_byte_order(type, BT_CTF_BYTE_ORDER_LITTLE_ENDIAN);
@@ -1481,7 +1507,8 @@ static void ctf_writer__cleanup(struct ctf_writer *cw)
memset(cw, 0, sizeof(*cw));
}
-static int ctf_writer__init(struct ctf_writer *cw, const char *path)
+static int ctf_writer__init(struct ctf_writer *cw, const char *path,
+ struct perf_session *session, bool tod)
{
struct bt_ctf_writer *writer;
struct bt_ctf_stream_class *stream_class;
@@ -1505,7 +1532,7 @@ static int ctf_writer__init(struct ctf_writer *cw, const char *path)
cw->clock = clock;
- if (ctf_writer__setup_clock(cw)) {
+ if (ctf_writer__setup_clock(cw, session, tod)) {
pr("Failed to setup CTF clock.\n");
goto err_cleanup;
}
@@ -1582,25 +1609,23 @@ int bt_convert__perf2ctf(const char *input, const char *path,
.mode = PERF_DATA_MODE_READ,
.force = opts->force,
};
- struct convert c = {
- .tool = {
- .sample = process_sample_event,
- .mmap = perf_event__process_mmap,
- .mmap2 = perf_event__process_mmap2,
- .comm = perf_event__process_comm,
- .exit = perf_event__process_exit,
- .fork = perf_event__process_fork,
- .lost = perf_event__process_lost,
- .tracing_data = perf_event__process_tracing_data,
- .build_id = perf_event__process_build_id,
- .namespaces = perf_event__process_namespaces,
- .ordered_events = true,
- .ordering_requires_timestamps = true,
- },
- };
+ struct convert c = {};
struct ctf_writer *cw = &c.writer;
int err;
+ perf_tool__init(&c.tool, /*ordered_events=*/true);
+ c.tool.sample = process_sample_event;
+ c.tool.mmap = perf_event__process_mmap;
+ c.tool.mmap2 = perf_event__process_mmap2;
+ c.tool.comm = perf_event__process_comm;
+ c.tool.exit = perf_event__process_exit;
+ c.tool.fork = perf_event__process_fork;
+ c.tool.lost = perf_event__process_lost;
+ c.tool.tracing_data = perf_event__process_tracing_data;
+ c.tool.build_id = perf_event__process_build_id;
+ c.tool.namespaces = perf_event__process_namespaces;
+ c.tool.ordering_requires_timestamps = true;
+
if (opts->all) {
c.tool.comm = process_comm_event;
c.tool.exit = process_exit_event;
@@ -1613,17 +1638,15 @@ int bt_convert__perf2ctf(const char *input, const char *path,
if (err)
return err;
- /* CTF writer */
- if (ctf_writer__init(cw, path))
- return -1;
-
err = -1;
/* perf.data session */
- session = perf_session__new(&data, 0, &c.tool);
- if (IS_ERR(session)) {
- err = PTR_ERR(session);
- goto free_writer;
- }
+ session = perf_session__new(&data, &c.tool);
+ if (IS_ERR(session))
+ return PTR_ERR(session);
+
+ /* CTF writer */
+ if (ctf_writer__init(cw, path, session, opts->tod))
+ goto free_session;
if (c.queue_size) {
ordered_events__set_alloc_size(&session->ordered_events,
@@ -1632,17 +1655,17 @@ int bt_convert__perf2ctf(const char *input, const char *path,
/* CTF writer env/clock setup */
if (ctf_writer__setup_env(cw, session))
- goto free_session;
+ goto free_writer;
/* CTF events setup */
if (setup_events(cw, session))
- goto free_session;
+ goto free_writer;
if (opts->all && setup_non_sample_events(cw, session))
- goto free_session;
+ goto free_writer;
if (setup_streams(cw, session))
- goto free_session;
+ goto free_writer;
err = perf_session__process_events(session);
if (!err)
@@ -1670,10 +1693,10 @@ int bt_convert__perf2ctf(const char *input, const char *path,
return err;
-free_session:
- perf_session__delete(session);
free_writer:
ctf_writer__cleanup(cw);
+free_session:
+ perf_session__delete(session);
pr_err("Error during conversion setup.\n");
return err;
}