* [PATCH] perf data ctf: replace libbabeltrace with babeltrace2-ctf-writer
@ 2026-05-12 19:47 Michael Jeanson
2026-05-12 21:54 ` Ian Rogers
0 siblings, 1 reply; 5+ messages in thread
From: Michael Jeanson @ 2026-05-12 19:47 UTC (permalink / raw)
To: linux-kernel
Cc: linux-perf-users, Michael Jeanson, Adrian Hunter,
Alexander Shishkin, Arnaldo Carvalho de Melo, Derek Foreman,
Ian Rogers, Ingo Molnar, James Clark, Jiri Olsa, Mark Rutland,
Mathieu Desnoyers, Namhyung Kim, Peter Zijlstra
The 1.x branch of Babeltrace has been superseded by 2.x in 2020 and has
been unmaintained since 2022, efforts have started to remove it from
popular distributions.
Babeltrace 2.x offers a very similar 'ctf-writer' library that can be used
with minimal changes for the '--to-ctf' feature and has been packaged
since Debian 11 and Fedora 32.
This patch replaces the 'libbabeltrace' build feature with
'babeltrace2-ctf-writer' using pkgconfig detection, adjusts the naming of
the public headers and applies minor API cleanups.
No changes to the output ctf traces, this API still implements version
1.8 of the CTF specification that can be read by either Babeltrace 1 / 2
or any CTF compliant reader.
Also remove some ifdefs in the cli option parsing to allow printing the
helpful error message with '--to-ctf' when built without babeltrace2.
Signed-off-by: Michael Jeanson <mjeanson@efficios.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Derek Foreman <derek.foreman@collabora.com>
Cc: Ian Rogers <irogers@google.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: James Clark <james.clark@linaro.org>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
---
tools/build/Makefile.feature | 5 +--
tools/build/feature/Makefile | 6 ++--
tools/build/feature/test-all.c | 13 ++------
...ltrace.c => test-babeltrace2-ctf-writer.c} | 3 +-
tools/perf/Makefile.config | 28 ++++++++--------
tools/perf/Makefile.perf | 2 +-
tools/perf/builtin-check.c | 2 +-
tools/perf/builtin-data.c | 18 +++-------
tools/perf/tests/make | 4 +--
.../shell/test_perf_data_converter_ctf.sh | 8 ++---
tools/perf/util/Build | 2 +-
tools/perf/util/data-convert-bt.c | 33 +++++++++----------
tools/perf/util/data-convert.h | 4 +--
13 files changed, 55 insertions(+), 73 deletions(-)
rename tools/build/feature/{test-libbabeltrace.c => test-babeltrace2-ctf-writer.c} (59%)
diff --git a/tools/build/Makefile.feature b/tools/build/Makefile.feature
index 0b7a7c38cb88..9e097144817e 100644
--- a/tools/build/Makefile.feature
+++ b/tools/build/Makefile.feature
@@ -113,7 +113,7 @@ FEATURE_TESTS_EXTRA := \
gtk2 \
gtk2-infobar \
hello \
- libbabeltrace \
+ babeltrace2-ctf-writer \
libcapstone \
libbfd-liberty \
libbfd-liberty-z \
@@ -162,6 +162,7 @@ FEATURE_GROUP_MEMBERS-libbfd = libbfd-liberty libbfd-liberty-z
# Declare list of feature dependency packages that provide pkg-config files.
#
FEATURE_PKG_CONFIG ?= \
+ babeltrace2-ctf-writer \
libtraceevent \
libtracefs
@@ -208,7 +209,7 @@ ifeq ($(feature-all), 1)
$(call feature_check,compile-32)
$(call feature_check,compile-x32)
$(call feature_check,bionic)
- $(call feature_check,libbabeltrace)
+ $(call feature_check,babeltrace2-ctf-writer)
else
$(foreach feat,$(FEATURE_TESTS),$(call feature_check,$(feat)))
endif
diff --git a/tools/build/feature/Makefile b/tools/build/feature/Makefile
index 1fbcb3ce74d2..7735e257c263 100644
--- a/tools/build/feature/Makefile
+++ b/tools/build/feature/Makefile
@@ -48,7 +48,7 @@ FILES= \
test-pthread-barrier.bin \
test-stackprotector-all.bin \
test-timerfd.bin \
- test-libbabeltrace.bin \
+ test-babeltrace2-ctf-writer.bin \
test-libcapstone.bin \
test-compile-32.bin \
test-compile-x32.bin \
@@ -301,8 +301,8 @@ $(OUTPUT)test-backtrace.bin:
$(OUTPUT)test-timerfd.bin:
$(BUILD)
-$(OUTPUT)test-libbabeltrace.bin:
- $(BUILD) # -lbabeltrace provided by $(FEATURE_CHECK_LDFLAGS-libbabeltrace)
+$(OUTPUT)test-babeltrace2-ctf-writer.bin:
+ $(BUILD) # -lbabeltrace2-ctf-writer provided by $(FEATURE_CHECK_LDFLAGS-babeltrace2-ctf-writer)
$(OUTPUT)test-libcapstone.bin:
$(BUILD) # -lcapstone provided by $(FEATURE_CHECK_LDFLAGS-libcapstone)
diff --git a/tools/build/feature/test-all.c b/tools/build/feature/test-all.c
index 1488bf6e6078..145abdee049d 100644
--- a/tools/build/feature/test-all.c
+++ b/tools/build/feature/test-all.c
@@ -98,17 +98,9 @@
# include "test-sched_getcpu.c"
#undef main
-# if 0
-/*
- * Disable libbabeltrace check for test-all, because the requested
- * library version is not released yet in most distributions. Will
- * reenable later.
- */
-
-#define main main_test_libbabeltrace
-# include "test-libbabeltrace.c"
+#define main main_test_babeltrace2_ctf_writer
+# include "test-babeltrace2-ctf-writer.c"
#undef main
-#endif
#define main main_test_lzma
# include "test-lzma.c"
@@ -178,6 +170,7 @@ int main(int argc, char *argv[])
main_test_libzstd();
main_test_libtraceevent();
main_test_libopenssl();
+ main_test_babeltrace2_ctf_writer();
return 0;
}
diff --git a/tools/build/feature/test-libbabeltrace.c b/tools/build/feature/test-babeltrace2-ctf-writer.c
similarity index 59%
rename from tools/build/feature/test-libbabeltrace.c
rename to tools/build/feature/test-babeltrace2-ctf-writer.c
index 10bb69d55694..9c89082e9f88 100644
--- a/tools/build/feature/test-libbabeltrace.c
+++ b/tools/build/feature/test-babeltrace2-ctf-writer.c
@@ -1,7 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
-#include <babeltrace/ctf-writer/writer.h>
-#include <babeltrace/ctf-ir/stream-class.h>
+#include <babeltrace2-ctf-writer/writer.h>
int main(void)
{
diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
index 15fbba9f4ca8..f2f5051c94e3 100644
--- a/tools/perf/Makefile.config
+++ b/tools/perf/Makefile.config
@@ -196,13 +196,13 @@ FEATURE_CHECK_CFLAGS-libdw := $(LIBDW_CFLAGS)
FEATURE_CHECK_LDFLAGS-libdw := $(LIBDW_LDFLAGS) $(DWARFLIBS)
# for linking with debug library, run like:
-# make DEBUG=1 LIBBABELTRACE_DIR=/opt/libbabeltrace/
-ifdef LIBBABELTRACE_DIR
- LIBBABELTRACE_CFLAGS := -I$(LIBBABELTRACE_DIR)/include
- LIBBABELTRACE_LDFLAGS := -L$(LIBBABELTRACE_DIR)/lib
+# make DEBUG=1 PKG_CONFIG_PATH=/opt/babeltrace2/(lib|lib64)/pkgconfig
+
+ifneq ($(NO_BABELTRACE2),1)
+ ifeq ($(call get-executable,$(PKG_CONFIG)),)
+ $(error Error: $(PKG_CONFIG) needed by babeltrace2 is missing on this system, please install it)
+ endif
endif
-FEATURE_CHECK_CFLAGS-libbabeltrace := $(LIBBABELTRACE_CFLAGS)
-FEATURE_CHECK_LDFLAGS-libbabeltrace := $(LIBBABELTRACE_LDFLAGS) -lbabeltrace-ctf
# for linking with debug library, run like:
# make DEBUG=1 LIBCAPSTONE_DIR=/opt/capstone/
@@ -1058,15 +1058,15 @@ else
NO_PERF_READ_VDSOX32 := 1
endif
-ifndef NO_LIBBABELTRACE
- $(call feature_check,libbabeltrace)
- ifeq ($(feature-libbabeltrace), 1)
- CFLAGS += -DHAVE_LIBBABELTRACE_SUPPORT $(LIBBABELTRACE_CFLAGS)
- LDFLAGS += $(LIBBABELTRACE_LDFLAGS)
- EXTLIBS += -lbabeltrace-ctf
- $(call detected,CONFIG_LIBBABELTRACE)
+ifndef NO_BABELTRACE2
+ $(call feature_check,babeltrace2-ctf-writer)
+ ifeq ($(feature-babeltrace2-ctf-writer), 1)
+ CFLAGS += -DHAVE_BABELTRACE2_SUPPORT $(shell $(PKG_CONFIG) --cflags babeltrace2-ctf-writer)
+ LDFLAGS += $(shell $(PKG_CONFIG) --libs-only-L babeltrace2-ctf-writer)
+ EXTLIBS += $(shell $(PKG_CONFIG) --libs-only-l babeltrace2-ctf-writer)
+ $(call detected,CONFIG_BABELTRACE2)
else
- $(warning No libbabeltrace found, disables 'perf data' CTF format support, please install libbabeltrace-dev[el]/libbabeltrace-ctf-dev)
+ $(warning No babeltrace2 found, disables 'perf data' CTF format support, please install libbabeltrace2-dev[el])
endif
endif
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index f7b936deeaa2..1f4e84a8472e 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -79,7 +79,7 @@ include ../scripts/utilities.mak
#
# Define NO_ZLIB if you do not want to support compressed kernel modules
#
-# Define NO_LIBBABELTRACE if you do not want libbabeltrace support
+# Define NO_BABELTRACE2 if you do not want babeltrace2-ctf-writer support
# for CTF data format.
#
# Define NO_CAPSTONE if you do not want libcapstone support
diff --git a/tools/perf/builtin-check.c b/tools/perf/builtin-check.c
index 3641d263b345..e9d14a960a03 100644
--- a/tools/perf/builtin-check.c
+++ b/tools/perf/builtin-check.c
@@ -43,7 +43,7 @@ struct feature_status supported_features[] = {
FEATURE_STATUS("dwarf_getlocations", HAVE_LIBDW_SUPPORT),
FEATURE_STATUS("dwarf-unwind", HAVE_DWARF_UNWIND_SUPPORT),
FEATURE_STATUS_TIP("libbfd", HAVE_LIBBFD_SUPPORT, "Deprecated, license incompatibility, use BUILD_NONDISTRO=1 and install binutils-dev[el]"),
- FEATURE_STATUS("libbabeltrace", HAVE_LIBBABELTRACE_SUPPORT),
+ FEATURE_STATUS("babeltrace2-ctf-writer", HAVE_BABELTRACE2_SUPPORT),
FEATURE_STATUS("libbpf-strings", HAVE_LIBBPF_STRINGS_SUPPORT),
FEATURE_STATUS("libcapstone", HAVE_LIBCAPSTONE_SUPPORT),
FEATURE_STATUS("libdw-dwarf-unwind", HAVE_LIBDW_SUPPORT),
diff --git a/tools/perf/builtin-data.c b/tools/perf/builtin-data.c
index 85f59886b5cf..260d74476439 100644
--- a/tools/perf/builtin-data.c
+++ b/tools/perf/builtin-data.c
@@ -40,10 +40,8 @@ const struct option data_options[] = {
OPT_INCR('v', "verbose", &verbose, "be more verbose"),
OPT_STRING('i', "input", &input_name, "file", "input file name"),
OPT_STRING(0, "to-json", &to_json, NULL, "Convert to JSON format"),
-#ifdef HAVE_LIBBABELTRACE_SUPPORT
OPT_STRING(0, "to-ctf", &to_ctf, NULL, "Convert to CTF format"),
OPT_BOOLEAN(0, "tod", &opts.tod, "Convert time to wall clock time"),
-#endif
OPT_BOOLEAN('f', "force", &opts.force, "don't complain, do it"),
OPT_BOOLEAN(0, "all", &opts.all, "Convert all events"),
OPT_STRING(0, "time", &opts.time_str, "str",
@@ -65,29 +63,21 @@ static int cmd_data_convert(int argc, const char **argv)
pr_err("You cannot specify both --to-ctf and --to-json.\n");
return -1;
}
-#ifdef HAVE_LIBBABELTRACE_SUPPORT
if (!to_json && !to_ctf) {
pr_err("You must specify one of --to-ctf or --to-json.\n");
return -1;
}
-#else
- if (!to_json) {
- pr_err("You must specify --to-json.\n");
- return -1;
-}
-#endif
if (to_json)
return bt_convert__perf2json(input_name, to_json, &opts);
if (to_ctf) {
-#if defined(HAVE_LIBBABELTRACE_SUPPORT) && defined(HAVE_LIBTRACEEVENT)
+#if defined(HAVE_BABELTRACE2_SUPPORT) && defined(HAVE_LIBTRACEEVENT)
return bt_convert__perf2ctf(input_name, to_ctf, &opts);
#else
- pr_err("The libbabeltrace support is not compiled in. perf should be "
- "compiled with environment variables LIBBABELTRACE=1 and "
- "LIBBABELTRACE_DIR=/path/to/libbabeltrace/.\n"
- "Check also if libbtraceevent devel files are available.\n");
+ pr_err("The babeltrace2 support is not compiled in. Ensure you have both\n"
+ "libbabeltrace2-dev[el] and libtraceevent-dev[el] installed or set\n"
+ "PKG_CONFIG_PATH to find a local installation of those libraries.\n");
return -1;
#endif
}
diff --git a/tools/perf/tests/make b/tools/perf/tests/make
index 6587dc326d1b..04f9b686cec0 100644
--- a/tools/perf/tests/make
+++ b/tools/perf/tests/make
@@ -93,7 +93,7 @@ make_no_libbpf := NO_LIBBPF=1
make_libbpf_dynamic := LIBBPF_DYNAMIC=1
make_no_libbpf_DEBUG := NO_LIBBPF=1 DEBUG=1
make_no_libllvm := NO_LIBLLVM=1
-make_with_babeltrace:= LIBBABELTRACE=1
+make_with_babeltrace2 := BABELTRACE2=1
make_with_coresight := CORESIGHT=1
make_no_sdt := NO_SDT=1
make_no_libpfm4 := NO_LIBPFM4=1
@@ -170,7 +170,7 @@ run += make_no_libbpf_DEBUG
run += make_no_libllvm
run += make_no_sdt
run += make_no_syscall_tbl
-run += make_with_babeltrace
+run += make_with_babeltrace2
run += make_with_coresight
run += make_with_clangllvm
run += make_no_libpfm4
diff --git a/tools/perf/tests/shell/test_perf_data_converter_ctf.sh b/tools/perf/tests/shell/test_perf_data_converter_ctf.sh
index 334eebc9945e..65d49a10c028 100755
--- a/tools/perf/tests/shell/test_perf_data_converter_ctf.sh
+++ b/tools/perf/tests/shell/test_perf_data_converter_ctf.sh
@@ -24,11 +24,11 @@ trap_cleanup()
}
trap trap_cleanup exit term int
-check_babeltrace_support()
+check_babeltrace2_support()
{
- if ! perf check feature libbabeltrace
+ if ! perf check feature babeltrace2-ctf-writer
then
- echo "perf not linked with libbabeltrace, skipping test"
+ echo "perf not linked with libbabeltrace2-ctf-writer, skipping test"
exit 2
fi
}
@@ -97,7 +97,7 @@ test_ctf_converter_pipe()
fi
}
-check_babeltrace_support
+check_babeltrace2_support
test_ctf_converter_file
test_ctf_converter_pipe
diff --git a/tools/perf/util/Build b/tools/perf/util/Build
index bcccad7487a9..7f3b67c8eeab 100644
--- a/tools/perf/util/Build
+++ b/tools/perf/util/Build
@@ -233,7 +233,7 @@ perf-util-$(CONFIG_LIBUNWIND_X86) += libunwind/x86_32.o
perf-util-$(CONFIG_LIBUNWIND_AARCH64) += libunwind/arm64.o
ifeq ($(CONFIG_LIBTRACEEVENT),y)
- perf-util-$(CONFIG_LIBBABELTRACE) += data-convert-bt.o
+ perf-util-$(CONFIG_BABELTRACE2) += data-convert-bt.o
endif
perf-util-y += data-convert-json.o
diff --git a/tools/perf/util/data-convert-bt.c b/tools/perf/util/data-convert-bt.c
index ba1c8e48d495..91d8cdc9e8c7 100644
--- a/tools/perf/util/data-convert-bt.c
+++ b/tools/perf/util/data-convert-bt.c
@@ -11,14 +11,13 @@
#include <linux/compiler.h>
#include <linux/kernel.h>
#include <linux/zalloc.h>
-#include <babeltrace/ctf-writer/writer.h>
-#include <babeltrace/ctf-writer/clock.h>
-#include <babeltrace/ctf-writer/stream.h>
-#include <babeltrace/ctf-writer/event.h>
-#include <babeltrace/ctf-writer/event-types.h>
-#include <babeltrace/ctf-writer/event-fields.h>
-#include <babeltrace/ctf-ir/utils.h>
-#include <babeltrace/ctf/events.h>
+#include <babeltrace2-ctf-writer/writer.h>
+#include <babeltrace2-ctf-writer/clock.h>
+#include <babeltrace2-ctf-writer/stream.h>
+#include <babeltrace2-ctf-writer/event.h>
+#include <babeltrace2-ctf-writer/event-types.h>
+#include <babeltrace2-ctf-writer/event-fields.h>
+#include <babeltrace2-ctf-writer/utils.h>
#include "asm/bug.h"
#include "data-convert.h"
#include "session.h"
@@ -121,13 +120,13 @@ static int value_set(struct bt_ctf_field_type *type,
}
if (sign) {
- ret = bt_ctf_field_signed_integer_set_value(field, val);
+ ret = bt_ctf_field_integer_signed_set_value(field, val);
if (ret) {
pr_err("failed to set field value %s\n", name);
goto err;
}
} else {
- ret = bt_ctf_field_unsigned_integer_set_value(field, val);
+ ret = bt_ctf_field_integer_unsigned_set_value(field, val);
if (ret) {
pr_err("failed to set field value %s\n", name);
goto err;
@@ -374,10 +373,10 @@ static int add_tracepoint_field_value(struct ctf_writer *cw,
data + offset + i * len, len);
if (!(flags & TEP_FIELD_IS_SIGNED))
- ret = bt_ctf_field_unsigned_integer_set_value(
+ ret = bt_ctf_field_integer_unsigned_set_value(
field, value_int);
else
- ret = bt_ctf_field_signed_integer_set_value(
+ ret = bt_ctf_field_integer_signed_set_value(
field, adjust_signedness(value_int, len));
}
@@ -471,7 +470,7 @@ add_bpf_output_values(struct bt_ctf_event_class *event_class,
goto put_len_type;
}
- ret = bt_ctf_field_unsigned_integer_set_value(len_field, nr_elements);
+ ret = bt_ctf_field_integer_unsigned_set_value(len_field, nr_elements);
if (ret) {
pr_err("failed to set field value for raw_len\n");
goto put_len_field;
@@ -500,7 +499,7 @@ add_bpf_output_values(struct bt_ctf_event_class *event_class,
struct bt_ctf_field *elem_field =
bt_ctf_field_sequence_get_field(seq_field, i);
- ret = bt_ctf_field_unsigned_integer_set_value(elem_field,
+ ret = bt_ctf_field_integer_unsigned_set_value(elem_field,
((u32 *)(sample->raw_data))[i]);
bt_ctf_field_put(elem_field);
@@ -545,7 +544,7 @@ add_callchain_output_values(struct bt_ctf_event_class *event_class,
goto put_len_type;
}
- ret = bt_ctf_field_unsigned_integer_set_value(len_field, nr_elements);
+ ret = bt_ctf_field_integer_unsigned_set_value(len_field, nr_elements);
if (ret) {
pr_err("failed to set field value for perf_callchain_size\n");
goto put_len_field;
@@ -575,7 +574,7 @@ add_callchain_output_values(struct bt_ctf_event_class *event_class,
struct bt_ctf_field *elem_field =
bt_ctf_field_sequence_get_field(seq_field, i);
- ret = bt_ctf_field_unsigned_integer_set_value(elem_field,
+ ret = bt_ctf_field_integer_unsigned_set_value(elem_field,
((u64 *)(callchain->ips))[i]);
bt_ctf_field_put(elem_field);
@@ -728,7 +727,7 @@ static struct ctf_stream *ctf_stream__create(struct ctf_writer *cw, int cpu)
goto out;
}
- ret = bt_ctf_field_unsigned_integer_set_value(cpu_field, (u32) cpu);
+ ret = bt_ctf_field_integer_unsigned_set_value(cpu_field, (u32) cpu);
if (ret) {
pr_err("Failed to update CPU number\n");
goto out;
diff --git a/tools/perf/util/data-convert.h b/tools/perf/util/data-convert.h
index ee651fa680a1..d174e6f2729d 100644
--- a/tools/perf/util/data-convert.h
+++ b/tools/perf/util/data-convert.h
@@ -11,10 +11,10 @@ struct perf_data_convert_opts {
const char *time_str;
};
-#ifdef HAVE_LIBBABELTRACE_SUPPORT
+#ifdef HAVE_BABELTRACE2_SUPPORT
int bt_convert__perf2ctf(const char *input_name, const char *to_ctf,
struct perf_data_convert_opts *opts);
-#endif /* HAVE_LIBBABELTRACE_SUPPORT */
+#endif /* HAVE_BABELTRACE2_SUPPORT */
int bt_convert__perf2json(const char *input_name, const char *to_ctf,
struct perf_data_convert_opts *opts);
--
2.47.3
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH] perf data ctf: replace libbabeltrace with babeltrace2-ctf-writer
2026-05-12 19:47 [PATCH] perf data ctf: replace libbabeltrace with babeltrace2-ctf-writer Michael Jeanson
@ 2026-05-12 21:54 ` Ian Rogers
2026-05-12 21:56 ` [PATCH 1/2] tools build: Add libbabeltrace2 feature test Ian Rogers
2026-05-13 14:14 ` [PATCH] perf data ctf: replace libbabeltrace with babeltrace2-ctf-writer Michael Jeanson
0 siblings, 2 replies; 5+ messages in thread
From: Ian Rogers @ 2026-05-12 21:54 UTC (permalink / raw)
To: Michael Jeanson
Cc: linux-kernel, linux-perf-users, Adrian Hunter, Alexander Shishkin,
Arnaldo Carvalho de Melo, Derek Foreman, Ingo Molnar, James Clark,
Jiri Olsa, Mark Rutland, Mathieu Desnoyers, Namhyung Kim,
Peter Zijlstra
On Tue, May 12, 2026 at 12:47 PM Michael Jeanson <mjeanson@efficios.com> wrote:
>
> The 1.x branch of Babeltrace has been superseded by 2.x in 2020 and has
> been unmaintained since 2022, efforts have started to remove it from
> popular distributions.
>
> Babeltrace 2.x offers a very similar 'ctf-writer' library that can be used
> with minimal changes for the '--to-ctf' feature and has been packaged
> since Debian 11 and Fedora 32.
>
> This patch replaces the 'libbabeltrace' build feature with
> 'babeltrace2-ctf-writer' using pkgconfig detection, adjusts the naming of
> the public headers and applies minor API cleanups.
>
> No changes to the output ctf traces, this API still implements version
> 1.8 of the CTF specification that can be read by either Babeltrace 1 / 2
> or any CTF compliant reader.
>
> Also remove some ifdefs in the cli option parsing to allow printing the
> helpful error message with '--to-ctf' when built without babeltrace2.
>
> Signed-off-by: Michael Jeanson <mjeanson@efficios.com>
> Cc: Adrian Hunter <adrian.hunter@intel.com>
> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
> Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
> Cc: Derek Foreman <derek.foreman@collabora.com>
> Cc: Ian Rogers <irogers@google.com>
> Cc: Ingo Molnar <mingo@redhat.com>
> Cc: James Clark <james.clark@linaro.org>
> Cc: Jiri Olsa <jolsa@kernel.org>
> Cc: Mark Rutland <mark.rutland@arm.com>
> Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
> Cc: Namhyung Kim <namhyung@kernel.org>
> Cc: Peter Zijlstra <peterz@infradead.org>
> ---
> tools/build/Makefile.feature | 5 +--
> tools/build/feature/Makefile | 6 ++--
> tools/build/feature/test-all.c | 13 ++------
> ...ltrace.c => test-babeltrace2-ctf-writer.c} | 3 +-
> tools/perf/Makefile.config | 28 ++++++++--------
> tools/perf/Makefile.perf | 2 +-
> tools/perf/builtin-check.c | 2 +-
> tools/perf/builtin-data.c | 18 +++-------
> tools/perf/tests/make | 4 +--
> .../shell/test_perf_data_converter_ctf.sh | 8 ++---
> tools/perf/util/Build | 2 +-
> tools/perf/util/data-convert-bt.c | 33 +++++++++----------
> tools/perf/util/data-convert.h | 4 +--
> 13 files changed, 55 insertions(+), 73 deletions(-)
> rename tools/build/feature/{test-libbabeltrace.c => test-babeltrace2-ctf-writer.c} (59%)
>
> diff --git a/tools/build/Makefile.feature b/tools/build/Makefile.feature
> index 0b7a7c38cb88..9e097144817e 100644
> --- a/tools/build/Makefile.feature
> +++ b/tools/build/Makefile.feature
> @@ -113,7 +113,7 @@ FEATURE_TESTS_EXTRA := \
> gtk2 \
> gtk2-infobar \
> hello \
> - libbabeltrace \
> + babeltrace2-ctf-writer \
> libcapstone \
> libbfd-liberty \
> libbfd-liberty-z \
> @@ -162,6 +162,7 @@ FEATURE_GROUP_MEMBERS-libbfd = libbfd-liberty libbfd-liberty-z
> # Declare list of feature dependency packages that provide pkg-config files.
> #
> FEATURE_PKG_CONFIG ?= \
> + babeltrace2-ctf-writer \
> libtraceevent \
> libtracefs
>
> @@ -208,7 +209,7 @@ ifeq ($(feature-all), 1)
> $(call feature_check,compile-32)
> $(call feature_check,compile-x32)
> $(call feature_check,bionic)
> - $(call feature_check,libbabeltrace)
> + $(call feature_check,babeltrace2-ctf-writer)
> else
> $(foreach feat,$(FEATURE_TESTS),$(call feature_check,$(feat)))
> endif
> diff --git a/tools/build/feature/Makefile b/tools/build/feature/Makefile
> index 1fbcb3ce74d2..7735e257c263 100644
> --- a/tools/build/feature/Makefile
> +++ b/tools/build/feature/Makefile
> @@ -48,7 +48,7 @@ FILES= \
> test-pthread-barrier.bin \
> test-stackprotector-all.bin \
> test-timerfd.bin \
> - test-libbabeltrace.bin \
> + test-babeltrace2-ctf-writer.bin \
> test-libcapstone.bin \
> test-compile-32.bin \
> test-compile-x32.bin \
> @@ -301,8 +301,8 @@ $(OUTPUT)test-backtrace.bin:
> $(OUTPUT)test-timerfd.bin:
> $(BUILD)
>
> -$(OUTPUT)test-libbabeltrace.bin:
> - $(BUILD) # -lbabeltrace provided by $(FEATURE_CHECK_LDFLAGS-libbabeltrace)
> +$(OUTPUT)test-babeltrace2-ctf-writer.bin:
> + $(BUILD) # -lbabeltrace2-ctf-writer provided by $(FEATURE_CHECK_LDFLAGS-babeltrace2-ctf-writer)
>
> $(OUTPUT)test-libcapstone.bin:
> $(BUILD) # -lcapstone provided by $(FEATURE_CHECK_LDFLAGS-libcapstone)
> diff --git a/tools/build/feature/test-all.c b/tools/build/feature/test-all.c
> index 1488bf6e6078..145abdee049d 100644
> --- a/tools/build/feature/test-all.c
> +++ b/tools/build/feature/test-all.c
> @@ -98,17 +98,9 @@
> # include "test-sched_getcpu.c"
> #undef main
>
> -# if 0
> -/*
> - * Disable libbabeltrace check for test-all, because the requested
> - * library version is not released yet in most distributions. Will
> - * reenable later.
> - */
> -
> -#define main main_test_libbabeltrace
> -# include "test-libbabeltrace.c"
> +#define main main_test_babeltrace2_ctf_writer
> +# include "test-babeltrace2-ctf-writer.c"
So I still think the comment about libbabeltrace is probably valid:
most distributions won't have it by default, so a separate test is
likely better than testing with test-all. You also need to update
FEATURE_TESTS_BASIFEATURE_TESTS_BASIC.
> #undef main
> -#endif
>
> #define main main_test_lzma
> # include "test-lzma.c"
> @@ -178,6 +170,7 @@ int main(int argc, char *argv[])
> main_test_libzstd();
> main_test_libtraceevent();
> main_test_libopenssl();
> + main_test_babeltrace2_ctf_writer();
>
> return 0;
> }
> diff --git a/tools/build/feature/test-libbabeltrace.c b/tools/build/feature/test-babeltrace2-ctf-writer.c
> similarity index 59%
> rename from tools/build/feature/test-libbabeltrace.c
> rename to tools/build/feature/test-babeltrace2-ctf-writer.c
> index 10bb69d55694..9c89082e9f88 100644
> --- a/tools/build/feature/test-libbabeltrace.c
> +++ b/tools/build/feature/test-babeltrace2-ctf-writer.c
> @@ -1,7 +1,6 @@
> // SPDX-License-Identifier: GPL-2.0
>
> -#include <babeltrace/ctf-writer/writer.h>
> -#include <babeltrace/ctf-ir/stream-class.h>
> +#include <babeltrace2-ctf-writer/writer.h>
>
> int main(void)
> {
> diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
> index 15fbba9f4ca8..f2f5051c94e3 100644
> --- a/tools/perf/Makefile.config
> +++ b/tools/perf/Makefile.config
> @@ -196,13 +196,13 @@ FEATURE_CHECK_CFLAGS-libdw := $(LIBDW_CFLAGS)
> FEATURE_CHECK_LDFLAGS-libdw := $(LIBDW_LDFLAGS) $(DWARFLIBS)
>
> # for linking with debug library, run like:
> -# make DEBUG=1 LIBBABELTRACE_DIR=/opt/libbabeltrace/
> -ifdef LIBBABELTRACE_DIR
> - LIBBABELTRACE_CFLAGS := -I$(LIBBABELTRACE_DIR)/include
> - LIBBABELTRACE_LDFLAGS := -L$(LIBBABELTRACE_DIR)/lib
> +# make DEBUG=1 PKG_CONFIG_PATH=/opt/babeltrace2/(lib|lib64)/pkgconfig
Delete?
> +
> +ifneq ($(NO_BABELTRACE2),1)
> + ifeq ($(call get-executable,$(PKG_CONFIG)),)
> + $(error Error: $(PKG_CONFIG) needed by babeltrace2 is missing on this system, please install it)
> + endif
> endif
> -FEATURE_CHECK_CFLAGS-libbabeltrace := $(LIBBABELTRACE_CFLAGS)
> -FEATURE_CHECK_LDFLAGS-libbabeltrace := $(LIBBABELTRACE_LDFLAGS) -lbabeltrace-ctf
>
> # for linking with debug library, run like:
> # make DEBUG=1 LIBCAPSTONE_DIR=/opt/capstone/
> @@ -1058,15 +1058,15 @@ else
> NO_PERF_READ_VDSOX32 := 1
> endif
>
> -ifndef NO_LIBBABELTRACE
> - $(call feature_check,libbabeltrace)
> - ifeq ($(feature-libbabeltrace), 1)
> - CFLAGS += -DHAVE_LIBBABELTRACE_SUPPORT $(LIBBABELTRACE_CFLAGS)
> - LDFLAGS += $(LIBBABELTRACE_LDFLAGS)
> - EXTLIBS += -lbabeltrace-ctf
> - $(call detected,CONFIG_LIBBABELTRACE)
> +ifndef NO_BABELTRACE2
> + $(call feature_check,babeltrace2-ctf-writer)
> + ifeq ($(feature-babeltrace2-ctf-writer), 1)
> + CFLAGS += -DHAVE_BABELTRACE2_SUPPORT $(shell $(PKG_CONFIG) --cflags babeltrace2-ctf-writer)
> + LDFLAGS += $(shell $(PKG_CONFIG) --libs-only-L babeltrace2-ctf-writer)
> + EXTLIBS += $(shell $(PKG_CONFIG) --libs-only-l babeltrace2-ctf-writer)
> + $(call detected,CONFIG_BABELTRACE2)
> else
> - $(warning No libbabeltrace found, disables 'perf data' CTF format support, please install libbabeltrace-dev[el]/libbabeltrace-ctf-dev)
> + $(warning No babeltrace2 found, disables 'perf data' CTF format support, please install libbabeltrace2-dev[el])
> endif
> endif
>
> diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
> index f7b936deeaa2..1f4e84a8472e 100644
> --- a/tools/perf/Makefile.perf
> +++ b/tools/perf/Makefile.perf
> @@ -79,7 +79,7 @@ include ../scripts/utilities.mak
> #
> # Define NO_ZLIB if you do not want to support compressed kernel modules
> #
> -# Define NO_LIBBABELTRACE if you do not want libbabeltrace support
> +# Define NO_BABELTRACE2 if you do not want babeltrace2-ctf-writer support
> # for CTF data format.
> #
> # Define NO_CAPSTONE if you do not want libcapstone support
> diff --git a/tools/perf/builtin-check.c b/tools/perf/builtin-check.c
> index 3641d263b345..e9d14a960a03 100644
> --- a/tools/perf/builtin-check.c
> +++ b/tools/perf/builtin-check.c
> @@ -43,7 +43,7 @@ struct feature_status supported_features[] = {
> FEATURE_STATUS("dwarf_getlocations", HAVE_LIBDW_SUPPORT),
> FEATURE_STATUS("dwarf-unwind", HAVE_DWARF_UNWIND_SUPPORT),
> FEATURE_STATUS_TIP("libbfd", HAVE_LIBBFD_SUPPORT, "Deprecated, license incompatibility, use BUILD_NONDISTRO=1 and install binutils-dev[el]"),
> - FEATURE_STATUS("libbabeltrace", HAVE_LIBBABELTRACE_SUPPORT),
> + FEATURE_STATUS("babeltrace2-ctf-writer", HAVE_BABELTRACE2_SUPPORT),
> FEATURE_STATUS("libbpf-strings", HAVE_LIBBPF_STRINGS_SUPPORT),
> FEATURE_STATUS("libcapstone", HAVE_LIBCAPSTONE_SUPPORT),
> FEATURE_STATUS("libdw-dwarf-unwind", HAVE_LIBDW_SUPPORT),
> diff --git a/tools/perf/builtin-data.c b/tools/perf/builtin-data.c
> index 85f59886b5cf..260d74476439 100644
> --- a/tools/perf/builtin-data.c
> +++ b/tools/perf/builtin-data.c
> @@ -40,10 +40,8 @@ const struct option data_options[] = {
> OPT_INCR('v', "verbose", &verbose, "be more verbose"),
> OPT_STRING('i', "input", &input_name, "file", "input file name"),
> OPT_STRING(0, "to-json", &to_json, NULL, "Convert to JSON format"),
> -#ifdef HAVE_LIBBABELTRACE_SUPPORT
> OPT_STRING(0, "to-ctf", &to_ctf, NULL, "Convert to CTF format"),
> OPT_BOOLEAN(0, "tod", &opts.tod, "Convert time to wall clock time"),
> -#endif
> OPT_BOOLEAN('f', "force", &opts.force, "don't complain, do it"),
> OPT_BOOLEAN(0, "all", &opts.all, "Convert all events"),
> OPT_STRING(0, "time", &opts.time_str, "str",
> @@ -65,29 +63,21 @@ static int cmd_data_convert(int argc, const char **argv)
> pr_err("You cannot specify both --to-ctf and --to-json.\n");
> return -1;
> }
> -#ifdef HAVE_LIBBABELTRACE_SUPPORT
> if (!to_json && !to_ctf) {
> pr_err("You must specify one of --to-ctf or --to-json.\n");
> return -1;
> }
> -#else
> - if (!to_json) {
> - pr_err("You must specify --to-json.\n");
> - return -1;
> -}
> -#endif
>
> if (to_json)
> return bt_convert__perf2json(input_name, to_json, &opts);
>
> if (to_ctf) {
> -#if defined(HAVE_LIBBABELTRACE_SUPPORT) && defined(HAVE_LIBTRACEEVENT)
> +#if defined(HAVE_BABELTRACE2_SUPPORT) && defined(HAVE_LIBTRACEEVENT)
> return bt_convert__perf2ctf(input_name, to_ctf, &opts);
> #else
> - pr_err("The libbabeltrace support is not compiled in. perf should be "
> - "compiled with environment variables LIBBABELTRACE=1 and "
> - "LIBBABELTRACE_DIR=/path/to/libbabeltrace/.\n"
> - "Check also if libbtraceevent devel files are available.\n");
> + pr_err("The babeltrace2 support is not compiled in. Ensure you have both\n"
> + "libbabeltrace2-dev[el] and libtraceevent-dev[el] installed or set\n"
> + "PKG_CONFIG_PATH to find a local installation of those libraries.\n");
> return -1;
> #endif
> }
> diff --git a/tools/perf/tests/make b/tools/perf/tests/make
> index 6587dc326d1b..04f9b686cec0 100644
> --- a/tools/perf/tests/make
> +++ b/tools/perf/tests/make
> @@ -93,7 +93,7 @@ make_no_libbpf := NO_LIBBPF=1
> make_libbpf_dynamic := LIBBPF_DYNAMIC=1
> make_no_libbpf_DEBUG := NO_LIBBPF=1 DEBUG=1
> make_no_libllvm := NO_LIBLLVM=1
> -make_with_babeltrace:= LIBBABELTRACE=1
> +make_with_babeltrace2 := BABELTRACE2=1
> make_with_coresight := CORESIGHT=1
> make_no_sdt := NO_SDT=1
> make_no_libpfm4 := NO_LIBPFM4=1
> @@ -170,7 +170,7 @@ run += make_no_libbpf_DEBUG
> run += make_no_libllvm
> run += make_no_sdt
> run += make_no_syscall_tbl
> -run += make_with_babeltrace
> +run += make_with_babeltrace2
> run += make_with_coresight
> run += make_with_clangllvm
> run += make_no_libpfm4
> diff --git a/tools/perf/tests/shell/test_perf_data_converter_ctf.sh b/tools/perf/tests/shell/test_perf_data_converter_ctf.sh
> index 334eebc9945e..65d49a10c028 100755
> --- a/tools/perf/tests/shell/test_perf_data_converter_ctf.sh
> +++ b/tools/perf/tests/shell/test_perf_data_converter_ctf.sh
> @@ -24,11 +24,11 @@ trap_cleanup()
> }
> trap trap_cleanup exit term int
>
> -check_babeltrace_support()
> +check_babeltrace2_support()
> {
> - if ! perf check feature libbabeltrace
> + if ! perf check feature babeltrace2-ctf-writer
> then
> - echo "perf not linked with libbabeltrace, skipping test"
> + echo "perf not linked with libbabeltrace2-ctf-writer, skipping test"
> exit 2
> fi
> }
> @@ -97,7 +97,7 @@ test_ctf_converter_pipe()
> fi
> }
>
> -check_babeltrace_support
> +check_babeltrace2_support
> test_ctf_converter_file
> test_ctf_converter_pipe
>
> diff --git a/tools/perf/util/Build b/tools/perf/util/Build
> index bcccad7487a9..7f3b67c8eeab 100644
> --- a/tools/perf/util/Build
> +++ b/tools/perf/util/Build
> @@ -233,7 +233,7 @@ perf-util-$(CONFIG_LIBUNWIND_X86) += libunwind/x86_32.o
> perf-util-$(CONFIG_LIBUNWIND_AARCH64) += libunwind/arm64.o
>
> ifeq ($(CONFIG_LIBTRACEEVENT),y)
> - perf-util-$(CONFIG_LIBBABELTRACE) += data-convert-bt.o
> + perf-util-$(CONFIG_BABELTRACE2) += data-convert-bt.o
> endif
>
> perf-util-y += data-convert-json.o
> diff --git a/tools/perf/util/data-convert-bt.c b/tools/perf/util/data-convert-bt.c
> index ba1c8e48d495..91d8cdc9e8c7 100644
> --- a/tools/perf/util/data-convert-bt.c
> +++ b/tools/perf/util/data-convert-bt.c
> @@ -11,14 +11,13 @@
> #include <linux/compiler.h>
> #include <linux/kernel.h>
> #include <linux/zalloc.h>
> -#include <babeltrace/ctf-writer/writer.h>
> -#include <babeltrace/ctf-writer/clock.h>
> -#include <babeltrace/ctf-writer/stream.h>
> -#include <babeltrace/ctf-writer/event.h>
> -#include <babeltrace/ctf-writer/event-types.h>
> -#include <babeltrace/ctf-writer/event-fields.h>
> -#include <babeltrace/ctf-ir/utils.h>
> -#include <babeltrace/ctf/events.h>
> +#include <babeltrace2-ctf-writer/writer.h>
> +#include <babeltrace2-ctf-writer/clock.h>
> +#include <babeltrace2-ctf-writer/stream.h>
> +#include <babeltrace2-ctf-writer/event.h>
> +#include <babeltrace2-ctf-writer/event-types.h>
> +#include <babeltrace2-ctf-writer/event-fields.h>
> +#include <babeltrace2-ctf-writer/utils.h>
This is cool, I'm surprised at how non-invasive the change is. I'd
done a similar thing but keeping both babeltrace 1 and 2. I'll post my
WIP in reply just as a heads up, but I have to do much more heavy
engineering.
Thanks,
Ian
> #include "asm/bug.h"
> #include "data-convert.h"
> #include "session.h"
> @@ -121,13 +120,13 @@ static int value_set(struct bt_ctf_field_type *type,
> }
>
> if (sign) {
> - ret = bt_ctf_field_signed_integer_set_value(field, val);
> + ret = bt_ctf_field_integer_signed_set_value(field, val);
> if (ret) {
> pr_err("failed to set field value %s\n", name);
> goto err;
> }
> } else {
> - ret = bt_ctf_field_unsigned_integer_set_value(field, val);
> + ret = bt_ctf_field_integer_unsigned_set_value(field, val);
> if (ret) {
> pr_err("failed to set field value %s\n", name);
> goto err;
> @@ -374,10 +373,10 @@ static int add_tracepoint_field_value(struct ctf_writer *cw,
> data + offset + i * len, len);
>
> if (!(flags & TEP_FIELD_IS_SIGNED))
> - ret = bt_ctf_field_unsigned_integer_set_value(
> + ret = bt_ctf_field_integer_unsigned_set_value(
> field, value_int);
> else
> - ret = bt_ctf_field_signed_integer_set_value(
> + ret = bt_ctf_field_integer_signed_set_value(
> field, adjust_signedness(value_int, len));
> }
>
> @@ -471,7 +470,7 @@ add_bpf_output_values(struct bt_ctf_event_class *event_class,
> goto put_len_type;
> }
>
> - ret = bt_ctf_field_unsigned_integer_set_value(len_field, nr_elements);
> + ret = bt_ctf_field_integer_unsigned_set_value(len_field, nr_elements);
> if (ret) {
> pr_err("failed to set field value for raw_len\n");
> goto put_len_field;
> @@ -500,7 +499,7 @@ add_bpf_output_values(struct bt_ctf_event_class *event_class,
> struct bt_ctf_field *elem_field =
> bt_ctf_field_sequence_get_field(seq_field, i);
>
> - ret = bt_ctf_field_unsigned_integer_set_value(elem_field,
> + ret = bt_ctf_field_integer_unsigned_set_value(elem_field,
> ((u32 *)(sample->raw_data))[i]);
>
> bt_ctf_field_put(elem_field);
> @@ -545,7 +544,7 @@ add_callchain_output_values(struct bt_ctf_event_class *event_class,
> goto put_len_type;
> }
>
> - ret = bt_ctf_field_unsigned_integer_set_value(len_field, nr_elements);
> + ret = bt_ctf_field_integer_unsigned_set_value(len_field, nr_elements);
> if (ret) {
> pr_err("failed to set field value for perf_callchain_size\n");
> goto put_len_field;
> @@ -575,7 +574,7 @@ add_callchain_output_values(struct bt_ctf_event_class *event_class,
> struct bt_ctf_field *elem_field =
> bt_ctf_field_sequence_get_field(seq_field, i);
>
> - ret = bt_ctf_field_unsigned_integer_set_value(elem_field,
> + ret = bt_ctf_field_integer_unsigned_set_value(elem_field,
> ((u64 *)(callchain->ips))[i]);
>
> bt_ctf_field_put(elem_field);
> @@ -728,7 +727,7 @@ static struct ctf_stream *ctf_stream__create(struct ctf_writer *cw, int cpu)
> goto out;
> }
>
> - ret = bt_ctf_field_unsigned_integer_set_value(cpu_field, (u32) cpu);
> + ret = bt_ctf_field_integer_unsigned_set_value(cpu_field, (u32) cpu);
> if (ret) {
> pr_err("Failed to update CPU number\n");
> goto out;
> diff --git a/tools/perf/util/data-convert.h b/tools/perf/util/data-convert.h
> index ee651fa680a1..d174e6f2729d 100644
> --- a/tools/perf/util/data-convert.h
> +++ b/tools/perf/util/data-convert.h
> @@ -11,10 +11,10 @@ struct perf_data_convert_opts {
> const char *time_str;
> };
>
> -#ifdef HAVE_LIBBABELTRACE_SUPPORT
> +#ifdef HAVE_BABELTRACE2_SUPPORT
> int bt_convert__perf2ctf(const char *input_name, const char *to_ctf,
> struct perf_data_convert_opts *opts);
> -#endif /* HAVE_LIBBABELTRACE_SUPPORT */
> +#endif /* HAVE_BABELTRACE2_SUPPORT */
>
> int bt_convert__perf2json(const char *input_name, const char *to_ctf,
> struct perf_data_convert_opts *opts);
> --
> 2.47.3
>
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 1/2] tools build: Add libbabeltrace2 feature test
2026-05-12 21:54 ` Ian Rogers
@ 2026-05-12 21:56 ` Ian Rogers
2026-05-12 21:56 ` [PATCH 2/2] perf data convert ctf: Initial babeltrace2 support Ian Rogers
2026-05-13 14:14 ` [PATCH] perf data ctf: replace libbabeltrace with babeltrace2-ctf-writer Michael Jeanson
1 sibling, 1 reply; 5+ messages in thread
From: Ian Rogers @ 2026-05-12 21:56 UTC (permalink / raw)
To: irogers
Cc: acme, adrian.hunter, alexander.shishkin, derek.foreman,
james.clark, jolsa, linux-kernel, linux-perf-users, mark.rutland,
mathieu.desnoyers, mingo, mjeanson, namhyung
libbabeltrace2 is a rewrite libbabeltrace from 2020, add support for
detecting it so that perf builds may prefer using it to libbabeltrace
which dates from 2010.
Signed-off-by: Ian Rogers <irogers@google.com>
---
tools/build/Makefile.feature | 1 +
tools/build/feature/Makefile | 4 ++++
tools/build/feature/test-libbabeltrace2.c | 9 +++++++++
3 files changed, 14 insertions(+)
create mode 100644 tools/build/feature/test-libbabeltrace2.c
diff --git a/tools/build/Makefile.feature b/tools/build/Makefile.feature
index 2f192d3bf61b..5425430582d2 100644
--- a/tools/build/Makefile.feature
+++ b/tools/build/Makefile.feature
@@ -114,6 +114,7 @@ FEATURE_TESTS_EXTRA := \
gtk2-infobar \
hello \
libbabeltrace \
+ libbabeltrace2 \
libcapstone \
libcheck \
libbfd-liberty \
diff --git a/tools/build/feature/Makefile b/tools/build/feature/Makefile
index 704c687ed3ad..9cf00d3fbefb 100644
--- a/tools/build/feature/Makefile
+++ b/tools/build/feature/Makefile
@@ -49,6 +49,7 @@ FILES= \
test-stackprotector-all.bin \
test-timerfd.bin \
test-libbabeltrace.bin \
+ test-libbabeltrace2.bin \
test-libcapstone.bin \
test-libcheck.bin \
test-compile-32.bin \
@@ -311,6 +312,9 @@ $(OUTPUT)test-timerfd.bin:
$(OUTPUT)test-libbabeltrace.bin:
$(BUILD) # -lbabeltrace provided by $(FEATURE_CHECK_LDFLAGS-libbabeltrace)
+$(OUTPUT)test-libbabeltrace2.bin:
+ $(BUILD) # -lbabeltrace2 provided by $(FEATURE_CHECK_LDFLAGS-libbabeltrace2)
+
$(OUTPUT)test-libcapstone.bin:
$(BUILD) # -lcapstone provided by $(FEATURE_CHECK_LDFLAGS-libcapstone)
diff --git a/tools/build/feature/test-libbabeltrace2.c b/tools/build/feature/test-libbabeltrace2.c
new file mode 100644
index 000000000000..0c964994a34e
--- /dev/null
+++ b/tools/build/feature/test-libbabeltrace2.c
@@ -0,0 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <babeltrace2/babeltrace.h>
+
+int main(void)
+{
+ bt_graph_create(0);
+ return 0;
+}
--
2.54.0.563.g4f69b47b94-goog
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 2/2] perf data convert ctf: Initial babeltrace2 support
2026-05-12 21:56 ` [PATCH 1/2] tools build: Add libbabeltrace2 feature test Ian Rogers
@ 2026-05-12 21:56 ` Ian Rogers
0 siblings, 0 replies; 5+ messages in thread
From: Ian Rogers @ 2026-05-12 21:56 UTC (permalink / raw)
To: irogers
Cc: acme, adrian.hunter, alexander.shishkin, derek.foreman,
james.clark, jolsa, linux-kernel, linux-perf-users, mark.rutland,
mathieu.desnoyers, mingo, mjeanson, namhyung
The libbabeltrace support is incomplete but as libbabeltrace is no
longer developed it is hard to debug what is happening. Add some
minimal libbabeltrace2 support that allows logging. When the support
is comparable to the libbabeltrace 1 support it'd be worth dropping
the libbabeltrace 1 support.
Signed-off-by: Ian Rogers <irogers@google.com>
---
tools/perf/Makefile.config | 13 +-
tools/perf/util/data-convert-bt.c | 1044 ++++++++++++++++++++++++-----
tools/perf/util/data-convert.h | 2 +-
3 files changed, 878 insertions(+), 181 deletions(-)
diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
index 06d7a3f9990c..af70f9436586 100644
--- a/tools/perf/Makefile.config
+++ b/tools/perf/Makefile.config
@@ -203,6 +203,8 @@ ifdef LIBBABELTRACE_DIR
endif
FEATURE_CHECK_CFLAGS-libbabeltrace := $(LIBBABELTRACE_CFLAGS)
FEATURE_CHECK_LDFLAGS-libbabeltrace := $(LIBBABELTRACE_LDFLAGS) -lbabeltrace-ctf
+FEATURE_CHECK_CFLAGS-libbabeltrace2 := $(LIBBABELTRACE_CFLAGS)
+FEATURE_CHECK_LDFLAGS-libbabeltrace2 := $(LIBBABELTRACE_LDFLAGS) -lbabeltrace2
# for linking with debug library, run like:
# make DEBUG=1 LIBCAPSTONE_DIR=/opt/capstone/
@@ -1067,7 +1069,16 @@ ifndef NO_LIBBABELTRACE
EXTLIBS += -lbabeltrace-ctf
$(call detected,CONFIG_LIBBABELTRACE)
else
- $(warning No libbabeltrace found, disables 'perf data' CTF format support, please install libbabeltrace-dev[el]/libbabeltrace-ctf-dev)
+ $(call feature_check,libbabeltrace2)
+ ifeq ($(feature-libbabeltrace2), 1)
+ $(info Experimental libbabeltrace2 support enabled)
+ CFLAGS += -DHAVE_LIBBABELTRACE2_SUPPORT $(LIBBABELTRACE_CFLAGS)
+ LDFLAGS += $(LIBBABELTRACE_LDFLAGS)
+ EXTLIBS += -lbabeltrace2
+ $(call detected,CONFIG_LIBBABELTRACE)
+ else
+ $(warning No libbabeltrace found, disables 'perf data' CTF format support)
+ endif
endif
endif
diff --git a/tools/perf/util/data-convert-bt.c b/tools/perf/util/data-convert-bt.c
index 3b8f2df823a9..b16544f8b9b9 100644
--- a/tools/perf/util/data-convert-bt.c
+++ b/tools/perf/util/data-convert-bt.c
@@ -6,11 +6,34 @@
* Copyright (C) 2014, Sebastian Andrzej Siewior <bigeasy@linutronix.de>
*/
+#include "clockid.h"
+#include "config.h"
+#include "data-convert.h"
+#include "debug.h"
+#include "evlist.h"
+#include "evsel.h"
+#include "header.h"
+#include "machine.h"
+#include "session.h"
+#include "tool.h"
+#include "util.h"
+#include "sample.h"
+#include "time-utils.h"
+
#include <errno.h>
#include <inttypes.h>
+#include <internal/lib.h>
#include <linux/compiler.h>
+#include <linux/ctype.h>
+#include <linux/err.h>
#include <linux/kernel.h>
+#include <linux/time64.h>
#include <linux/zalloc.h>
+#include <perf/event.h>
+
+#ifdef HAVE_LIBBABELTRACE2_SUPPORT
+#include <babeltrace2/babeltrace.h>
+#elif defined(HAVE_LIBBABELTRACE_SUPPORT)
#include <babeltrace/ctf-writer/writer.h>
#include <babeltrace/ctf-writer/clock.h>
#include <babeltrace/ctf-writer/stream.h>
@@ -19,26 +42,8 @@
#include <babeltrace/ctf-writer/event-fields.h>
#include <babeltrace/ctf-ir/utils.h>
#include <babeltrace/ctf/events.h>
-#include "asm/bug.h"
-#include "data-convert.h"
-#include "session.h"
-#include "debug.h"
-#include "tool.h"
-#include "evlist.h"
-#include "evsel.h"
-#include "machine.h"
-#include "config.h"
-#include <linux/ctype.h>
-#include <linux/err.h>
-#include <linux/time64.h>
-#include "util.h"
-#include "clockid.h"
-#include "util/sample.h"
-#include "util/time-utils.h"
-#include "header.h"
-
-#ifdef HAVE_LIBTRACEEVENT
-#include <event-parse.h>
+#else
+#error "Missing libbabeltrace2/libbabeltrace support"
#endif
#define pr_N(n, fmt, ...) \
@@ -47,51 +52,91 @@
#define pr(fmt, ...) pr_N(1, pr_fmt(fmt), ##__VA_ARGS__)
#define pr2(fmt, ...) pr_N(2, pr_fmt(fmt), ##__VA_ARGS__)
-#define pr_time2(t, fmt, ...) pr_time_N(2, debug_data_convert, t, pr_fmt(fmt), ##__VA_ARGS__)
+#define STREAM_FLUSH_COUNT 100000
+#define QUEUE_SIZE 16384
+#define MAX_CPUS 4096
struct evsel_priv {
+#ifdef HAVE_LIBBABELTRACE2_SUPPORT
+ bt_event_class *event_class;
+#else
struct bt_ctf_event_class *event_class;
+#endif
};
-#define MAX_CPUS 4096
-
struct ctf_stream {
+#ifdef HAVE_LIBBABELTRACE2_SUPPORT
+ bt_stream *stream;
+ bt_packet *packet;
+#else
struct bt_ctf_stream *stream;
+#endif
int cpu;
u32 count;
};
struct ctf_writer {
- /* writer primitives */
- struct bt_ctf_writer *writer;
struct ctf_stream **stream;
int stream_cnt;
+#ifdef HAVE_LIBBABELTRACE2_SUPPORT
+ /* writer primitives */
+ bt_graph *graph;
+ const bt_component_source *source;
+ const bt_component_sink *sink;
+ bt_trace_class *trace_class;
+ bt_stream_class *stream_class;
+ bt_clock_class *clock_class;
+ bt_trace *trace;
+
+ /* runtime */
+ bt_self_component_source *self_comp;
+ bt_self_message_iterator *self_iter;
+
+ /* data types */
+ struct {
+ bt_field_class *s64;
+ bt_field_class *u64;
+ bt_field_class *s32;
+ bt_field_class *u32;
+ bt_field_class *string;
+ bt_field_class *u32_hex;
+ bt_field_class *u64_hex;
+ } data;
+
+ /* event classes */
+ bt_event_class *comm_class;
+ bt_event_class *exit_class;
+ bt_event_class *fork_class;
+ bt_event_class *mmap_class;
+ bt_event_class *mmap2_class;
+#else
+ /* writer primitives */
+ struct bt_ctf_writer *writer;
struct bt_ctf_stream_class *stream_class;
struct bt_ctf_clock *clock;
/* data types */
- union {
- struct {
- struct bt_ctf_field_type *s64;
- struct bt_ctf_field_type *u64;
- struct bt_ctf_field_type *s32;
- struct bt_ctf_field_type *u32;
- struct bt_ctf_field_type *string;
- struct bt_ctf_field_type *u32_hex;
- struct bt_ctf_field_type *u64_hex;
- };
- struct bt_ctf_field_type *array[6];
+ struct {
+ struct bt_ctf_field_type *s64;
+ struct bt_ctf_field_type *u64;
+ struct bt_ctf_field_type *s32;
+ struct bt_ctf_field_type *u32;
+ struct bt_ctf_field_type *string;
+ struct bt_ctf_field_type *u32_hex;
+ struct bt_ctf_field_type *u64_hex;
} data;
struct bt_ctf_event_class *comm_class;
struct bt_ctf_event_class *exit_class;
struct bt_ctf_event_class *fork_class;
struct bt_ctf_event_class *mmap_class;
struct bt_ctf_event_class *mmap2_class;
+#endif
};
struct convert {
struct perf_tool tool;
struct ctf_writer writer;
+ struct perf_session *session;
struct perf_time_interval *ptime_range;
int range_size;
@@ -101,11 +146,97 @@ struct convert {
u64 events_count;
u64 non_sample_count;
u64 skipped;
+ u64 last_ts;
/* Ordered events configured queue size. */
u64 queue_size;
+#ifdef HAVE_LIBBABELTRACE2_SUPPORT
+ /* message queue */
+ bt_message **queue;
+ unsigned int queue_head;
+ unsigned int queue_tail;
+ unsigned int queue_mask;
+#endif
+ bool finished;
+
};
+static void ctf_writer__cleanup(struct ctf_writer *cw);
+
+#ifdef HAVE_LIBBABELTRACE2_SUPPORT
+static int ctf_writer__flush_queue(struct convert *c)
+{
+ bt_graph_run_once_status status = bt_graph_run_once(c->writer.graph);
+
+ if (status == BT_GRAPH_RUN_ONCE_STATUS_OK)
+ return 0;
+ if (status == BT_GRAPH_RUN_ONCE_STATUS_AGAIN)
+ return 0; /* Should retry, but let's assume made progress or empty */
+ return -1;
+}
+
+static void queue_push(struct convert *c, bt_message *msg)
+{
+ unsigned int next_head = (c->queue_head + 1) & c->queue_mask;
+
+ while (next_head == c->queue_tail) {
+ /* Queue is full, drive the graph to consume */
+ if (ctf_writer__flush_queue(c) < 0)
+ break;
+ next_head = (c->queue_head + 1) & c->queue_mask;
+ }
+
+ c->queue[c->queue_head] = msg;
+ c->queue_head = next_head;
+}
+
+static bt_message *queue_pop(struct convert *c)
+{
+ bt_message *msg;
+
+ if (c->queue_head == c->queue_tail)
+ return NULL;
+
+ msg = c->queue[c->queue_tail];
+ c->queue_tail = (c->queue_tail + 1) & c->queue_mask;
+ return msg;
+}
+
+/* Helper to set field value */
+static int value_set(bt_field *field, u64 val)
+{
+ const bt_field_class *type = bt_field_borrow_class_const(field);
+ bt_field_class_type class_type = bt_field_class_get_type(type);
+
+ if (class_type == BT_FIELD_CLASS_TYPE_UNSIGNED_INTEGER ||
+ class_type == BT_FIELD_CLASS_TYPE_UNSIGNED_ENUMERATION) {
+ bt_field_integer_unsigned_set_value(field, val);
+ } else if (class_type == BT_FIELD_CLASS_TYPE_SIGNED_INTEGER ||
+ class_type == BT_FIELD_CLASS_TYPE_SIGNED_ENUMERATION) {
+ bt_field_integer_signed_set_value(field, (int64_t)val);
+ } else {
+ return -1;
+ }
+ return 0;
+}
+
+static int value_set_from_type(bt_event *event, const char *name, u64 val)
+{
+ bt_field *field = bt_event_borrow_payload_field(event);
+ bt_field *member;
+
+ if (!field) {
+ pr_err("failed to find payload field\n");
+ return -1;
+ }
+ member = bt_field_structure_borrow_member_field_by_name(field, name);
+ if (!member) {
+ pr_err("failed to find payload field %s\n", name);
+ return -1;
+ }
+ return value_set(member, val);
+}
+#else
static int value_set(struct bt_ctf_field_type *type,
struct bt_ctf_event *event,
const char *name, u64 val)
@@ -148,7 +279,7 @@ static int value_set(struct bt_ctf_field_type *type,
}
#define __FUNC_VALUE_SET(_name, _val_type) \
-static __maybe_unused int value_set_##_name(struct ctf_writer *cw, \
+static int value_set_##_name(struct ctf_writer *cw, \
struct bt_ctf_event *event, \
const char *name, \
_val_type val) \
@@ -161,12 +292,11 @@ static __maybe_unused int value_set_##_name(struct ctf_writer *cw, \
FUNC_VALUE_SET(s32)
FUNC_VALUE_SET(u32)
-FUNC_VALUE_SET(s64)
FUNC_VALUE_SET(u64)
__FUNC_VALUE_SET(u64_hex, u64)
static int string_set_value(struct bt_ctf_field *field, const char *string);
-static __maybe_unused int
+static int
value_set_string(struct ctf_writer *cw, struct bt_ctf_event *event,
const char *name, const char *string)
{
@@ -599,9 +729,14 @@ add_callchain_output_values(struct bt_ctf_event_class *event_class,
bt_ctf_field_type_put(len_type);
return ret;
}
+#endif
-static int add_generic_values(struct ctf_writer *cw,
+static int add_generic_values(struct ctf_writer *cw __maybe_unused,
+#ifdef HAVE_LIBBABELTRACE2_SUPPORT
+ bt_event *event,
+#else
struct bt_ctf_event *event,
+#endif
struct evsel *evsel,
struct perf_sample *sample)
{
@@ -620,56 +755,90 @@ static int add_generic_values(struct ctf_writer *cw,
*/
if (type & PERF_SAMPLE_IP) {
+#ifdef HAVE_LIBBABELTRACE2_SUPPORT
+ ret = value_set_from_type(event, "perf_ip", sample->ip);
+#else
ret = value_set_u64_hex(cw, event, "perf_ip", sample->ip);
+#endif
if (ret)
return -1;
}
if (type & PERF_SAMPLE_TID) {
+#ifdef HAVE_LIBBABELTRACE2_SUPPORT
+ ret = value_set_from_type(event, "perf_tid", sample->tid);
+#else
ret = value_set_s32(cw, event, "perf_tid", sample->tid);
+#endif
if (ret)
return -1;
+#ifdef HAVE_LIBBABELTRACE2_SUPPORT
+ ret = value_set_from_type(event, "perf_pid", sample->pid);
+#else
ret = value_set_s32(cw, event, "perf_pid", sample->pid);
+#endif
if (ret)
return -1;
}
if ((type & PERF_SAMPLE_ID) ||
(type & PERF_SAMPLE_IDENTIFIER)) {
+#ifdef HAVE_LIBBABELTRACE2_SUPPORT
+ ret = value_set_from_type(event, "perf_id", sample->id);
+#else
ret = value_set_u64(cw, event, "perf_id", sample->id);
+#endif
if (ret)
return -1;
}
if (type & PERF_SAMPLE_STREAM_ID) {
+#ifdef HAVE_LIBBABELTRACE2_SUPPORT
+ ret = value_set_from_type(event, "perf_stream_id", sample->stream_id);
+#else
ret = value_set_u64(cw, event, "perf_stream_id", sample->stream_id);
+#endif
if (ret)
return -1;
}
if (type & PERF_SAMPLE_PERIOD) {
+#ifdef HAVE_LIBBABELTRACE2_SUPPORT
+ ret = value_set_from_type(event, "perf_period", sample->period);
+#else
ret = value_set_u64(cw, event, "perf_period", sample->period);
+#endif
if (ret)
return -1;
}
if (type & PERF_SAMPLE_WEIGHT) {
+#ifdef HAVE_LIBBABELTRACE2_SUPPORT
+ ret = value_set_from_type(event, "perf_weight", sample->weight);
+#else
ret = value_set_u64(cw, event, "perf_weight", sample->weight);
+#endif
if (ret)
return -1;
}
if (type & PERF_SAMPLE_DATA_SRC) {
- ret = value_set_u64(cw, event, "perf_data_src",
- sample->data_src);
+#ifdef HAVE_LIBBABELTRACE2_SUPPORT
+ ret = value_set_from_type(event, "perf_data_src", sample->data_src);
+#else
+ ret = value_set_u64(cw, event, "perf_data_src", sample->data_src);
+#endif
if (ret)
return -1;
}
if (type & PERF_SAMPLE_TRANSACTION) {
- ret = value_set_u64(cw, event, "perf_transaction",
- sample->transaction);
+#ifdef HAVE_LIBBABELTRACE2_SUPPORT
+ ret = value_set_from_type(event, "perf_transaction", sample->transaction);
+#else
+ ret = value_set_u64(cw, event, "perf_transaction", sample->transaction);
+#endif
if (ret)
return -1;
}
@@ -677,24 +846,43 @@ static int add_generic_values(struct ctf_writer *cw,
return 0;
}
-static int ctf_stream__flush(struct ctf_stream *cs)
+static int ctf_stream__flush(struct convert *c __maybe_unused, struct ctf_stream *cs,
+ u64 time __maybe_unused)
{
- int err = 0;
+#ifdef HAVE_LIBBABELTRACE2_SUPPORT
+ struct ctf_writer *cw = &c->writer;
+ bt_message *msg;
- if (cs) {
- err = bt_ctf_stream_flush(cs->stream);
- if (err)
- pr_err("CTF stream %d flush failed\n", cs->cpu);
+ if (!cs->packet)
+ return 0;
- pr("Flush stream for cpu %d (%u samples)\n",
- cs->cpu, cs->count);
+ msg = bt_message_packet_end_create_with_default_clock_snapshot(cw->self_iter,
+ cs->packet, time);
+ if (!msg)
+ return -1;
- cs->count = 0;
- }
+ queue_push(c, msg);
+ bt_packet_put_ref(cs->packet);
+ cs->packet = NULL;
+ cs->count = 0;
+ return 0;
+#else
+ int err;
- return err;
+ if (!cs)
+ return 0;
+
+ err = bt_ctf_stream_flush(cs->stream);
+ if (err)
+ pr_err("CTF stream %d flush failed\n", cs->cpu);
+
+ pr("Flush stream for cpu %d (%u samples)\n", cs->cpu, cs->count);
+ cs->count = 0;
+ return err;
+#endif
}
+#ifndef HAVE_LIBBABELTRACE2_SUPPORT
static struct ctf_stream *ctf_stream__create(struct ctf_writer *cw, int cpu)
{
struct ctf_stream *cs;
@@ -757,16 +945,37 @@ static void ctf_stream__delete(struct ctf_stream *cs)
free(cs);
}
}
+#endif
-static struct ctf_stream *ctf_stream(struct ctf_writer *cw, int cpu)
+static struct ctf_stream *ctf_stream(struct convert *c, int cpu)
{
- struct ctf_stream *cs = cw->stream[cpu];
+ struct ctf_writer *cw = &c->writer;
+ struct ctf_stream *cs;
+
+ if (cpu >= cw->stream_cnt)
+ return NULL;
+ cs = cw->stream[cpu];
if (!cs) {
+#ifdef HAVE_LIBBABELTRACE2_SUPPORT
+ bt_message *msg;
+
+ cs = zalloc(sizeof(*cs));
+ if (!cs)
+ return NULL;
+ cs->cpu = cpu;
+ cs->stream = bt_stream_create_with_id(cw->stream_class, cw->trace, cpu);
+ if (!cs->stream) {
+ free(cs);
+ return NULL;
+ }
+ msg = bt_message_stream_beginning_create(cw->self_iter, cs->stream);
+ queue_push(c, msg);
+#else
cs = ctf_stream__create(cw, cpu);
+#endif
cw->stream[cpu] = cs;
}
-
return cs;
}
@@ -774,20 +983,47 @@ static int get_sample_cpu(struct ctf_writer *cw, struct perf_sample *sample,
struct evsel *evsel)
{
int cpu = 0;
-
if (evsel->core.attr.sample_type & PERF_SAMPLE_CPU)
cpu = sample->cpu;
- if (cpu > cw->stream_cnt) {
- pr_err("Event was recorded for CPU %d, limit is at %d.\n",
+ if (cpu < 0 || cpu >= cw->stream_cnt) {
+ pr_debug("Event recorded for CPU %d, limit is %d. Using CPU 0.\n",
cpu, cw->stream_cnt);
cpu = 0;
}
-
return cpu;
}
-#define STREAM_FLUSH_COUNT 100000
+#ifdef HAVE_LIBBABELTRACE2_SUPPORT
+static int ctf_stream__create_packet(struct convert *c, struct ctf_stream *cs, u64 time)
+{
+ struct ctf_writer *cw = &c->writer;
+ bt_message *msg;
+ bt_field *pc;
+
+ if (cs->packet)
+ return 0;
+
+ cs->packet = bt_packet_create(cs->stream);
+ if (!cs->packet)
+ return -1;
+
+ msg = bt_message_packet_beginning_create_with_default_clock_snapshot(cw->self_iter,
+ cs->packet, time);
+ if (!msg)
+ return -1;
+
+ pc = bt_packet_borrow_context_field(cs->packet);
+ if (pc) {
+ bt_field *cpu = bt_field_structure_borrow_member_field_by_name(pc, "cpu_id");
+ if (cpu)
+ bt_field_integer_unsigned_set_value(cpu, cs->cpu);
+ }
+
+ queue_push(c, msg);
+ return 0;
+}
+#endif
/*
* Currently we have no other way to determine the
@@ -810,28 +1046,60 @@ static int process_sample_event(const struct perf_tool *tool,
struct evsel_priv *priv = evsel->priv;
struct ctf_writer *cw = &c->writer;
struct ctf_stream *cs;
- struct bt_ctf_event_class *event_class;
+#ifdef HAVE_LIBBABELTRACE2_SUPPORT
+ bt_event *event;
+ bt_message *msg;
+#else
struct bt_ctf_event *event;
+#endif
int ret;
- unsigned long type = evsel->core.attr.sample_type;
- if (WARN_ONCE(!priv, "Failed to setup all events.\n"))
+ if (!priv) {
+ pr_warning_once("Failed to setup all events.\n");
return 0;
+ }
+
+#ifdef HAVE_LIBBABELTRACE2_SUPPORT
+ if (!cw->self_iter)
+ return 0;
+#endif
if (perf_time__ranges_skip_sample(c->ptime_range, c->range_num, sample->time)) {
- ++c->skipped;
+ c->skipped++;
return 0;
}
- event_class = priv->event_class;
-
- /* update stats */
c->events_count++;
c->events_size += _event->header.size;
+ c->last_ts = sample->time;
- pr_time2(sample->time, "sample %" PRIu64 "\n", c->events_count);
+ cs = ctf_stream(c, get_sample_cpu(cw, sample, evsel));
+ if (!cs)
+ return -1;
+
+ if (is_flush_needed(cs))
+ ctf_stream__flush(c, cs, sample->time);
+
+#ifdef HAVE_LIBBABELTRACE2_SUPPORT
+ if (ctf_stream__create_packet(c, cs, sample->time))
+ return -1;
- event = bt_ctf_event_create(event_class);
+ /* Create event with default clock snapshot if possible */
+ msg = bt_message_event_create_with_default_clock_snapshot(cw->self_iter,
+ priv->event_class,
+ cs->stream,
+ sample->time);
+ if (!msg)
+ return -1;
+
+ event = bt_message_event_borrow_event(msg);
+ /* bt_event_set_packet removed as it is implicit in message creation */
+
+ ret = add_generic_values(cw, event, evsel, sample);
+
+ queue_push(c, msg);
+#else
+ event = bt_ctf_event_create(priv->event_class);
if (!event) {
pr_err("Failed to create an CTF event\n");
return -1;
@@ -844,38 +1112,32 @@ static int process_sample_event(const struct perf_tool *tool,
return -1;
if (evsel->core.attr.type == PERF_TYPE_TRACEPOINT) {
- ret = add_tracepoint_values(cw, event_class, event,
+ ret = add_tracepoint_values(cw, priv->event_class, event,
evsel, sample);
if (ret)
return -1;
}
- if (type & PERF_SAMPLE_CALLCHAIN) {
- ret = add_callchain_output_values(event_class,
- event, sample->callchain);
+ if (evsel->core.attr.sample_type & PERF_SAMPLE_CALLCHAIN) {
+ ret = add_callchain_output_values(priv->event_class, event, sample->callchain);
if (ret)
return -1;
}
if (evsel__is_bpf_output(evsel)) {
- ret = add_bpf_output_values(event_class, event, sample);
+ ret = add_bpf_output_values(priv->event_class, event, sample);
if (ret)
return -1;
}
- cs = ctf_stream(cw, get_sample_cpu(cw, sample, evsel));
- if (cs) {
- if (is_flush_needed(cs))
- ctf_stream__flush(cs);
-
- cs->count++;
- bt_ctf_stream_append_event(cs->stream, event);
- }
-
+ bt_ctf_stream_append_event(cs->stream, event);
bt_ctf_event_put(event);
- return cs ? 0 : -1;
+#endif
+ cs->count++;
+ return ret;
}
+#ifndef HAVE_LIBBABELTRACE2_SUPPORT
#define __NON_SAMPLE_SET_FIELD(_name, _type, _field) \
do { \
ret = value_set_##_type(cw, event, #_field, _event->_name._field);\
@@ -906,10 +1168,10 @@ static int process_##_name##_event(const struct perf_tool *tool, \
\
bt_ctf_clock_set_time(cw->clock, sample->time); \
body \
- cs = ctf_stream(cw, 0); \
+ cs = ctf_stream(c, 0); \
if (cs) { \
if (is_flush_needed(cs)) \
- ctf_stream__flush(cs); \
+ ctf_stream__flush(c, cs, c->last_ts); \
\
cs->count++; \
bt_ctf_stream_append_event(cs->stream, event); \
@@ -989,7 +1251,22 @@ static char *change_name(char *name, char *orig_name, int dup)
free(name);
return new_name;
}
+#endif
+
+static int add_environment_string(struct ctf_writer *cw, const char *name, const char *value)
+{
+ if (!value)
+ return 0;
+#ifdef HAVE_LIBBABELTRACE2_SUPPORT
+ bt_trace_set_environment_entry_string(cw->trace, name, value);
+ return 0;
+#else
+ return bt_ctf_writer_add_environment_field(cw->writer, name, value);
+#endif
+}
+
+#ifndef HAVE_LIBBABELTRACE2_SUPPORT
static int event_class_add_field(struct bt_ctf_event_class *event_class,
struct bt_ctf_field_type *type,
struct tep_format_field *field)
@@ -1079,7 +1356,7 @@ static int add_tracepoint_types(struct ctf_writer *cw,
{
const struct tep_event *tp_format = evsel__tp_format(evsel);
struct tep_format_field *common_fields = tp_format ? tp_format->format.common_fields : NULL;
- struct tep_format_field *fields = tp_format ? tp_format->format.fields : NULL;
+ struct tep_format_field *fields = tp_format ? tp_format->format.fields : NULL;
int ret;
ret = add_tracepoint_fields_types(cw, common_fields, class);
@@ -1107,7 +1384,108 @@ static int add_bpf_output_types(struct ctf_writer *cw,
return bt_ctf_event_class_add_field(class, seq_type, "raw_data");
}
+#endif
+
+#ifdef HAVE_LIBBABELTRACE2_SUPPORT
+static bt_field_class *create_unsigned_int(bt_trace_class *tc, int size, bool hex) {
+ bt_field_class *fc = bt_field_class_integer_unsigned_create(tc);
+
+ bt_field_class_integer_set_field_value_range(fc, size);
+ if (hex) {
+ bt_field_class_integer_set_preferred_display_base(fc,
+ BT_FIELD_CLASS_INTEGER_PREFERRED_DISPLAY_BASE_HEXADECIMAL);
+ }
+ return fc;
+}
+
+static bt_field_class *create_signed_int(bt_trace_class *tc, int size) {
+ bt_field_class *fc = bt_field_class_integer_signed_create(tc);
+ bt_field_class_integer_set_field_value_range(fc, size);
+ return fc;
+}
+
+/* Component methods */
+static bt_component_class_get_supported_mip_versions_method_status
+source_get_supported_mip_versions(
+ bt_self_component_class_source *self_component_class __maybe_unused,
+ const bt_value *params __maybe_unused,
+ void *init_method_data __maybe_unused,
+ bt_logging_level logging_level __maybe_unused,
+ bt_integer_range_set_unsigned *supported_versions)
+{
+ bt_integer_range_set_add_range_status status;
+
+ status = bt_integer_range_set_unsigned_add_range(supported_versions, 0, 1);
+ if (status != BT_INTEGER_RANGE_SET_ADD_RANGE_STATUS_OK)
+ return BT_COMPONENT_CLASS_GET_SUPPORTED_MIP_VERSIONS_METHOD_STATUS_ERROR;
+
+ return BT_COMPONENT_CLASS_GET_SUPPORTED_MIP_VERSIONS_METHOD_STATUS_OK;
+}
+
+static int add_generic_types(struct ctf_writer *cw, struct evsel *evsel,
+ bt_event_class *event_class)
+{
+ bt_trace_class *tc = cw->trace_class;
+ u64 type = evsel->core.attr.sample_type;
+ bt_field_class *payload_fc = bt_event_class_borrow_payload_field_class(event_class);
+ bt_field_class *fc;
+
+ /*
+ * missing:
+ * PERF_SAMPLE_TIME - not needed as we have it in
+ * ctf event header
+ * PERF_SAMPLE_READ - TODO
+ * PERF_SAMPLE_CALLCHAIN - TODO
+ * PERF_SAMPLE_RAW - tracepoint fields and BPF output
+ * are handled separately
+ * PERF_SAMPLE_BRANCH_STACK - TODO
+ * PERF_SAMPLE_REGS_USER - TODO
+ * PERF_SAMPLE_STACK_USER - TODO
+ */
+
+#define ADD_FIELD(t, n) \
+ do { \
+ fc = t; \
+ if (!fc) return -1; \
+ if (bt_field_class_structure_append_member(payload_fc, n, fc)) { \
+ bt_field_class_put_ref(fc); \
+ pr_err("Failed to add field '%s';\n", n); \
+ return -1; \
+ } \
+ bt_field_class_put_ref(fc); \
+ } while (0)
+
+ if (type & PERF_SAMPLE_IP)
+ ADD_FIELD(create_unsigned_int(tc, 64, true), "perf_ip");
+
+ if (type & PERF_SAMPLE_TID) {
+ ADD_FIELD(create_signed_int(tc, 32), "perf_tid");
+ ADD_FIELD(create_signed_int(tc, 32), "perf_pid");
+ }
+
+ if ((type & PERF_SAMPLE_ID) ||
+ (type & PERF_SAMPLE_IDENTIFIER))
+ ADD_FIELD(create_unsigned_int(tc, 64, false), "perf_id");
+
+ if (type & PERF_SAMPLE_STREAM_ID)
+ ADD_FIELD(create_unsigned_int(tc, 64, false), "perf_stream_id");
+
+ if (type & PERF_SAMPLE_PERIOD)
+ ADD_FIELD(create_unsigned_int(tc, 64, false), "perf_period");
+
+ if (type & PERF_SAMPLE_WEIGHT)
+ ADD_FIELD(create_unsigned_int(tc, 64, false), "perf_weight");
+
+ if (type & PERF_SAMPLE_DATA_SRC)
+ ADD_FIELD(create_unsigned_int(tc, 64, false), "perf_data_src");
+ if (type & PERF_SAMPLE_TRANSACTION)
+ ADD_FIELD(create_unsigned_int(tc, 64, false), "perf_transaction");
+
+#undef ADD_FIELD
+ return 0;
+}
+#else
static int add_generic_types(struct ctf_writer *cw, struct evsel *evsel,
struct bt_ctf_event_class *event_class)
{
@@ -1173,10 +1551,16 @@ static int add_generic_types(struct ctf_writer *cw, struct evsel *evsel,
#undef ADD_FIELD
return 0;
}
+#endif
static int add_event(struct ctf_writer *cw, struct evsel *evsel)
{
+#ifdef HAVE_LIBBABELTRACE2_SUPPORT
+ bt_event_class *event_class;
+ bt_field_class *fc;
+#else
struct bt_ctf_event_class *event_class;
+#endif
struct evsel_priv *priv;
const char *name = evsel__name(evsel);
int ret;
@@ -1187,31 +1571,62 @@ static int add_event(struct ctf_writer *cw, struct evsel *evsel)
}
pr("Adding event '%s' (type %d)\n", name, evsel->core.attr.type);
+#ifdef HAVE_LIBBABELTRACE2_SUPPORT
+ event_class = bt_event_class_create(cw->stream_class);
+ if (!event_class)
+ return -1;
+
+ if (bt_event_class_set_name(event_class, name)) {
+ pr_err("Failed to set event name\n");
+ goto err;
+ }
+
+ if (evsel->priv) {
+ bt_event_class_put_ref(event_class);
+ return 0;
+ }
+
+ fc = bt_field_class_structure_create(cw->trace_class);
+ if (!fc) goto err;
+ bt_event_class_set_payload_field_class(event_class, fc);
+ bt_field_class_put_ref(fc);
+#else
event_class = bt_ctf_event_class_create(name);
if (!event_class)
return -1;
+#endif
ret = add_generic_types(cw, evsel, event_class);
if (ret)
goto err;
if (evsel->core.attr.type == PERF_TYPE_TRACEPOINT) {
+#ifdef HAVE_LIBBABELTRACE2_SUPPORT
+ /* TODO: Add tracepoint types types */
+#else
ret = add_tracepoint_types(cw, evsel, event_class);
if (ret)
goto err;
+#endif
}
if (evsel__is_bpf_output(evsel)) {
+#ifdef HAVE_LIBBABELTRACE2_SUPPORT
+ /* TODO: Add BPF output types */
+#else
ret = add_bpf_output_types(cw, event_class);
if (ret)
goto err;
+#endif
}
+#ifndef HAVE_LIBBABELTRACE2_SUPPORT
ret = bt_ctf_stream_class_add_event_class(cw->stream_class, event_class);
if (ret) {
pr("Failed to add event class into stream.\n");
goto err;
}
+#endif
priv = malloc(sizeof(*priv));
if (!priv)
@@ -1222,7 +1637,11 @@ static int add_event(struct ctf_writer *cw, struct evsel *evsel)
return 0;
err:
+#ifdef HAVE_LIBBABELTRACE2_SUPPORT
+ bt_event_class_put_ref(event_class);
+#else
bt_ctf_event_class_put(event_class);
+#endif
pr_err("Failed to add event '%s'.\n", name);
return -1;
}
@@ -1256,6 +1675,7 @@ static int setup_events(struct ctf_writer *cw, struct perf_session *session,
return 0;
}
+#ifndef HAVE_LIBBABELTRACE2_SUPPORT
#define __NON_SAMPLE_ADD_FIELD(t, n) \
do { \
pr2(" field '%s'\n", #n); \
@@ -1348,6 +1768,7 @@ static int setup_non_sample_events(struct ctf_writer *cw,
return ret;
return 0;
}
+#endif
static void cleanup_events(struct perf_session *session)
{
@@ -1358,9 +1779,14 @@ static void cleanup_events(struct perf_session *session)
struct evsel_priv *priv;
priv = evsel->priv;
- if (priv)
+ if (priv) {
+#ifdef HAVE_LIBBABELTRACE2_SUPPORT
+ bt_event_class_put_ref(priv->event_class);
+#else
bt_ctf_event_class_put(priv->event_class);
- zfree(&evsel->priv);
+#endif
+ zfree(&evsel->priv);
+ }
}
evlist__delete(evlist);
@@ -1392,10 +1818,12 @@ static int setup_streams(struct ctf_writer *cw, struct perf_session *session)
static void free_streams(struct ctf_writer *cw)
{
+#ifndef HAVE_LIBBABELTRACE2_SUPPORT
int cpu;
for (cpu = 0; cpu < cw->stream_cnt; cpu++)
ctf_stream__delete(cw->stream[cpu]);
+#endif
zfree(&cw->stream);
}
@@ -1404,23 +1832,15 @@ static int ctf_writer__setup_env(struct ctf_writer *cw,
struct perf_session *session)
{
struct perf_env *env = perf_session__env(session);
- struct bt_ctf_writer *writer = cw->writer;
-#define ADD(__n, __v) \
-do { \
- if (__v && bt_ctf_writer_add_environment_field(writer, __n, __v)) \
- return -1; \
-} while (0)
-
- ADD("host", env->hostname);
- ADD("sysname", "Linux");
- ADD("release", env->os_release);
- ADD("version", env->version);
- ADD("machine", env->arch);
- ADD("domain", "kernel");
- ADD("tracer_name", "perf");
+ add_environment_string(cw, "host", env->hostname);
+ add_environment_string(cw, "sysname", "Linux");
+ add_environment_string(cw, "release", env->os_release);
+ add_environment_string(cw, "version", env->version);
+ add_environment_string(cw, "machine", env->arch);
+ add_environment_string(cw, "domain", "kernel");
+ add_environment_string(cw, "tracer_name", "perf");
-#undef ADD
return 0;
}
@@ -1450,33 +1870,16 @@ static int process_feature_event(const struct perf_tool *tool,
*/
return setup_events(cw, session, SETUP_EVENTS_NOT_TRACEPOINT);
case HEADER_HOSTNAME:
- if (session->header.env.hostname) {
- return bt_ctf_writer_add_environment_field(cw->writer, "host",
- session->header.env.hostname);
- }
- break;
+ return add_environment_string(cw, "host", session->header.env.hostname);
case HEADER_OSRELEASE:
- if (session->header.env.os_release) {
- return bt_ctf_writer_add_environment_field(cw->writer, "release",
- session->header.env.os_release);
- }
- break;
+ return add_environment_string(cw, "release", session->header.env.os_release);
case HEADER_VERSION:
- if (session->header.env.version) {
- return bt_ctf_writer_add_environment_field(cw->writer, "version",
- session->header.env.version);
- }
- break;
+ return add_environment_string(cw, "version", session->header.env.version);
case HEADER_ARCH:
- if (session->header.env.arch) {
- return bt_ctf_writer_add_environment_field(cw->writer, "machine",
- session->header.env.arch);
- }
- break;
+ return add_environment_string(cw, "machine", session->header.env.arch);
default:
- break;
+ return 0;
}
- return 0;
}
static int process_tracing_data(const struct perf_tool *tool,
@@ -1499,6 +1902,7 @@ static int process_tracing_data(const struct perf_tool *tool,
return setup_events(cw, session, SETUP_EVENTS_TRACEPOINT_ONLY);
}
+#ifndef HAVE_LIBBABELTRACE2_SUPPORT
static int ctf_writer__setup_clock(struct ctf_writer *cw,
struct perf_session *session,
bool tod)
@@ -1535,7 +1939,105 @@ do { \
#undef SET
return 0;
}
+#endif
+
+#ifdef HAVE_LIBBABELTRACE2_SUPPORT
+static int ctf_writer__setup_packet_context(struct ctf_writer *cw)
+{
+ bt_field_class *fc = bt_field_class_structure_create(cw->trace_class);
+ bt_field_class *cpu_fc = bt_field_class_integer_unsigned_create(cw->trace_class);
+ bt_field_class_integer_set_field_value_range(cpu_fc, 32);
+ bt_field_class_structure_append_member(fc, "cpu_id", cpu_fc);
+ bt_field_class_put_ref(cpu_fc);
+
+ bt_stream_class_set_packet_context_field_class(cw->stream_class, fc);
+ bt_field_class_put_ref(fc);
+ return 0;
+}
+
+static bt_component_class_initialize_method_status
+source_init(bt_self_component_source *self_comp,
+ bt_self_component_source_configuration *config __maybe_unused,
+ const bt_value *params __maybe_unused,
+ void *init_method_data)
+{
+ struct convert *c = init_method_data;
+ struct ctf_writer *cw = &c->writer;
+ cw->self_comp = self_comp;
+
+ bt_self_component_set_data(bt_self_component_source_as_self_component(self_comp), c);
+
+ /* Create trace class */
+ cw->trace_class = bt_trace_class_create(bt_self_component_source_as_self_component(self_comp));
+ if (!cw->trace_class) return BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_ERROR;
+
+ /* Create clock class */
+ cw->clock_class = bt_clock_class_create(bt_self_component_source_as_self_component(self_comp));
+ bt_clock_class_set_frequency(cw->clock_class, 1000000000);
+
+ /* Create stream class */
+ cw->stream_class = bt_stream_class_create(cw->trace_class);
+ bt_stream_class_set_assigns_automatic_stream_id(cw->stream_class, BT_FALSE);
+ bt_stream_class_set_default_clock_class(cw->stream_class, cw->clock_class);
+ bt_stream_class_set_supports_packets(cw->stream_class, BT_TRUE, BT_TRUE, BT_TRUE);
+
+ if (ctf_writer__setup_packet_context(cw))
+ return BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_ERROR;
+
+ /* Create trace */
+ cw->trace = bt_trace_create(cw->trace_class);
+
+ if (ctf_writer__setup_env(cw, c->session))
+ return BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_ERROR;
+
+ bt_self_component_source_add_output_port(self_comp, "out", NULL, NULL);
+ return BT_COMPONENT_CLASS_INITIALIZE_METHOD_STATUS_OK;
+}
+
+static bt_message_iterator_class_next_method_status
+iter_next(bt_self_message_iterator *self_iter,
+ bt_message_array_const msgs, uint64_t capacity,
+ uint64_t *count)
+{
+ struct convert *c = bt_self_message_iterator_get_data(self_iter);
+ bt_message *msg;
+ uint64_t i = 0;
+
+ if (!c->writer.self_iter)
+ c->writer.self_iter = self_iter;
+
+ while (i < capacity) {
+ msg = queue_pop(c);
+ if (!msg) {
+ if (c->finished) {
+ *count = i;
+ return i > 0 ? BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_OK :
+ BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_END;
+ }
+ break; /* Return what we have, or AGAIN */
+ }
+ msgs[i++] = msg;
+ }
+
+ *count = i;
+ if (i > 0)
+ return BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_OK;
+ return BT_MESSAGE_ITERATOR_CLASS_NEXT_METHOD_STATUS_AGAIN;
+}
+
+static bt_message_iterator_class_initialize_method_status
+iter_init(bt_self_message_iterator *self_iter,
+ bt_self_message_iterator_configuration *config __maybe_unused,
+ bt_self_component_port_output *port __maybe_unused)
+{
+ struct convert *c = bt_self_component_get_data(
+ bt_self_message_iterator_borrow_component(self_iter));
+ bt_self_message_iterator_set_data(self_iter, c);
+ c->writer.self_iter = self_iter;
+ return BT_MESSAGE_ITERATOR_CLASS_INITIALIZE_METHOD_STATUS_OK;
+}
+#else
static struct bt_ctf_field_type *create_int_type(int size, bool sign, bool hex)
{
struct bt_ctf_field_type *type;
@@ -1566,15 +2068,35 @@ static struct bt_ctf_field_type *create_int_type(int size, bool sign, bool hex)
bt_ctf_field_type_put(type);
return NULL;
}
+#endif
static void ctf_writer__cleanup_data(struct ctf_writer *cw)
{
- unsigned int i;
-
- for (i = 0; i < ARRAY_SIZE(cw->data.array); i++)
- bt_ctf_field_type_put(cw->data.array[i]);
+#ifdef HAVE_LIBBABELTRACE2_SUPPORT
+#define CLEANUP(type) \
+ if (cw->data.type) { \
+ bt_field_class_put_ref(cw->data.s64); \
+ cw->data.s64 = NULL; \
+ }
+#else
+#define CLEANUP(type) \
+ if (cw->data.type) { \
+ bt_ctf_field_type_put(cw->data.s64); \
+ cw->data.s64 = NULL; \
+ }
+#endif
+ CLEANUP(s64);
+ CLEANUP(u64);
+ CLEANUP(s32);
+ CLEANUP(u32);
+ CLEANUP(string);
+ CLEANUP(u32_hex);
+ CLEANUP(u64_hex);
+#undef CLEANUP
}
+
+#ifndef HAVE_LIBBABELTRACE2_SUPPORT
static int ctf_writer__init_data(struct ctf_writer *cw)
{
#define CREATE_INT_TYPE(type, size, sign, hex) \
@@ -1600,23 +2122,124 @@ do { \
pr_err("Failed to create data types.\n");
return -1;
}
+#endif
static void ctf_writer__cleanup(struct ctf_writer *cw)
{
+ /* Release data type field classes */
ctf_writer__cleanup_data(cw);
-
- bt_ctf_clock_put(cw->clock);
free_streams(cw);
+#ifdef HAVE_LIBBABELTRACE2_SUPPORT
+ if (cw->graph) {
+ bt_graph_put_ref(cw->graph);
+ cw->graph = NULL;
+ }
+ if (cw->source) {
+ bt_component_put_ref(bt_component_source_as_component_const(cw->source));
+ cw->source = NULL;
+ }
+ if (cw->sink) {
+ bt_component_put_ref(bt_component_sink_as_component_const(cw->sink));
+ cw->sink = NULL;
+ }
+ if (cw->trace) {
+ bt_trace_put_ref(cw->trace);
+ cw->trace = NULL;
+ }
+ if (cw->stream_class) {
+ bt_stream_class_put_ref(cw->stream_class);
+ cw->stream_class = NULL;
+ }
+ if (cw->clock_class) {
+ bt_clock_class_put_ref(cw->clock_class);
+ cw->clock_class = NULL;
+ }
+ if (cw->trace_class) {
+ bt_trace_class_put_ref(cw->trace_class);
+ cw->trace_class = NULL;
+ }
+#else
+ bt_ctf_clock_put(cw->clock);
bt_ctf_stream_class_put(cw->stream_class);
bt_ctf_writer_put(cw->writer);
/* and NULL all the pointers */
memset(cw, 0, sizeof(*cw));
+#endif
}
static int ctf_writer__init(struct ctf_writer *cw, const char *path,
- struct perf_session *session, bool tod)
+ struct perf_session *session __maybe_unused,
+ bool tod __maybe_unused, struct convert *c __maybe_unused)
{
+#ifdef HAVE_LIBBABELTRACE2_SUPPORT
+ bt_component_class_source *src_comp_class = NULL;
+ bt_message_iterator_class *iter_class = NULL;
+ bt_component_class_sink *sink_comp_class = NULL;
+ const bt_plugin *plugin = NULL;
+ bt_value *sink_params = NULL;
+ int status, err = -1;
+
+ /* Setup babeltrace2 graph */
+ cw->graph = bt_graph_create(1);
+ if (!cw->graph)
+ goto err;
+
+ iter_class = bt_message_iterator_class_create(iter_next);
+ bt_message_iterator_class_set_initialize_method(iter_class, iter_init);
+
+ src_comp_class = bt_component_class_source_create("perf", iter_class);
+ bt_component_class_source_set_initialize_method(src_comp_class, source_init);
+ bt_component_class_source_set_get_supported_mip_versions_method(src_comp_class, source_get_supported_mip_versions);
+
+ bt_graph_add_source_component_with_initialize_method_data(cw->graph, src_comp_class,
+ "perf_source", NULL, c,
+ BT_LOGGING_LEVEL_NONE,
+ &cw->source);
+
+ /* Sink */
+ bt_plugin_find("ctf", BT_TRUE, BT_TRUE, BT_TRUE, BT_TRUE, BT_TRUE, &plugin);
+ if (plugin) {
+ sink_comp_class = (bt_component_class_sink *) bt_plugin_borrow_sink_component_class_by_name_const(plugin, "fs");
+ bt_component_class_get_ref(bt_component_class_sink_as_component_class(sink_comp_class));
+ bt_plugin_put_ref(plugin);
+ }
+ if (!sink_comp_class) {
+ pr_err("Failed to find ctf.fs sink component\n");
+ goto err;
+ }
+
+ sink_params = bt_value_map_create();
+ bt_value_map_insert_string_entry(sink_params, "path", path);
+
+ status = bt_graph_add_sink_component(cw->graph, sink_comp_class, "ctf_sink", sink_params, BT_LOGGING_LEVEL_WARNING, (const bt_component_sink **) &cw->sink);
+ if (status < 0) {
+ pr_err("Failed to add ctf.fs sink component, status: %d\n", status);
+ goto err;
+ }
+ bt_value_put_ref(sink_params);
+
+ /* Connect */
+ bt_graph_connect_ports(cw->graph,
+ bt_component_source_borrow_output_port_by_index_const(cw->source, 0),
+ bt_component_sink_borrow_input_port_by_index_const(cw->sink, 0), NULL);
+
+ err = setup_streams(cw, session);
+err:
+ if (sink_comp_class)
+ bt_component_class_sink_put_ref(sink_comp_class);
+ if (src_comp_class)
+ bt_component_class_source_put_ref(src_comp_class);
+ if (iter_class)
+ bt_message_iterator_class_put_ref(iter_class);
+ return 0;
+
+ ctf_writer__cleanup(cw);
+ if (err)
+ pr_err("Failed to setup CTF writer.\n");
+ return err;
+
+#else
struct bt_ctf_writer *writer;
struct bt_ctf_stream_class *stream_class;
struct bt_ctf_clock *clock;
@@ -1678,21 +2301,62 @@ static int ctf_writer__init(struct ctf_writer *cw, const char *path,
goto err_cleanup;
}
- return 0;
+ /* CTF writer env setup */
+ if (ctf_writer__setup_env(cw, session))
+ goto err_cleanup;
+
+ ret = setup_streams(cw, session);
+ if (!ret)
+ return 0;
err_cleanup:
ctf_writer__cleanup(cw);
err:
pr_err("Failed to setup CTF writer.\n");
return -1;
+#endif
}
-static int ctf_writer__flush_streams(struct ctf_writer *cw)
+static int ctf_writer__flush_streams(struct convert *c)
{
- int cpu, ret = 0;
+ int cpu;
+ int ret = 0;
+
+ for (cpu = 0; cpu < c->writer.stream_cnt; cpu++) {
+ struct ctf_stream *cs = c->writer.stream[cpu];
+#ifdef HAVE_LIBBABELTRACE2_SUPPORT
+ bt_message *msg;
+#endif
+ if (!cs)
+ continue;
+
+ if (ctf_stream__flush(c, cs, c->last_ts)) {
+ ret = -1;
+ break;
+ }
+
+#ifdef HAVE_LIBBABELTRACE2_SUPPORT
+ /* Also end the stream */
+ msg = bt_message_stream_end_create(c->writer.self_iter, cs->stream);
+ if (!msg)
+ ret = -1;
+ else
+ queue_push(c, msg);
+
+ bt_stream_put_ref(cs->stream);
+ cs->stream = NULL;
+ free(cs);
+ c->writer.stream[cpu] = NULL;
+#endif
+ }
+
+#ifdef HAVE_LIBBABELTRACE2_SUPPORT
+ while (c->queue_head != c->queue_tail)
+ ctf_writer__flush_queue(c);
- for (cpu = 0; cpu < cw->stream_cnt && !ret; cpu++)
- ret = ctf_stream__flush(cw->stream[cpu]);
+ /* Run until end */
+ while (bt_graph_run_once(c->writer.graph) == BT_GRAPH_RUN_ONCE_STATUS_OK);
+#endif
return ret;
}
@@ -1707,6 +2371,13 @@ static int convert__config(const char *var, const char *value, void *cb)
return 0;
}
+static int process_finished_init_event(const struct perf_tool *tool __maybe_unused,
+ struct perf_session *session __maybe_unused,
+ union perf_event *event __maybe_unused)
+{
+ return 0;
+}
+
int bt_convert__perf2ctf(const char *input, const char *path,
struct perf_data_convert_opts *opts)
{
@@ -1716,10 +2387,19 @@ int bt_convert__perf2ctf(const char *input, const char *path,
.mode = PERF_DATA_MODE_READ,
.force = opts->force,
};
- struct convert c = {};
- struct ctf_writer *cw = &c.writer;
- int err;
+ struct convert c = {0};
+ int err = -1;
+
+ dump_trace = 1;
+ debug_data_convert = 3;
+ /* Setup queue */
+ c.queue_size = QUEUE_SIZE;
+#ifdef HAVE_LIBBABELTRACE2_SUPPORT
+ c.queue = zalloc(sizeof(bt_message *) * c.queue_size);
+ c.queue_mask = c.queue_size - 1;
+#endif
+ /* Setup tool */
perf_tool__init(&c.tool, /*ordered_events=*/true);
c.tool.sample = process_sample_event;
c.tool.mmap = perf_event__process_mmap;
@@ -1732,10 +2412,12 @@ int bt_convert__perf2ctf(const char *input, const char *path,
c.tool.build_id = perf_event__process_build_id;
c.tool.namespaces = perf_event__process_namespaces;
c.tool.finished_round = perf_event__process_finished_round;
+ c.tool.finished_init = process_finished_init_event;
c.tool.attr = perf_event__process_attr;
c.tool.feature = process_feature_event;
c.tool.ordering_requires_timestamps = true;
+#ifndef HAVE_LIBBABELTRACE2_SUPPORT
if (opts->all) {
c.tool.comm = process_comm_event;
c.tool.exit = process_exit_event;
@@ -1743,6 +2425,7 @@ int bt_convert__perf2ctf(const char *input, const char *path,
c.tool.mmap = process_mmap_event;
c.tool.mmap2 = process_mmap2_event;
}
+#endif
err = perf_config(convert__config, &c);
if (err)
@@ -1753,6 +2436,7 @@ int bt_convert__perf2ctf(const char *input, const char *path,
session = perf_session__new(&data, &c.tool);
if (IS_ERR(session))
return PTR_ERR(session);
+ c.session = session;
if (opts->time_str) {
err = perf_time__parse_for_ranges(opts->time_str, session,
@@ -1760,40 +2444,52 @@ int bt_convert__perf2ctf(const char *input, const char *path,
&c.range_size,
&c.range_num);
if (err < 0)
- goto free_session;
+ goto out;
}
/* CTF writer */
- if (ctf_writer__init(cw, path, session, opts->tod))
- goto free_session;
+ if (ctf_writer__init(&c.writer, path, session, opts->tod, &c))
+ goto out;
+
+#ifdef HAVE_LIBBABELTRACE2_SUPPORT
+ /* Run graph once to trigger iterator init */
+ while (!c.writer.self_iter) {
+ int status = bt_graph_run_once(c.writer.graph);
+
+ if (status != BT_GRAPH_RUN_ONCE_STATUS_OK && status != BT_GRAPH_RUN_ONCE_STATUS_AGAIN) {
+ pr_err("Failed to run graph for iterator init, status: %d\n", status);
+ goto out;
+ }
+ }
+#else
if (c.queue_size) {
ordered_events__set_alloc_size(&session->ordered_events,
c.queue_size);
}
-
- /* CTF writer env/clock setup */
- if (ctf_writer__setup_env(cw, session))
- goto free_writer;
+#endif
/*
* CTF events setup. Note, in pipe mode no events exist yet (they come
* in via header feature events) and so this does nothing.
*/
- if (setup_events(cw, session, SETUP_EVENTS_ALL))
- goto free_writer;
-
- if (opts->all && setup_non_sample_events(cw, session))
- goto free_writer;
+ if (setup_events(&c.writer, session, SETUP_EVENTS_ALL))
+ goto out;
- if (setup_streams(cw, session))
- goto free_writer;
+#ifndef HAVE_LIBBABELTRACE2_SUPPORT
+ if (opts->all && setup_non_sample_events(&c.writer, session))
+ goto out;
+#endif
+ /* Process events */
err = perf_session__process_events(session);
- if (!err)
- err = ctf_writer__flush_streams(cw);
- else
- pr_err("Error during conversion.\n");
+ if (err)
+ pr_err("Error during conversion (%d).\n", err);
+
+ /* Flush remaining */
+ c.finished = true;
+
+ err = ctf_writer__flush_streams(&c);
fprintf(stderr, "[ perf data convert: Converted '%s' into CTF data '%s' ]\n",
data.path, path);
@@ -1807,27 +2503,17 @@ int bt_convert__perf2ctf(const char *input, const char *path,
else
fprintf(stderr, ", %" PRIu64 " non-samples) ]\n", c.non_sample_count);
- if (c.skipped) {
- fprintf(stderr, "[ perf data convert: Skipped %" PRIu64 " samples ]\n",
- c.skipped);
- }
-
+ if (c.skipped)
+ fprintf(stderr, "[ perf data convert: Skipped %" PRIu64 " samples ]\n", c.skipped);
+out:
if (c.ptime_range)
zfree(&c.ptime_range);
cleanup_events(session);
perf_session__delete(session);
- ctf_writer__cleanup(cw);
-
- return err;
-
-free_writer:
- ctf_writer__cleanup(cw);
-free_session:
- if (c.ptime_range)
- zfree(&c.ptime_range);
-
- perf_session__delete(session);
- pr_err("Error during conversion setup.\n");
+ ctf_writer__cleanup(&c.writer);
+#ifndef HAVE_LIBBABELTRACE2_SUPPORT
+ ctf_writer__cleanup(&c.writer);
+#endif
return err;
}
diff --git a/tools/perf/util/data-convert.h b/tools/perf/util/data-convert.h
index ee651fa680a1..75c835496cbd 100644
--- a/tools/perf/util/data-convert.h
+++ b/tools/perf/util/data-convert.h
@@ -11,7 +11,7 @@ struct perf_data_convert_opts {
const char *time_str;
};
-#ifdef HAVE_LIBBABELTRACE_SUPPORT
+#if defined(HAVE_LIBBABELTRACE_SUPPORT) || defined(HAVE_LIBBABELTRACE2_SUPPORT)
int bt_convert__perf2ctf(const char *input_name, const char *to_ctf,
struct perf_data_convert_opts *opts);
#endif /* HAVE_LIBBABELTRACE_SUPPORT */
--
2.54.0.563.g4f69b47b94-goog
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH] perf data ctf: replace libbabeltrace with babeltrace2-ctf-writer
2026-05-12 21:54 ` Ian Rogers
2026-05-12 21:56 ` [PATCH 1/2] tools build: Add libbabeltrace2 feature test Ian Rogers
@ 2026-05-13 14:14 ` Michael Jeanson
1 sibling, 0 replies; 5+ messages in thread
From: Michael Jeanson @ 2026-05-13 14:14 UTC (permalink / raw)
To: Ian Rogers
Cc: linux-kernel, linux-perf-users, Adrian Hunter, Alexander Shishkin,
Arnaldo Carvalho de Melo, Derek Foreman, Ingo Molnar, James Clark,
Jiri Olsa, Mark Rutland, Mathieu Desnoyers, Namhyung Kim,
Peter Zijlstra
On 2026-05-12 17:54, Ian Rogers wrote:
> On Tue, May 12, 2026 at 12:47 PM Michael Jeanson <mjeanson@efficios.com> wrote:
>>
>> The 1.x branch of Babeltrace has been superseded by 2.x in 2020 and has
>> been unmaintained since 2022, efforts have started to remove it from
>> popular distributions.
>>
>> Babeltrace 2.x offers a very similar 'ctf-writer' library that can be used
>> with minimal changes for the '--to-ctf' feature and has been packaged
>> since Debian 11 and Fedora 32.
>>
>> This patch replaces the 'libbabeltrace' build feature with
>> 'babeltrace2-ctf-writer' using pkgconfig detection, adjusts the naming of
>> the public headers and applies minor API cleanups.
>>
>> No changes to the output ctf traces, this API still implements version
>> 1.8 of the CTF specification that can be read by either Babeltrace 1 / 2
>> or any CTF compliant reader.
>>
>> Also remove some ifdefs in the cli option parsing to allow printing the
>> helpful error message with '--to-ctf' when built without babeltrace2.
>>
>> Signed-off-by: Michael Jeanson <mjeanson@efficios.com>
>> Cc: Adrian Hunter <adrian.hunter@intel.com>
>> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
>> Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
>> Cc: Derek Foreman <derek.foreman@collabora.com>
>> Cc: Ian Rogers <irogers@google.com>
>> Cc: Ingo Molnar <mingo@redhat.com>
>> Cc: James Clark <james.clark@linaro.org>
>> Cc: Jiri Olsa <jolsa@kernel.org>
>> Cc: Mark Rutland <mark.rutland@arm.com>
>> Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
>> Cc: Namhyung Kim <namhyung@kernel.org>
>> Cc: Peter Zijlstra <peterz@infradead.org>
>> ---
>> tools/build/Makefile.feature | 5 +--
>> tools/build/feature/Makefile | 6 ++--
>> tools/build/feature/test-all.c | 13 ++------
>> ...ltrace.c => test-babeltrace2-ctf-writer.c} | 3 +-
>> tools/perf/Makefile.config | 28 ++++++++--------
>> tools/perf/Makefile.perf | 2 +-
>> tools/perf/builtin-check.c | 2 +-
>> tools/perf/builtin-data.c | 18 +++-------
>> tools/perf/tests/make | 4 +--
>> .../shell/test_perf_data_converter_ctf.sh | 8 ++---
>> tools/perf/util/Build | 2 +-
>> tools/perf/util/data-convert-bt.c | 33 +++++++++----------
>> tools/perf/util/data-convert.h | 4 +--
>> 13 files changed, 55 insertions(+), 73 deletions(-)
>> rename tools/build/feature/{test-libbabeltrace.c => test-babeltrace2-ctf-writer.c} (59%)
>>
>> diff --git a/tools/build/Makefile.feature b/tools/build/Makefile.feature
>> index 0b7a7c38cb88..9e097144817e 100644
>> --- a/tools/build/Makefile.feature
>> +++ b/tools/build/Makefile.feature
>> @@ -113,7 +113,7 @@ FEATURE_TESTS_EXTRA := \
>> gtk2 \
>> gtk2-infobar \
>> hello \
>> - libbabeltrace \
>> + babeltrace2-ctf-writer \
>> libcapstone \
>> libbfd-liberty \
>> libbfd-liberty-z \
>> @@ -162,6 +162,7 @@ FEATURE_GROUP_MEMBERS-libbfd = libbfd-liberty libbfd-liberty-z
>> # Declare list of feature dependency packages that provide pkg-config files.
>> #
>> FEATURE_PKG_CONFIG ?= \
>> + babeltrace2-ctf-writer \
>> libtraceevent \
>> libtracefs
>>
>> @@ -208,7 +209,7 @@ ifeq ($(feature-all), 1)
>> $(call feature_check,compile-32)
>> $(call feature_check,compile-x32)
>> $(call feature_check,bionic)
>> - $(call feature_check,libbabeltrace)
>> + $(call feature_check,babeltrace2-ctf-writer)
>> else
>> $(foreach feat,$(FEATURE_TESTS),$(call feature_check,$(feat)))
>> endif
>> diff --git a/tools/build/feature/Makefile b/tools/build/feature/Makefile
>> index 1fbcb3ce74d2..7735e257c263 100644
>> --- a/tools/build/feature/Makefile
>> +++ b/tools/build/feature/Makefile
>> @@ -48,7 +48,7 @@ FILES= \
>> test-pthread-barrier.bin \
>> test-stackprotector-all.bin \
>> test-timerfd.bin \
>> - test-libbabeltrace.bin \
>> + test-babeltrace2-ctf-writer.bin \
>> test-libcapstone.bin \
>> test-compile-32.bin \
>> test-compile-x32.bin \
>> @@ -301,8 +301,8 @@ $(OUTPUT)test-backtrace.bin:
>> $(OUTPUT)test-timerfd.bin:
>> $(BUILD)
>>
>> -$(OUTPUT)test-libbabeltrace.bin:
>> - $(BUILD) # -lbabeltrace provided by $(FEATURE_CHECK_LDFLAGS-libbabeltrace)
>> +$(OUTPUT)test-babeltrace2-ctf-writer.bin:
>> + $(BUILD) # -lbabeltrace2-ctf-writer provided by $(FEATURE_CHECK_LDFLAGS-babeltrace2-ctf-writer)
>>
>> $(OUTPUT)test-libcapstone.bin:
>> $(BUILD) # -lcapstone provided by $(FEATURE_CHECK_LDFLAGS-libcapstone)
>> diff --git a/tools/build/feature/test-all.c b/tools/build/feature/test-all.c
>> index 1488bf6e6078..145abdee049d 100644
>> --- a/tools/build/feature/test-all.c
>> +++ b/tools/build/feature/test-all.c
>> @@ -98,17 +98,9 @@
>> # include "test-sched_getcpu.c"
>> #undef main
>>
>> -# if 0
>> -/*
>> - * Disable libbabeltrace check for test-all, because the requested
>> - * library version is not released yet in most distributions. Will
>> - * reenable later.
>> - */
>> -
>> -#define main main_test_libbabeltrace
>> -# include "test-libbabeltrace.c"
>> +#define main main_test_babeltrace2_ctf_writer
>> +# include "test-babeltrace2-ctf-writer.c"
>
> So I still think the comment about libbabeltrace is probably valid:
> most distributions won't have it by default, so a separate test is
> likely better than testing with test-all. You also need to update
> FEATURE_TESTS_BASIFEATURE_TESTS_BASIC.
I went by the comment in 'Makefile.feature' that says features in
FEATURE_TESTS_EXTRA should be included in 'test-all.c'. I'll remove it.
>
>> #undef main
>> -#endif
>>
>> #define main main_test_lzma
>> # include "test-lzma.c"
>> @@ -178,6 +170,7 @@ int main(int argc, char *argv[])
>> main_test_libzstd();
>> main_test_libtraceevent();
>> main_test_libopenssl();
>> + main_test_babeltrace2_ctf_writer();
>>
>> return 0;
>> }
>> diff --git a/tools/build/feature/test-libbabeltrace.c b/tools/build/feature/test-babeltrace2-ctf-writer.c
>> similarity index 59%
>> rename from tools/build/feature/test-libbabeltrace.c
>> rename to tools/build/feature/test-babeltrace2-ctf-writer.c
>> index 10bb69d55694..9c89082e9f88 100644
>> --- a/tools/build/feature/test-libbabeltrace.c
>> +++ b/tools/build/feature/test-babeltrace2-ctf-writer.c
>> @@ -1,7 +1,6 @@
>> // SPDX-License-Identifier: GPL-2.0
>>
>> -#include <babeltrace/ctf-writer/writer.h>
>> -#include <babeltrace/ctf-ir/stream-class.h>
>> +#include <babeltrace2-ctf-writer/writer.h>
>>
>> int main(void)
>> {
>> diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config
>> index 15fbba9f4ca8..f2f5051c94e3 100644
>> --- a/tools/perf/Makefile.config
>> +++ b/tools/perf/Makefile.config
>> @@ -196,13 +196,13 @@ FEATURE_CHECK_CFLAGS-libdw := $(LIBDW_CFLAGS)
>> FEATURE_CHECK_LDFLAGS-libdw := $(LIBDW_LDFLAGS) $(DWARFLIBS)
>>
>> # for linking with debug library, run like:
>> -# make DEBUG=1 LIBBABELTRACE_DIR=/opt/libbabeltrace/
>> -ifdef LIBBABELTRACE_DIR
>> - LIBBABELTRACE_CFLAGS := -I$(LIBBABELTRACE_DIR)/include
>> - LIBBABELTRACE_LDFLAGS := -L$(LIBBABELTRACE_DIR)/lib
>> +# make DEBUG=1 PKG_CONFIG_PATH=/opt/babeltrace2/(lib|lib64)/pkgconfig
>
> Delete?
Sure.
>
>> +
>> +ifneq ($(NO_BABELTRACE2),1)
>> + ifeq ($(call get-executable,$(PKG_CONFIG)),)
>> + $(error Error: $(PKG_CONFIG) needed by babeltrace2 is missing on this system, please install it)
>> + endif
>> endif
>> -FEATURE_CHECK_CFLAGS-libbabeltrace := $(LIBBABELTRACE_CFLAGS)
>> -FEATURE_CHECK_LDFLAGS-libbabeltrace := $(LIBBABELTRACE_LDFLAGS) -lbabeltrace-ctf
>>
>> # for linking with debug library, run like:
>> # make DEBUG=1 LIBCAPSTONE_DIR=/opt/capstone/
>> @@ -1058,15 +1058,15 @@ else
>> NO_PERF_READ_VDSOX32 := 1
>> endif
>>
>> -ifndef NO_LIBBABELTRACE
>> - $(call feature_check,libbabeltrace)
>> - ifeq ($(feature-libbabeltrace), 1)
>> - CFLAGS += -DHAVE_LIBBABELTRACE_SUPPORT $(LIBBABELTRACE_CFLAGS)
>> - LDFLAGS += $(LIBBABELTRACE_LDFLAGS)
>> - EXTLIBS += -lbabeltrace-ctf
>> - $(call detected,CONFIG_LIBBABELTRACE)
>> +ifndef NO_BABELTRACE2
>> + $(call feature_check,babeltrace2-ctf-writer)
>> + ifeq ($(feature-babeltrace2-ctf-writer), 1)
>> + CFLAGS += -DHAVE_BABELTRACE2_SUPPORT $(shell $(PKG_CONFIG) --cflags babeltrace2-ctf-writer)
>> + LDFLAGS += $(shell $(PKG_CONFIG) --libs-only-L babeltrace2-ctf-writer)
>> + EXTLIBS += $(shell $(PKG_CONFIG) --libs-only-l babeltrace2-ctf-writer)
>> + $(call detected,CONFIG_BABELTRACE2)
>> else
>> - $(warning No libbabeltrace found, disables 'perf data' CTF format support, please install libbabeltrace-dev[el]/libbabeltrace-ctf-dev)
>> + $(warning No babeltrace2 found, disables 'perf data' CTF format support, please install libbabeltrace2-dev[el])
>> endif
>> endif
>>
>> diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
>> index f7b936deeaa2..1f4e84a8472e 100644
>> --- a/tools/perf/Makefile.perf
>> +++ b/tools/perf/Makefile.perf
>> @@ -79,7 +79,7 @@ include ../scripts/utilities.mak
>> #
>> # Define NO_ZLIB if you do not want to support compressed kernel modules
>> #
>> -# Define NO_LIBBABELTRACE if you do not want libbabeltrace support
>> +# Define NO_BABELTRACE2 if you do not want babeltrace2-ctf-writer support
>> # for CTF data format.
>> #
>> # Define NO_CAPSTONE if you do not want libcapstone support
>> diff --git a/tools/perf/builtin-check.c b/tools/perf/builtin-check.c
>> index 3641d263b345..e9d14a960a03 100644
>> --- a/tools/perf/builtin-check.c
>> +++ b/tools/perf/builtin-check.c
>> @@ -43,7 +43,7 @@ struct feature_status supported_features[] = {
>> FEATURE_STATUS("dwarf_getlocations", HAVE_LIBDW_SUPPORT),
>> FEATURE_STATUS("dwarf-unwind", HAVE_DWARF_UNWIND_SUPPORT),
>> FEATURE_STATUS_TIP("libbfd", HAVE_LIBBFD_SUPPORT, "Deprecated, license incompatibility, use BUILD_NONDISTRO=1 and install binutils-dev[el]"),
>> - FEATURE_STATUS("libbabeltrace", HAVE_LIBBABELTRACE_SUPPORT),
>> + FEATURE_STATUS("babeltrace2-ctf-writer", HAVE_BABELTRACE2_SUPPORT),
>> FEATURE_STATUS("libbpf-strings", HAVE_LIBBPF_STRINGS_SUPPORT),
>> FEATURE_STATUS("libcapstone", HAVE_LIBCAPSTONE_SUPPORT),
>> FEATURE_STATUS("libdw-dwarf-unwind", HAVE_LIBDW_SUPPORT),
>> diff --git a/tools/perf/builtin-data.c b/tools/perf/builtin-data.c
>> index 85f59886b5cf..260d74476439 100644
>> --- a/tools/perf/builtin-data.c
>> +++ b/tools/perf/builtin-data.c
>> @@ -40,10 +40,8 @@ const struct option data_options[] = {
>> OPT_INCR('v', "verbose", &verbose, "be more verbose"),
>> OPT_STRING('i', "input", &input_name, "file", "input file name"),
>> OPT_STRING(0, "to-json", &to_json, NULL, "Convert to JSON format"),
>> -#ifdef HAVE_LIBBABELTRACE_SUPPORT
>> OPT_STRING(0, "to-ctf", &to_ctf, NULL, "Convert to CTF format"),
>> OPT_BOOLEAN(0, "tod", &opts.tod, "Convert time to wall clock time"),
>> -#endif
>> OPT_BOOLEAN('f', "force", &opts.force, "don't complain, do it"),
>> OPT_BOOLEAN(0, "all", &opts.all, "Convert all events"),
>> OPT_STRING(0, "time", &opts.time_str, "str",
>> @@ -65,29 +63,21 @@ static int cmd_data_convert(int argc, const char **argv)
>> pr_err("You cannot specify both --to-ctf and --to-json.\n");
>> return -1;
>> }
>> -#ifdef HAVE_LIBBABELTRACE_SUPPORT
>> if (!to_json && !to_ctf) {
>> pr_err("You must specify one of --to-ctf or --to-json.\n");
>> return -1;
>> }
>> -#else
>> - if (!to_json) {
>> - pr_err("You must specify --to-json.\n");
>> - return -1;
>> -}
>> -#endif
>>
>> if (to_json)
>> return bt_convert__perf2json(input_name, to_json, &opts);
>>
>> if (to_ctf) {
>> -#if defined(HAVE_LIBBABELTRACE_SUPPORT) && defined(HAVE_LIBTRACEEVENT)
>> +#if defined(HAVE_BABELTRACE2_SUPPORT) && defined(HAVE_LIBTRACEEVENT)
>> return bt_convert__perf2ctf(input_name, to_ctf, &opts);
>> #else
>> - pr_err("The libbabeltrace support is not compiled in. perf should be "
>> - "compiled with environment variables LIBBABELTRACE=1 and "
>> - "LIBBABELTRACE_DIR=/path/to/libbabeltrace/.\n"
>> - "Check also if libbtraceevent devel files are available.\n");
>> + pr_err("The babeltrace2 support is not compiled in. Ensure you have both\n"
>> + "libbabeltrace2-dev[el] and libtraceevent-dev[el] installed or set\n"
>> + "PKG_CONFIG_PATH to find a local installation of those libraries.\n");
>> return -1;
>> #endif
>> }
>> diff --git a/tools/perf/tests/make b/tools/perf/tests/make
>> index 6587dc326d1b..04f9b686cec0 100644
>> --- a/tools/perf/tests/make
>> +++ b/tools/perf/tests/make
>> @@ -93,7 +93,7 @@ make_no_libbpf := NO_LIBBPF=1
>> make_libbpf_dynamic := LIBBPF_DYNAMIC=1
>> make_no_libbpf_DEBUG := NO_LIBBPF=1 DEBUG=1
>> make_no_libllvm := NO_LIBLLVM=1
>> -make_with_babeltrace:= LIBBABELTRACE=1
>> +make_with_babeltrace2 := BABELTRACE2=1
>> make_with_coresight := CORESIGHT=1
>> make_no_sdt := NO_SDT=1
>> make_no_libpfm4 := NO_LIBPFM4=1
>> @@ -170,7 +170,7 @@ run += make_no_libbpf_DEBUG
>> run += make_no_libllvm
>> run += make_no_sdt
>> run += make_no_syscall_tbl
>> -run += make_with_babeltrace
>> +run += make_with_babeltrace2
>> run += make_with_coresight
>> run += make_with_clangllvm
>> run += make_no_libpfm4
>> diff --git a/tools/perf/tests/shell/test_perf_data_converter_ctf.sh b/tools/perf/tests/shell/test_perf_data_converter_ctf.sh
>> index 334eebc9945e..65d49a10c028 100755
>> --- a/tools/perf/tests/shell/test_perf_data_converter_ctf.sh
>> +++ b/tools/perf/tests/shell/test_perf_data_converter_ctf.sh
>> @@ -24,11 +24,11 @@ trap_cleanup()
>> }
>> trap trap_cleanup exit term int
>>
>> -check_babeltrace_support()
>> +check_babeltrace2_support()
>> {
>> - if ! perf check feature libbabeltrace
>> + if ! perf check feature babeltrace2-ctf-writer
>> then
>> - echo "perf not linked with libbabeltrace, skipping test"
>> + echo "perf not linked with libbabeltrace2-ctf-writer, skipping test"
>> exit 2
>> fi
>> }
>> @@ -97,7 +97,7 @@ test_ctf_converter_pipe()
>> fi
>> }
>>
>> -check_babeltrace_support
>> +check_babeltrace2_support
>> test_ctf_converter_file
>> test_ctf_converter_pipe
>>
>> diff --git a/tools/perf/util/Build b/tools/perf/util/Build
>> index bcccad7487a9..7f3b67c8eeab 100644
>> --- a/tools/perf/util/Build
>> +++ b/tools/perf/util/Build
>> @@ -233,7 +233,7 @@ perf-util-$(CONFIG_LIBUNWIND_X86) += libunwind/x86_32.o
>> perf-util-$(CONFIG_LIBUNWIND_AARCH64) += libunwind/arm64.o
>>
>> ifeq ($(CONFIG_LIBTRACEEVENT),y)
>> - perf-util-$(CONFIG_LIBBABELTRACE) += data-convert-bt.o
>> + perf-util-$(CONFIG_BABELTRACE2) += data-convert-bt.o
>> endif
>>
>> perf-util-y += data-convert-json.o
>> diff --git a/tools/perf/util/data-convert-bt.c b/tools/perf/util/data-convert-bt.c
>> index ba1c8e48d495..91d8cdc9e8c7 100644
>> --- a/tools/perf/util/data-convert-bt.c
>> +++ b/tools/perf/util/data-convert-bt.c
>> @@ -11,14 +11,13 @@
>> #include <linux/compiler.h>
>> #include <linux/kernel.h>
>> #include <linux/zalloc.h>
>> -#include <babeltrace/ctf-writer/writer.h>
>> -#include <babeltrace/ctf-writer/clock.h>
>> -#include <babeltrace/ctf-writer/stream.h>
>> -#include <babeltrace/ctf-writer/event.h>
>> -#include <babeltrace/ctf-writer/event-types.h>
>> -#include <babeltrace/ctf-writer/event-fields.h>
>> -#include <babeltrace/ctf-ir/utils.h>
>> -#include <babeltrace/ctf/events.h>
>> +#include <babeltrace2-ctf-writer/writer.h>
>> +#include <babeltrace2-ctf-writer/clock.h>
>> +#include <babeltrace2-ctf-writer/stream.h>
>> +#include <babeltrace2-ctf-writer/event.h>
>> +#include <babeltrace2-ctf-writer/event-types.h>
>> +#include <babeltrace2-ctf-writer/event-fields.h>
>> +#include <babeltrace2-ctf-writer/utils.h>
>
> This is cool, I'm surprised at how non-invasive the change is. I'd
> done a similar thing but keeping both babeltrace 1 and 2. I'll post my
> WIP in reply just as a heads up, but I have to do much more heavy
> engineering.
I think I can rework this to try babeltrace2-ctf-writer first and fall
back on libbabeltrace1. The change is non-invasive because
bt2-ctf-writer is basically just a compat API for the ctf-writer of bt1
but it doesn't expose any of the new features of bt2.
Your WIP patch that uses the proper libbabeltrace2 API is definitely the
way to go for the long term. In the meantime would you like a v2 of this
patch?
Cheers,
Michael
>
> Thanks,
> Ian
>
>> #include "asm/bug.h"
>> #include "data-convert.h"
>> #include "session.h"
>> @@ -121,13 +120,13 @@ static int value_set(struct bt_ctf_field_type *type,
>> }
>>
>> if (sign) {
>> - ret = bt_ctf_field_signed_integer_set_value(field, val);
>> + ret = bt_ctf_field_integer_signed_set_value(field, val);
>> if (ret) {
>> pr_err("failed to set field value %s\n", name);
>> goto err;
>> }
>> } else {
>> - ret = bt_ctf_field_unsigned_integer_set_value(field, val);
>> + ret = bt_ctf_field_integer_unsigned_set_value(field, val);
>> if (ret) {
>> pr_err("failed to set field value %s\n", name);
>> goto err;
>> @@ -374,10 +373,10 @@ static int add_tracepoint_field_value(struct ctf_writer *cw,
>> data + offset + i * len, len);
>>
>> if (!(flags & TEP_FIELD_IS_SIGNED))
>> - ret = bt_ctf_field_unsigned_integer_set_value(
>> + ret = bt_ctf_field_integer_unsigned_set_value(
>> field, value_int);
>> else
>> - ret = bt_ctf_field_signed_integer_set_value(
>> + ret = bt_ctf_field_integer_signed_set_value(
>> field, adjust_signedness(value_int, len));
>> }
>>
>> @@ -471,7 +470,7 @@ add_bpf_output_values(struct bt_ctf_event_class *event_class,
>> goto put_len_type;
>> }
>>
>> - ret = bt_ctf_field_unsigned_integer_set_value(len_field, nr_elements);
>> + ret = bt_ctf_field_integer_unsigned_set_value(len_field, nr_elements);
>> if (ret) {
>> pr_err("failed to set field value for raw_len\n");
>> goto put_len_field;
>> @@ -500,7 +499,7 @@ add_bpf_output_values(struct bt_ctf_event_class *event_class,
>> struct bt_ctf_field *elem_field =
>> bt_ctf_field_sequence_get_field(seq_field, i);
>>
>> - ret = bt_ctf_field_unsigned_integer_set_value(elem_field,
>> + ret = bt_ctf_field_integer_unsigned_set_value(elem_field,
>> ((u32 *)(sample->raw_data))[i]);
>>
>> bt_ctf_field_put(elem_field);
>> @@ -545,7 +544,7 @@ add_callchain_output_values(struct bt_ctf_event_class *event_class,
>> goto put_len_type;
>> }
>>
>> - ret = bt_ctf_field_unsigned_integer_set_value(len_field, nr_elements);
>> + ret = bt_ctf_field_integer_unsigned_set_value(len_field, nr_elements);
>> if (ret) {
>> pr_err("failed to set field value for perf_callchain_size\n");
>> goto put_len_field;
>> @@ -575,7 +574,7 @@ add_callchain_output_values(struct bt_ctf_event_class *event_class,
>> struct bt_ctf_field *elem_field =
>> bt_ctf_field_sequence_get_field(seq_field, i);
>>
>> - ret = bt_ctf_field_unsigned_integer_set_value(elem_field,
>> + ret = bt_ctf_field_integer_unsigned_set_value(elem_field,
>> ((u64 *)(callchain->ips))[i]);
>>
>> bt_ctf_field_put(elem_field);
>> @@ -728,7 +727,7 @@ static struct ctf_stream *ctf_stream__create(struct ctf_writer *cw, int cpu)
>> goto out;
>> }
>>
>> - ret = bt_ctf_field_unsigned_integer_set_value(cpu_field, (u32) cpu);
>> + ret = bt_ctf_field_integer_unsigned_set_value(cpu_field, (u32) cpu);
>> if (ret) {
>> pr_err("Failed to update CPU number\n");
>> goto out;
>> diff --git a/tools/perf/util/data-convert.h b/tools/perf/util/data-convert.h
>> index ee651fa680a1..d174e6f2729d 100644
>> --- a/tools/perf/util/data-convert.h
>> +++ b/tools/perf/util/data-convert.h
>> @@ -11,10 +11,10 @@ struct perf_data_convert_opts {
>> const char *time_str;
>> };
>>
>> -#ifdef HAVE_LIBBABELTRACE_SUPPORT
>> +#ifdef HAVE_BABELTRACE2_SUPPORT
>> int bt_convert__perf2ctf(const char *input_name, const char *to_ctf,
>> struct perf_data_convert_opts *opts);
>> -#endif /* HAVE_LIBBABELTRACE_SUPPORT */
>> +#endif /* HAVE_BABELTRACE2_SUPPORT */
>>
>> int bt_convert__perf2json(const char *input_name, const char *to_ctf,
>> struct perf_data_convert_opts *opts);
>> --
>> 2.47.3
>>
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-05-13 14:14 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-12 19:47 [PATCH] perf data ctf: replace libbabeltrace with babeltrace2-ctf-writer Michael Jeanson
2026-05-12 21:54 ` Ian Rogers
2026-05-12 21:56 ` [PATCH 1/2] tools build: Add libbabeltrace2 feature test Ian Rogers
2026-05-12 21:56 ` [PATCH 2/2] perf data convert ctf: Initial babeltrace2 support Ian Rogers
2026-05-13 14:14 ` [PATCH] perf data ctf: replace libbabeltrace with babeltrace2-ctf-writer Michael Jeanson
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox