^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * CTF writing support via babeltrace.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2014, Jiri Olsa <jolsa@redhat.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 2014, Sebastian Andrzej Siewior <bigeasy@linutronix.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <inttypes.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/compiler.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/zalloc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <babeltrace/ctf-writer/writer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <babeltrace/ctf-writer/clock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <babeltrace/ctf-writer/stream.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <babeltrace/ctf-writer/event.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <babeltrace/ctf-writer/event-types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <babeltrace/ctf-writer/event-fields.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <babeltrace/ctf-ir/utils.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <babeltrace/ctf/events.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <traceevent/event-parse.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include "asm/bug.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include "data-convert-bt.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include "session.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include "debug.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include "tool.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include "evlist.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include "evsel.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include "machine.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include "config.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <linux/ctype.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <linux/time64.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include "util.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include "clockid.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define pr_N(n, fmt, ...) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) eprintf(n, debug_data_convert, fmt, ##__VA_ARGS__)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define pr(fmt, ...) pr_N(1, pr_fmt(fmt), ##__VA_ARGS__)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define pr2(fmt, ...) pr_N(2, pr_fmt(fmt), ##__VA_ARGS__)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define pr_time2(t, fmt, ...) pr_time_N(2, debug_data_convert, t, pr_fmt(fmt), ##__VA_ARGS__)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) struct evsel_priv {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) struct bt_ctf_event_class *event_class;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define MAX_CPUS 4096
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) struct ctf_stream {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) struct bt_ctf_stream *stream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) int cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) u32 count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) struct ctf_writer {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) /* writer primitives */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) struct bt_ctf_writer *writer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) struct ctf_stream **stream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) int stream_cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) struct bt_ctf_stream_class *stream_class;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) struct bt_ctf_clock *clock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) /* data types */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) union {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) struct bt_ctf_field_type *s64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) struct bt_ctf_field_type *u64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) struct bt_ctf_field_type *s32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) struct bt_ctf_field_type *u32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) struct bt_ctf_field_type *string;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) struct bt_ctf_field_type *u32_hex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) struct bt_ctf_field_type *u64_hex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) struct bt_ctf_field_type *array[6];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) } data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) struct bt_ctf_event_class *comm_class;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) struct bt_ctf_event_class *exit_class;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) struct bt_ctf_event_class *fork_class;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) struct bt_ctf_event_class *mmap_class;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) struct bt_ctf_event_class *mmap2_class;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) struct convert {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) struct perf_tool tool;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) struct ctf_writer writer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) u64 events_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) u64 events_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) u64 non_sample_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) /* Ordered events configured queue size. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) u64 queue_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) static int value_set(struct bt_ctf_field_type *type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) struct bt_ctf_event *event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) const char *name, u64 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) struct bt_ctf_field *field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) bool sign = bt_ctf_field_type_integer_get_signed(type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) field = bt_ctf_field_create(type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) if (!field) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) pr_err("failed to create a field %s\n", name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) if (sign) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) ret = bt_ctf_field_signed_integer_set_value(field, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) pr_err("failed to set field value %s\n", name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) ret = bt_ctf_field_unsigned_integer_set_value(field, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) pr_err("failed to set field value %s\n", name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) ret = bt_ctf_event_set_payload(event, name, field);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) pr_err("failed to set payload %s\n", name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) pr2(" SET [%s = %" PRIu64 "]\n", name, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) bt_ctf_field_put(field);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) #define __FUNC_VALUE_SET(_name, _val_type) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) static __maybe_unused int value_set_##_name(struct ctf_writer *cw, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) struct bt_ctf_event *event, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) const char *name, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) _val_type val) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) struct bt_ctf_field_type *type = cw->data._name; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) return value_set(type, event, name, (u64) val); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) #define FUNC_VALUE_SET(_name) __FUNC_VALUE_SET(_name, _name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) FUNC_VALUE_SET(s32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) FUNC_VALUE_SET(u32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) FUNC_VALUE_SET(s64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) FUNC_VALUE_SET(u64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) __FUNC_VALUE_SET(u64_hex, u64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) static int string_set_value(struct bt_ctf_field *field, const char *string);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) static __maybe_unused int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) value_set_string(struct ctf_writer *cw, struct bt_ctf_event *event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) const char *name, const char *string)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) struct bt_ctf_field_type *type = cw->data.string;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) struct bt_ctf_field *field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) field = bt_ctf_field_create(type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) if (!field) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) pr_err("failed to create a field %s\n", name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) ret = string_set_value(field, string);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) pr_err("failed to set value %s\n", name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) goto err_put_field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) ret = bt_ctf_event_set_payload(event, name, field);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) pr_err("failed to set payload %s\n", name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) err_put_field:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) bt_ctf_field_put(field);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) static struct bt_ctf_field_type*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) get_tracepoint_field_type(struct ctf_writer *cw, struct tep_format_field *field)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) unsigned long flags = field->flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) if (flags & TEP_FIELD_IS_STRING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) return cw->data.string;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) if (!(flags & TEP_FIELD_IS_SIGNED)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) /* unsigned long are mostly pointers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) if (flags & TEP_FIELD_IS_LONG || flags & TEP_FIELD_IS_POINTER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) return cw->data.u64_hex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) if (flags & TEP_FIELD_IS_SIGNED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) if (field->size == 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) return cw->data.s64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) return cw->data.s32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) if (field->size == 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) return cw->data.u64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) return cw->data.u32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) static unsigned long long adjust_signedness(unsigned long long value_int, int size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) unsigned long long value_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) * value_mask = (1 << (size * 8 - 1)) - 1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) * Directly set value_mask for code readers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) switch (size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) value_mask = 0x7fULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) case 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) value_mask = 0x7fffULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) case 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) value_mask = 0x7fffffffULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) case 8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) * For 64 bit value, return it self. There is no need
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) * to fill high bit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) /* Fall through */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) /* BUG! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) return value_int;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) /* If it is a positive value, don't adjust. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) if ((value_int & (~0ULL - value_mask)) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) return value_int;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) /* Fill upper part of value_int with 1 to make it a negative long long. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) return (value_int & value_mask) | ~value_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) static int string_set_value(struct bt_ctf_field *field, const char *string)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) char *buffer = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) size_t len = strlen(string), i, p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) for (i = p = 0; i < len; i++, p++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) if (isprint(string[i])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) if (!buffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) buffer[p] = string[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) char numstr[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) snprintf(numstr, sizeof(numstr), "\\x%02x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) (unsigned int)(string[i]) & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) if (!buffer) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) buffer = zalloc(i + (len - i) * 4 + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) if (!buffer) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) pr_err("failed to set unprintable string '%s'\n", string);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) return bt_ctf_field_string_set_value(field, "UNPRINTABLE-STRING");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) if (i > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) strncpy(buffer, string, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) memcpy(buffer + p, numstr, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) p += 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) if (!buffer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) return bt_ctf_field_string_set_value(field, string);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) err = bt_ctf_field_string_set_value(field, buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) free(buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) static int add_tracepoint_field_value(struct ctf_writer *cw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) struct bt_ctf_event_class *event_class,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) struct bt_ctf_event *event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) struct perf_sample *sample,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) struct tep_format_field *fmtf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) struct bt_ctf_field_type *type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) struct bt_ctf_field *array_field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) struct bt_ctf_field *field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) const char *name = fmtf->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) void *data = sample->raw_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) unsigned long flags = fmtf->flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) unsigned int n_items;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) unsigned int offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) unsigned int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) name = fmtf->alias;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) offset = fmtf->offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) len = fmtf->size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) if (flags & TEP_FIELD_IS_STRING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) flags &= ~TEP_FIELD_IS_ARRAY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) if (flags & TEP_FIELD_IS_DYNAMIC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) unsigned long long tmp_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) tmp_val = tep_read_number(fmtf->event->tep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) data + offset, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) offset = tmp_val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) len = offset >> 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) offset &= 0xffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) if (flags & TEP_FIELD_IS_ARRAY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) type = bt_ctf_event_class_get_field_by_name(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) event_class, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) array_field = bt_ctf_field_create(type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) bt_ctf_field_type_put(type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) if (!array_field) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) pr_err("Failed to create array type %s\n", name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) len = fmtf->size / fmtf->arraylen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) n_items = fmtf->arraylen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) n_items = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) array_field = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) type = get_tracepoint_field_type(cw, fmtf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) for (i = 0; i < n_items; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) if (flags & TEP_FIELD_IS_ARRAY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) field = bt_ctf_field_array_get_field(array_field, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) field = bt_ctf_field_create(type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) if (!field) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) pr_err("failed to create a field %s\n", name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) if (flags & TEP_FIELD_IS_STRING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) ret = string_set_value(field, data + offset + i * len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) unsigned long long value_int;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) value_int = tep_read_number(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) fmtf->event->tep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) data + offset + i * len, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) if (!(flags & TEP_FIELD_IS_SIGNED))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) ret = bt_ctf_field_unsigned_integer_set_value(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) field, value_int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) ret = bt_ctf_field_signed_integer_set_value(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) field, adjust_signedness(value_int, len));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) pr_err("failed to set file value %s\n", name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) goto err_put_field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) if (!(flags & TEP_FIELD_IS_ARRAY)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) ret = bt_ctf_event_set_payload(event, name, field);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) pr_err("failed to set payload %s\n", name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) goto err_put_field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) bt_ctf_field_put(field);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) if (flags & TEP_FIELD_IS_ARRAY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) ret = bt_ctf_event_set_payload(event, name, array_field);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) pr_err("Failed add payload array %s\n", name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) bt_ctf_field_put(array_field);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) err_put_field:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) bt_ctf_field_put(field);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) static int add_tracepoint_fields_values(struct ctf_writer *cw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) struct bt_ctf_event_class *event_class,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) struct bt_ctf_event *event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) struct tep_format_field *fields,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) struct perf_sample *sample)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) struct tep_format_field *field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) for (field = fields; field; field = field->next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) ret = add_tracepoint_field_value(cw, event_class, event, sample,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) field);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) static int add_tracepoint_values(struct ctf_writer *cw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) struct bt_ctf_event_class *event_class,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) struct bt_ctf_event *event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) struct evsel *evsel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) struct perf_sample *sample)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) struct tep_format_field *common_fields = evsel->tp_format->format.common_fields;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) struct tep_format_field *fields = evsel->tp_format->format.fields;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) ret = add_tracepoint_fields_values(cw, event_class, event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) common_fields, sample);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) ret = add_tracepoint_fields_values(cw, event_class, event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) fields, sample);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) add_bpf_output_values(struct bt_ctf_event_class *event_class,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) struct bt_ctf_event *event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) struct perf_sample *sample)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) struct bt_ctf_field_type *len_type, *seq_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) struct bt_ctf_field *len_field, *seq_field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) unsigned int raw_size = sample->raw_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) unsigned int nr_elements = raw_size / sizeof(u32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) if (nr_elements * sizeof(u32) != raw_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) pr_warning("Incorrect raw_size (%u) in bpf output event, skip %zu bytes\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) raw_size, nr_elements * sizeof(u32) - raw_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) len_type = bt_ctf_event_class_get_field_by_name(event_class, "raw_len");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) len_field = bt_ctf_field_create(len_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) if (!len_field) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) pr_err("failed to create 'raw_len' for bpf output event\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) ret = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) goto put_len_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) ret = bt_ctf_field_unsigned_integer_set_value(len_field, nr_elements);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) pr_err("failed to set field value for raw_len\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) goto put_len_field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) ret = bt_ctf_event_set_payload(event, "raw_len", len_field);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) pr_err("failed to set payload to raw_len\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) goto put_len_field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) seq_type = bt_ctf_event_class_get_field_by_name(event_class, "raw_data");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) seq_field = bt_ctf_field_create(seq_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) if (!seq_field) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) pr_err("failed to create 'raw_data' for bpf output event\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) ret = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) goto put_seq_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) ret = bt_ctf_field_sequence_set_length(seq_field, len_field);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) pr_err("failed to set length of 'raw_data'\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) goto put_seq_field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) for (i = 0; i < nr_elements; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) struct bt_ctf_field *elem_field =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) bt_ctf_field_sequence_get_field(seq_field, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) ret = bt_ctf_field_unsigned_integer_set_value(elem_field,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) ((u32 *)(sample->raw_data))[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) bt_ctf_field_put(elem_field);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) pr_err("failed to set raw_data[%d]\n", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) goto put_seq_field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) ret = bt_ctf_event_set_payload(event, "raw_data", seq_field);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) pr_err("failed to set payload for raw_data\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) put_seq_field:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) bt_ctf_field_put(seq_field);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) put_seq_type:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) bt_ctf_field_type_put(seq_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) put_len_field:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) bt_ctf_field_put(len_field);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) put_len_type:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) bt_ctf_field_type_put(len_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) add_callchain_output_values(struct bt_ctf_event_class *event_class,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) struct bt_ctf_event *event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) struct ip_callchain *callchain)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) struct bt_ctf_field_type *len_type, *seq_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) struct bt_ctf_field *len_field, *seq_field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) unsigned int nr_elements = callchain->nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) len_type = bt_ctf_event_class_get_field_by_name(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) event_class, "perf_callchain_size");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) len_field = bt_ctf_field_create(len_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) if (!len_field) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) pr_err("failed to create 'perf_callchain_size' for callchain output event\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) ret = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) goto put_len_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) ret = bt_ctf_field_unsigned_integer_set_value(len_field, nr_elements);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) pr_err("failed to set field value for perf_callchain_size\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) goto put_len_field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) ret = bt_ctf_event_set_payload(event, "perf_callchain_size", len_field);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) pr_err("failed to set payload to perf_callchain_size\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) goto put_len_field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) seq_type = bt_ctf_event_class_get_field_by_name(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) event_class, "perf_callchain");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) seq_field = bt_ctf_field_create(seq_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) if (!seq_field) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) pr_err("failed to create 'perf_callchain' for callchain output event\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) ret = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) goto put_seq_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) ret = bt_ctf_field_sequence_set_length(seq_field, len_field);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) pr_err("failed to set length of 'perf_callchain'\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) goto put_seq_field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) for (i = 0; i < nr_elements; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) struct bt_ctf_field *elem_field =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) bt_ctf_field_sequence_get_field(seq_field, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) ret = bt_ctf_field_unsigned_integer_set_value(elem_field,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) ((u64 *)(callchain->ips))[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) bt_ctf_field_put(elem_field);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) pr_err("failed to set callchain[%d]\n", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) goto put_seq_field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) ret = bt_ctf_event_set_payload(event, "perf_callchain", seq_field);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) pr_err("failed to set payload for raw_data\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) put_seq_field:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) bt_ctf_field_put(seq_field);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) put_seq_type:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) bt_ctf_field_type_put(seq_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) put_len_field:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) bt_ctf_field_put(len_field);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) put_len_type:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) bt_ctf_field_type_put(len_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) static int add_generic_values(struct ctf_writer *cw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) struct bt_ctf_event *event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) struct evsel *evsel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) struct perf_sample *sample)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) u64 type = evsel->core.attr.sample_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) * missing:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) * PERF_SAMPLE_TIME - not needed as we have it in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) * ctf event header
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) * PERF_SAMPLE_READ - TODO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) * PERF_SAMPLE_RAW - tracepoint fields are handled separately
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) * PERF_SAMPLE_BRANCH_STACK - TODO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) * PERF_SAMPLE_REGS_USER - TODO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) * PERF_SAMPLE_STACK_USER - TODO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) if (type & PERF_SAMPLE_IP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) ret = value_set_u64_hex(cw, event, "perf_ip", sample->ip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) if (type & PERF_SAMPLE_TID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) ret = value_set_s32(cw, event, "perf_tid", sample->tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) ret = value_set_s32(cw, event, "perf_pid", sample->pid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) if ((type & PERF_SAMPLE_ID) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) (type & PERF_SAMPLE_IDENTIFIER)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) ret = value_set_u64(cw, event, "perf_id", sample->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) if (type & PERF_SAMPLE_STREAM_ID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) ret = value_set_u64(cw, event, "perf_stream_id", sample->stream_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) if (type & PERF_SAMPLE_PERIOD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) ret = value_set_u64(cw, event, "perf_period", sample->period);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) if (type & PERF_SAMPLE_WEIGHT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) ret = value_set_u64(cw, event, "perf_weight", sample->weight);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) if (type & PERF_SAMPLE_DATA_SRC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) ret = value_set_u64(cw, event, "perf_data_src",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) sample->data_src);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) if (type & PERF_SAMPLE_TRANSACTION) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) ret = value_set_u64(cw, event, "perf_transaction",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) sample->transaction);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) static int ctf_stream__flush(struct ctf_stream *cs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) if (cs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) err = bt_ctf_stream_flush(cs->stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) pr_err("CTF stream %d flush failed\n", cs->cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) pr("Flush stream for cpu %d (%u samples)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) cs->cpu, cs->count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) cs->count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) static struct ctf_stream *ctf_stream__create(struct ctf_writer *cw, int cpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) struct ctf_stream *cs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) struct bt_ctf_field *pkt_ctx = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) struct bt_ctf_field *cpu_field = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) struct bt_ctf_stream *stream = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) cs = zalloc(sizeof(*cs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) if (!cs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) pr_err("Failed to allocate ctf stream\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) stream = bt_ctf_writer_create_stream(cw->writer, cw->stream_class);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) if (!stream) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) pr_err("Failed to create CTF stream\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) pkt_ctx = bt_ctf_stream_get_packet_context(stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) if (!pkt_ctx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) pr_err("Failed to obtain packet context\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) cpu_field = bt_ctf_field_structure_get_field(pkt_ctx, "cpu_id");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) bt_ctf_field_put(pkt_ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) if (!cpu_field) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) pr_err("Failed to obtain cpu field\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) ret = bt_ctf_field_unsigned_integer_set_value(cpu_field, (u32) cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) pr_err("Failed to update CPU number\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) bt_ctf_field_put(cpu_field);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) cs->cpu = cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) cs->stream = stream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) return cs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) if (cpu_field)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) bt_ctf_field_put(cpu_field);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) if (stream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) bt_ctf_stream_put(stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) free(cs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) static void ctf_stream__delete(struct ctf_stream *cs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) if (cs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) bt_ctf_stream_put(cs->stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) free(cs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) static struct ctf_stream *ctf_stream(struct ctf_writer *cw, int cpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) struct ctf_stream *cs = cw->stream[cpu];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) if (!cs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) cs = ctf_stream__create(cw, cpu);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) cw->stream[cpu] = cs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) return cs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) static int get_sample_cpu(struct ctf_writer *cw, struct perf_sample *sample,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) struct evsel *evsel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) int cpu = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) if (evsel->core.attr.sample_type & PERF_SAMPLE_CPU)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) cpu = sample->cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) if (cpu > cw->stream_cnt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) pr_err("Event was recorded for CPU %d, limit is at %d.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) cpu, cw->stream_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) cpu = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) return cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) #define STREAM_FLUSH_COUNT 100000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) * Currently we have no other way to determine the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) * time for the stream flush other than keep track
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) * of the number of events and check it against
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) * threshold.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) static bool is_flush_needed(struct ctf_stream *cs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) return cs->count >= STREAM_FLUSH_COUNT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) static int process_sample_event(struct perf_tool *tool,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) union perf_event *_event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) struct perf_sample *sample,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) struct evsel *evsel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) struct machine *machine __maybe_unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) struct convert *c = container_of(tool, struct convert, tool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) struct evsel_priv *priv = evsel->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) struct ctf_writer *cw = &c->writer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) struct ctf_stream *cs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) struct bt_ctf_event_class *event_class;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) struct bt_ctf_event *event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) unsigned long type = evsel->core.attr.sample_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) if (WARN_ONCE(!priv, "Failed to setup all events.\n"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) event_class = priv->event_class;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) /* update stats */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) c->events_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) c->events_size += _event->header.size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) pr_time2(sample->time, "sample %" PRIu64 "\n", c->events_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) event = bt_ctf_event_create(event_class);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) if (!event) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) pr_err("Failed to create an CTF event\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) bt_ctf_clock_set_time(cw->clock, sample->time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) ret = add_generic_values(cw, event, evsel, sample);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) if (evsel->core.attr.type == PERF_TYPE_TRACEPOINT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) ret = add_tracepoint_values(cw, event_class, event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) evsel, sample);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) if (type & PERF_SAMPLE_CALLCHAIN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) ret = add_callchain_output_values(event_class,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) event, sample->callchain);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) if (evsel__is_bpf_output(evsel)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) ret = add_bpf_output_values(event_class, event, sample);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) cs = ctf_stream(cw, get_sample_cpu(cw, sample, evsel));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) if (cs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) if (is_flush_needed(cs))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) ctf_stream__flush(cs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) cs->count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) bt_ctf_stream_append_event(cs->stream, event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) bt_ctf_event_put(event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) return cs ? 0 : -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) #define __NON_SAMPLE_SET_FIELD(_name, _type, _field) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) do { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) ret = value_set_##_type(cw, event, #_field, _event->_name._field);\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) if (ret) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) return -1; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) } while(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) #define __FUNC_PROCESS_NON_SAMPLE(_name, body) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) static int process_##_name##_event(struct perf_tool *tool, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) union perf_event *_event, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) struct perf_sample *sample, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) struct machine *machine) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) struct convert *c = container_of(tool, struct convert, tool);\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) struct ctf_writer *cw = &c->writer; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) struct bt_ctf_event_class *event_class = cw->_name##_class;\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) struct bt_ctf_event *event; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) struct ctf_stream *cs; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) int ret; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) c->non_sample_count++; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) c->events_size += _event->header.size; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) event = bt_ctf_event_create(event_class); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) if (!event) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) pr_err("Failed to create an CTF event\n"); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) return -1; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) } \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) bt_ctf_clock_set_time(cw->clock, sample->time); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) body \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) cs = ctf_stream(cw, 0); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) if (cs) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) if (is_flush_needed(cs)) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) ctf_stream__flush(cs); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) cs->count++; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) bt_ctf_stream_append_event(cs->stream, event); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) } \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) bt_ctf_event_put(event); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) return perf_event__process_##_name(tool, _event, sample, machine);\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) __FUNC_PROCESS_NON_SAMPLE(comm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) __NON_SAMPLE_SET_FIELD(comm, u32, pid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) __NON_SAMPLE_SET_FIELD(comm, u32, tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) __NON_SAMPLE_SET_FIELD(comm, string, comm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) __FUNC_PROCESS_NON_SAMPLE(fork,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) __NON_SAMPLE_SET_FIELD(fork, u32, pid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) __NON_SAMPLE_SET_FIELD(fork, u32, ppid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) __NON_SAMPLE_SET_FIELD(fork, u32, tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) __NON_SAMPLE_SET_FIELD(fork, u32, ptid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) __NON_SAMPLE_SET_FIELD(fork, u64, time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) __FUNC_PROCESS_NON_SAMPLE(exit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) __NON_SAMPLE_SET_FIELD(fork, u32, pid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) __NON_SAMPLE_SET_FIELD(fork, u32, ppid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) __NON_SAMPLE_SET_FIELD(fork, u32, tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) __NON_SAMPLE_SET_FIELD(fork, u32, ptid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) __NON_SAMPLE_SET_FIELD(fork, u64, time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) __FUNC_PROCESS_NON_SAMPLE(mmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) __NON_SAMPLE_SET_FIELD(mmap, u32, pid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) __NON_SAMPLE_SET_FIELD(mmap, u32, tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) __NON_SAMPLE_SET_FIELD(mmap, u64_hex, start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) __NON_SAMPLE_SET_FIELD(mmap, string, filename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) __FUNC_PROCESS_NON_SAMPLE(mmap2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) __NON_SAMPLE_SET_FIELD(mmap2, u32, pid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) __NON_SAMPLE_SET_FIELD(mmap2, u32, tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) __NON_SAMPLE_SET_FIELD(mmap2, u64_hex, start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) __NON_SAMPLE_SET_FIELD(mmap2, string, filename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) #undef __NON_SAMPLE_SET_FIELD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) #undef __FUNC_PROCESS_NON_SAMPLE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) /* If dup < 0, add a prefix. Else, add _dupl_X suffix. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) static char *change_name(char *name, char *orig_name, int dup)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) char *new_name = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) size_t len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) if (!name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) name = orig_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) if (dup >= 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) * Add '_' prefix to potential keywork. According to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) * Mathieu Desnoyers (https://lkml.org/lkml/2015/1/23/652),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) * futher CTF spec updating may require us to use '$'.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) if (dup < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) len = strlen(name) + sizeof("_");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) len = strlen(orig_name) + sizeof("_dupl_X");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) new_name = malloc(len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) if (!new_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) if (dup < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) snprintf(new_name, len, "_%s", name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) snprintf(new_name, len, "%s_dupl_%d", orig_name, dup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) if (name != orig_name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) free(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) return new_name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) static int event_class_add_field(struct bt_ctf_event_class *event_class,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) struct bt_ctf_field_type *type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) struct tep_format_field *field)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) struct bt_ctf_field_type *t = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) int dup = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) /* alias was already assigned */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) if (field->alias != field->name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) return bt_ctf_event_class_add_field(event_class, type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) (char *)field->alias);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) name = field->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) /* If 'name' is a keywork, add prefix. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) if (bt_ctf_validate_identifier(name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) name = change_name(name, field->name, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) if (!name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) pr_err("Failed to fix invalid identifier.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) while ((t = bt_ctf_event_class_get_field_by_name(event_class, name))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) bt_ctf_field_type_put(t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) name = change_name(name, field->name, dup++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) if (!name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) pr_err("Failed to create dup name for '%s'\n", field->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) ret = bt_ctf_event_class_add_field(event_class, type, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) field->alias = name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) static int add_tracepoint_fields_types(struct ctf_writer *cw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) struct tep_format_field *fields,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) struct bt_ctf_event_class *event_class)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) struct tep_format_field *field;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) for (field = fields; field; field = field->next) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) struct bt_ctf_field_type *type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) unsigned long flags = field->flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) pr2(" field '%s'\n", field->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) type = get_tracepoint_field_type(cw, field);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) if (!type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) * A string is an array of chars. For this we use the string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) * type and don't care that it is an array. What we don't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) * support is an array of strings.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) if (flags & TEP_FIELD_IS_STRING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) flags &= ~TEP_FIELD_IS_ARRAY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) if (flags & TEP_FIELD_IS_ARRAY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) type = bt_ctf_field_type_array_create(type, field->arraylen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) ret = event_class_add_field(event_class, type, field);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) if (flags & TEP_FIELD_IS_ARRAY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) bt_ctf_field_type_put(type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) pr_err("Failed to add field '%s': %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) field->name, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) static int add_tracepoint_types(struct ctf_writer *cw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) struct evsel *evsel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) struct bt_ctf_event_class *class)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) struct tep_format_field *common_fields = evsel->tp_format->format.common_fields;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) struct tep_format_field *fields = evsel->tp_format->format.fields;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) ret = add_tracepoint_fields_types(cw, common_fields, class);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) ret = add_tracepoint_fields_types(cw, fields, class);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) static int add_bpf_output_types(struct ctf_writer *cw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) struct bt_ctf_event_class *class)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) struct bt_ctf_field_type *len_type = cw->data.u32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) struct bt_ctf_field_type *seq_base_type = cw->data.u32_hex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) struct bt_ctf_field_type *seq_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) ret = bt_ctf_event_class_add_field(class, len_type, "raw_len");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) seq_type = bt_ctf_field_type_sequence_create(seq_base_type, "raw_len");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) if (!seq_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) return bt_ctf_event_class_add_field(class, seq_type, "raw_data");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) static int add_generic_types(struct ctf_writer *cw, struct evsel *evsel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) struct bt_ctf_event_class *event_class)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) u64 type = evsel->core.attr.sample_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) * missing:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) * PERF_SAMPLE_TIME - not needed as we have it in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) * ctf event header
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) * PERF_SAMPLE_READ - TODO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) * PERF_SAMPLE_CALLCHAIN - TODO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) * PERF_SAMPLE_RAW - tracepoint fields and BPF output
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) * are handled separately
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) * PERF_SAMPLE_BRANCH_STACK - TODO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) * PERF_SAMPLE_REGS_USER - TODO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) * PERF_SAMPLE_STACK_USER - TODO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) #define ADD_FIELD(cl, t, n) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) do { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) pr2(" field '%s'\n", n); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) if (bt_ctf_event_class_add_field(cl, t, n)) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) pr_err("Failed to add field '%s';\n", n); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) return -1; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) } \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) if (type & PERF_SAMPLE_IP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) ADD_FIELD(event_class, cw->data.u64_hex, "perf_ip");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) if (type & PERF_SAMPLE_TID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) ADD_FIELD(event_class, cw->data.s32, "perf_tid");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) ADD_FIELD(event_class, cw->data.s32, "perf_pid");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) if ((type & PERF_SAMPLE_ID) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) (type & PERF_SAMPLE_IDENTIFIER))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) ADD_FIELD(event_class, cw->data.u64, "perf_id");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) if (type & PERF_SAMPLE_STREAM_ID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) ADD_FIELD(event_class, cw->data.u64, "perf_stream_id");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) if (type & PERF_SAMPLE_PERIOD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) ADD_FIELD(event_class, cw->data.u64, "perf_period");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) if (type & PERF_SAMPLE_WEIGHT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) ADD_FIELD(event_class, cw->data.u64, "perf_weight");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) if (type & PERF_SAMPLE_DATA_SRC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) ADD_FIELD(event_class, cw->data.u64, "perf_data_src");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) if (type & PERF_SAMPLE_TRANSACTION)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) ADD_FIELD(event_class, cw->data.u64, "perf_transaction");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) if (type & PERF_SAMPLE_CALLCHAIN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) ADD_FIELD(event_class, cw->data.u32, "perf_callchain_size");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) ADD_FIELD(event_class,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) bt_ctf_field_type_sequence_create(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) cw->data.u64_hex, "perf_callchain_size"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) "perf_callchain");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) #undef ADD_FIELD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) static int add_event(struct ctf_writer *cw, struct evsel *evsel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) struct bt_ctf_event_class *event_class;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) struct evsel_priv *priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) const char *name = evsel__name(evsel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) pr("Adding event '%s' (type %d)\n", name, evsel->core.attr.type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) event_class = bt_ctf_event_class_create(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) if (!event_class)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) ret = add_generic_types(cw, evsel, event_class);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) if (evsel->core.attr.type == PERF_TYPE_TRACEPOINT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) ret = add_tracepoint_types(cw, evsel, event_class);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) if (evsel__is_bpf_output(evsel)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) ret = add_bpf_output_types(cw, event_class);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) ret = bt_ctf_stream_class_add_event_class(cw->stream_class, event_class);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) pr("Failed to add event class into stream.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) priv = malloc(sizeof(*priv));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) if (!priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) priv->event_class = event_class;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) evsel->priv = priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) bt_ctf_event_class_put(event_class);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) pr_err("Failed to add event '%s'.\n", name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) static int setup_events(struct ctf_writer *cw, struct perf_session *session)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) struct evlist *evlist = session->evlist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) struct evsel *evsel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) evlist__for_each_entry(evlist, evsel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) ret = add_event(cw, evsel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) #define __NON_SAMPLE_ADD_FIELD(t, n) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) do { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) pr2(" field '%s'\n", #n); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) if (bt_ctf_event_class_add_field(event_class, cw->data.t, #n)) {\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) pr_err("Failed to add field '%s';\n", #n);\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) return -1; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) } \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) } while(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) #define __FUNC_ADD_NON_SAMPLE_EVENT_CLASS(_name, body) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) static int add_##_name##_event(struct ctf_writer *cw) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) struct bt_ctf_event_class *event_class; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) int ret; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) pr("Adding "#_name" event\n"); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) event_class = bt_ctf_event_class_create("perf_" #_name);\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) if (!event_class) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) return -1; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) body \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) ret = bt_ctf_stream_class_add_event_class(cw->stream_class, event_class);\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) if (ret) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) pr("Failed to add event class '"#_name"' into stream.\n");\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) return ret; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) } \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) cw->_name##_class = event_class; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) bt_ctf_event_class_put(event_class); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) return 0; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) __FUNC_ADD_NON_SAMPLE_EVENT_CLASS(comm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) __NON_SAMPLE_ADD_FIELD(u32, pid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) __NON_SAMPLE_ADD_FIELD(u32, tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) __NON_SAMPLE_ADD_FIELD(string, comm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) __FUNC_ADD_NON_SAMPLE_EVENT_CLASS(fork,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) __NON_SAMPLE_ADD_FIELD(u32, pid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) __NON_SAMPLE_ADD_FIELD(u32, ppid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) __NON_SAMPLE_ADD_FIELD(u32, tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) __NON_SAMPLE_ADD_FIELD(u32, ptid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) __NON_SAMPLE_ADD_FIELD(u64, time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) __FUNC_ADD_NON_SAMPLE_EVENT_CLASS(exit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) __NON_SAMPLE_ADD_FIELD(u32, pid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) __NON_SAMPLE_ADD_FIELD(u32, ppid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) __NON_SAMPLE_ADD_FIELD(u32, tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) __NON_SAMPLE_ADD_FIELD(u32, ptid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) __NON_SAMPLE_ADD_FIELD(u64, time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) __FUNC_ADD_NON_SAMPLE_EVENT_CLASS(mmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) __NON_SAMPLE_ADD_FIELD(u32, pid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) __NON_SAMPLE_ADD_FIELD(u32, tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) __NON_SAMPLE_ADD_FIELD(u64_hex, start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) __NON_SAMPLE_ADD_FIELD(string, filename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) __FUNC_ADD_NON_SAMPLE_EVENT_CLASS(mmap2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) __NON_SAMPLE_ADD_FIELD(u32, pid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) __NON_SAMPLE_ADD_FIELD(u32, tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) __NON_SAMPLE_ADD_FIELD(u64_hex, start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) __NON_SAMPLE_ADD_FIELD(string, filename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) #undef __NON_SAMPLE_ADD_FIELD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) #undef __FUNC_ADD_NON_SAMPLE_EVENT_CLASS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) static int setup_non_sample_events(struct ctf_writer *cw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) struct perf_session *session __maybe_unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) ret = add_comm_event(cw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) ret = add_exit_event(cw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) ret = add_fork_event(cw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) ret = add_mmap_event(cw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) ret = add_mmap2_event(cw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) static void cleanup_events(struct perf_session *session)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) struct evlist *evlist = session->evlist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) struct evsel *evsel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) evlist__for_each_entry(evlist, evsel) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) struct evsel_priv *priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) priv = evsel->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) bt_ctf_event_class_put(priv->event_class);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) zfree(&evsel->priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) evlist__delete(evlist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) session->evlist = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) static int setup_streams(struct ctf_writer *cw, struct perf_session *session)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) struct ctf_stream **stream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) struct perf_header *ph = &session->header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) int ncpus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) * Try to get the number of cpus used in the data file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) * if not present fallback to the MAX_CPUS.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) ncpus = ph->env.nr_cpus_avail ?: MAX_CPUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) stream = zalloc(sizeof(*stream) * ncpus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) if (!stream) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) pr_err("Failed to allocate streams.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) cw->stream = stream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) cw->stream_cnt = ncpus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) static void free_streams(struct ctf_writer *cw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) int cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) for (cpu = 0; cpu < cw->stream_cnt; cpu++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) ctf_stream__delete(cw->stream[cpu]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) zfree(&cw->stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) static int ctf_writer__setup_env(struct ctf_writer *cw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) struct perf_session *session)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) struct perf_header *header = &session->header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) struct bt_ctf_writer *writer = cw->writer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) #define ADD(__n, __v) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) do { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) if (bt_ctf_writer_add_environment_field(writer, __n, __v)) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) return -1; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) ADD("host", header->env.hostname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) ADD("sysname", "Linux");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) ADD("release", header->env.os_release);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) ADD("version", header->env.version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) ADD("machine", header->env.arch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) ADD("domain", "kernel");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) ADD("tracer_name", "perf");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) #undef ADD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) static int ctf_writer__setup_clock(struct ctf_writer *cw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) struct perf_session *session,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) bool tod)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) struct bt_ctf_clock *clock = cw->clock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) const char *desc = "perf clock";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) int64_t offset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) if (tod) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) struct perf_env *env = &session->header.env;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) if (!env->clock.enabled) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) pr_err("Can't provide --tod time, missing clock data. "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) "Please record with -k/--clockid option.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) desc = clockid_name(env->clock.clockid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) offset = env->clock.tod_ns - env->clock.clockid_ns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) #define SET(__n, __v) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) do { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) if (bt_ctf_clock_set_##__n(clock, __v)) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) return -1; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) SET(frequency, 1000000000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) SET(offset, offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) SET(description, desc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) SET(precision, 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) SET(is_absolute, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) #undef SET
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) static struct bt_ctf_field_type *create_int_type(int size, bool sign, bool hex)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) struct bt_ctf_field_type *type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) type = bt_ctf_field_type_integer_create(size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) if (!type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) if (sign &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) bt_ctf_field_type_integer_set_signed(type, 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) if (hex &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) bt_ctf_field_type_integer_set_base(type, BT_CTF_INTEGER_BASE_HEXADECIMAL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) #if __BYTE_ORDER == __BIG_ENDIAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) bt_ctf_field_type_set_byte_order(type, BT_CTF_BYTE_ORDER_BIG_ENDIAN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) bt_ctf_field_type_set_byte_order(type, BT_CTF_BYTE_ORDER_LITTLE_ENDIAN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) pr2("Created type: INTEGER %d-bit %ssigned %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) size, sign ? "un" : "", hex ? "hex" : "");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) return type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) bt_ctf_field_type_put(type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) static void ctf_writer__cleanup_data(struct ctf_writer *cw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) for (i = 0; i < ARRAY_SIZE(cw->data.array); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) bt_ctf_field_type_put(cw->data.array[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) static int ctf_writer__init_data(struct ctf_writer *cw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) #define CREATE_INT_TYPE(type, size, sign, hex) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) do { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) (type) = create_int_type(size, sign, hex); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) if (!(type)) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) goto err; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) CREATE_INT_TYPE(cw->data.s64, 64, true, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) CREATE_INT_TYPE(cw->data.u64, 64, false, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) CREATE_INT_TYPE(cw->data.s32, 32, true, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) CREATE_INT_TYPE(cw->data.u32, 32, false, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) CREATE_INT_TYPE(cw->data.u32_hex, 32, false, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) CREATE_INT_TYPE(cw->data.u64_hex, 64, false, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) cw->data.string = bt_ctf_field_type_string_create();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) if (cw->data.string)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) ctf_writer__cleanup_data(cw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) pr_err("Failed to create data types.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) static void ctf_writer__cleanup(struct ctf_writer *cw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) ctf_writer__cleanup_data(cw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) bt_ctf_clock_put(cw->clock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) free_streams(cw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) bt_ctf_stream_class_put(cw->stream_class);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) bt_ctf_writer_put(cw->writer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) /* and NULL all the pointers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) memset(cw, 0, sizeof(*cw));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) static int ctf_writer__init(struct ctf_writer *cw, const char *path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) struct perf_session *session, bool tod)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) struct bt_ctf_writer *writer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) struct bt_ctf_stream_class *stream_class;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) struct bt_ctf_clock *clock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) struct bt_ctf_field_type *pkt_ctx_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) /* CTF writer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) writer = bt_ctf_writer_create(path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) if (!writer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) cw->writer = writer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) /* CTF clock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) clock = bt_ctf_clock_create("perf_clock");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) if (!clock) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) pr("Failed to create CTF clock.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) goto err_cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) cw->clock = clock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) if (ctf_writer__setup_clock(cw, session, tod)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) pr("Failed to setup CTF clock.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) goto err_cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) /* CTF stream class */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) stream_class = bt_ctf_stream_class_create("perf_stream");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) if (!stream_class) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) pr("Failed to create CTF stream class.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) goto err_cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) cw->stream_class = stream_class;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) /* CTF clock stream setup */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) if (bt_ctf_stream_class_set_clock(stream_class, clock)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) pr("Failed to assign CTF clock to stream class.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) goto err_cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) if (ctf_writer__init_data(cw))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) goto err_cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) /* Add cpu_id for packet context */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) pkt_ctx_type = bt_ctf_stream_class_get_packet_context_type(stream_class);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) if (!pkt_ctx_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) goto err_cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) ret = bt_ctf_field_type_structure_add_field(pkt_ctx_type, cw->data.u32, "cpu_id");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) bt_ctf_field_type_put(pkt_ctx_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) goto err_cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) /* CTF clock writer setup */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) if (bt_ctf_writer_add_clock(writer, clock)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) pr("Failed to assign CTF clock to writer.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) goto err_cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) err_cleanup:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) ctf_writer__cleanup(cw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) pr_err("Failed to setup CTF writer.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) static int ctf_writer__flush_streams(struct ctf_writer *cw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) int cpu, ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) for (cpu = 0; cpu < cw->stream_cnt && !ret; cpu++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) ret = ctf_stream__flush(cw->stream[cpu]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) static int convert__config(const char *var, const char *value, void *cb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) struct convert *c = cb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) if (!strcmp(var, "convert.queue-size"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) return perf_config_u64(&c->queue_size, var, value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) int bt_convert__perf2ctf(const char *input, const char *path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) struct perf_data_convert_opts *opts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) struct perf_session *session;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) struct perf_data data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) .path = input,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) .mode = PERF_DATA_MODE_READ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) .force = opts->force,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) struct convert c = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) .tool = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) .sample = process_sample_event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) .mmap = perf_event__process_mmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) .mmap2 = perf_event__process_mmap2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) .comm = perf_event__process_comm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) .exit = perf_event__process_exit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) .fork = perf_event__process_fork,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) .lost = perf_event__process_lost,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) .tracing_data = perf_event__process_tracing_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) .build_id = perf_event__process_build_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) .namespaces = perf_event__process_namespaces,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) .ordered_events = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) .ordering_requires_timestamps = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) struct ctf_writer *cw = &c.writer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) if (opts->all) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) c.tool.comm = process_comm_event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) c.tool.exit = process_exit_event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) c.tool.fork = process_fork_event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) c.tool.mmap = process_mmap_event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) c.tool.mmap2 = process_mmap2_event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) err = perf_config(convert__config, &c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) err = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) /* perf.data session */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) session = perf_session__new(&data, 0, &c.tool);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) if (IS_ERR(session))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) return PTR_ERR(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) /* CTF writer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) if (ctf_writer__init(cw, path, session, opts->tod))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) goto free_session;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) if (c.queue_size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) ordered_events__set_alloc_size(&session->ordered_events,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) c.queue_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) /* CTF writer env/clock setup */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) if (ctf_writer__setup_env(cw, session))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) goto free_writer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) /* CTF events setup */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) if (setup_events(cw, session))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) goto free_writer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) if (opts->all && setup_non_sample_events(cw, session))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) goto free_writer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) if (setup_streams(cw, session))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) goto free_writer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) err = perf_session__process_events(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) if (!err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) err = ctf_writer__flush_streams(cw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) pr_err("Error during conversion.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) fprintf(stderr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) "[ perf data convert: Converted '%s' into CTF data '%s' ]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) data.path, path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) fprintf(stderr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) "[ perf data convert: Converted and wrote %.3f MB (%" PRIu64 " samples",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) (double) c.events_size / 1024.0 / 1024.0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) c.events_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) if (!c.non_sample_count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) fprintf(stderr, ") ]\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) fprintf(stderr, ", %" PRIu64 " non-samples) ]\n", c.non_sample_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) cleanup_events(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) perf_session__delete(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) ctf_writer__cleanup(cw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) free_writer:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) ctf_writer__cleanup(cw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) free_session:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) perf_session__delete(session);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) pr_err("Error during conversion setup.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) }