mirror of
https://github.com/torvalds/linux.git
synced 2024-12-27 13:22:23 +00:00
88371c5898
Adad support to convert and store time of day in CTF data conversion for 'perf data convert' subcommand. The perf.data used for conversion needs to have clock data information - must be recorded with -k/--clockid option). New --tod option is added to 'perf data convert' subcommand to convert data with timestamps converted to wall clock time. Record data with clockid set: # perf record -k CLOCK_MONOTONIC kill kill: not enough arguments [ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.033 MB perf.data (8 samples) ] Convert data with TOD timestamps: # perf data convert --tod --to-ctf ./ctf [ perf data convert: Converted 'perf.data' into CTF data './ctf' ] [ perf data convert: Converted and wrote 0.000 MB (8 samples) ] Display data in perf script: # perf script -F+tod --ns perf 262150 2020-07-13 18:38:50.097678523 153633.958246159: 1 cycles: ... perf 262150 2020-07-13 18:38:50.097682941 153633.958250577: 1 cycles: ... perf 262150 2020-07-13 18:38:50.097684997 153633.958252633: 7 cycles: ... ... Display data in babeltrace: # babeltrace --clock-date ./ctf [2020-07-13 18:38:50.097678523] (+?.?????????) cycles: { cpu_id = 0 }, { perf_ip = 0xFFF ... [2020-07-13 18:38:50.097682941] (+0.000004418) cycles: { cpu_id = 0 }, { perf_ip = 0xFFF ... [2020-07-13 18:38:50.097684997] (+0.000002056) cycles: { cpu_id = 0 }, { perf_ip = 0xFFF ... ... It's available only for recording with clockid specified, because it's the only case where we can get reference time to wallclock time. It's can't do that with perf clock yet. Error is display if you want to use --tod on data without clockid specified: # perf data convert --tod --to-ctf ./ctf Can't provide --tod time, missing clock data. Please record with -k/--clockid option. Failed to setup CTF writer. Error during conversion setup. Signed-off-by: Jiri Olsa <jolsa@kernel.org> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> Cc: Andi Kleen <ak@linux.intel.com> Cc: David Ahern <dsahern@gmail.com> Cc: Geneviève Bastien <gbastien@versatic.net> Cc: Ian Rogers <irogers@google.com> Cc: Jeremie Galarneau <jgalar@efficios.com> Cc: Michael Petlan <mpetlan@redhat.com> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Wang Nan <wangnan0@huawei.com> Link: http://lore.kernel.org/lkml/20200805093444.314999-6-jolsa@kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
132 lines
2.9 KiB
C
132 lines
2.9 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
#include <linux/compiler.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include "builtin.h"
|
|
#include "perf.h"
|
|
#include "debug.h"
|
|
#include <subcmd/parse-options.h>
|
|
#include "data-convert.h"
|
|
#include "data-convert-bt.h"
|
|
|
|
typedef int (*data_cmd_fn_t)(int argc, const char **argv);
|
|
|
|
struct data_cmd {
|
|
const char *name;
|
|
const char *summary;
|
|
data_cmd_fn_t fn;
|
|
};
|
|
|
|
static struct data_cmd data_cmds[];
|
|
|
|
#define for_each_cmd(cmd) \
|
|
for (cmd = data_cmds; cmd && cmd->name; cmd++)
|
|
|
|
static const struct option data_options[] = {
|
|
OPT_END()
|
|
};
|
|
|
|
static const char * const data_subcommands[] = { "convert", NULL };
|
|
|
|
static const char *data_usage[] = {
|
|
"perf data [<common options>] <command> [<options>]",
|
|
NULL
|
|
};
|
|
|
|
static void print_usage(void)
|
|
{
|
|
struct data_cmd *cmd;
|
|
|
|
printf("Usage:\n");
|
|
printf("\t%s\n\n", data_usage[0]);
|
|
printf("\tAvailable commands:\n");
|
|
|
|
for_each_cmd(cmd) {
|
|
printf("\t %s\t- %s\n", cmd->name, cmd->summary);
|
|
}
|
|
|
|
printf("\n");
|
|
}
|
|
|
|
static const char * const data_convert_usage[] = {
|
|
"perf data convert [<options>]",
|
|
NULL
|
|
};
|
|
|
|
static int cmd_data_convert(int argc, const char **argv)
|
|
{
|
|
const char *to_ctf = NULL;
|
|
struct perf_data_convert_opts opts = {
|
|
.force = false,
|
|
.all = false,
|
|
};
|
|
const struct option options[] = {
|
|
OPT_INCR('v', "verbose", &verbose, "be more verbose"),
|
|
OPT_STRING('i', "input", &input_name, "file", "input file name"),
|
|
#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_END()
|
|
};
|
|
|
|
#ifndef HAVE_LIBBABELTRACE_SUPPORT
|
|
pr_err("No conversion support compiled in. perf should be compiled with environment variables LIBBABELTRACE=1 and LIBBABELTRACE_DIR=/path/to/libbabeltrace/\n");
|
|
return -1;
|
|
#endif
|
|
|
|
argc = parse_options(argc, argv, options,
|
|
data_convert_usage, 0);
|
|
if (argc) {
|
|
usage_with_options(data_convert_usage, options);
|
|
return -1;
|
|
}
|
|
|
|
if (to_ctf) {
|
|
#ifdef HAVE_LIBBABELTRACE_SUPPORT
|
|
return bt_convert__perf2ctf(input_name, to_ctf, &opts);
|
|
#else
|
|
pr_err("The libbabeltrace support is not compiled in.\n");
|
|
return -1;
|
|
#endif
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static struct data_cmd data_cmds[] = {
|
|
{ "convert", "converts data file between formats", cmd_data_convert },
|
|
{ .name = NULL, },
|
|
};
|
|
|
|
int cmd_data(int argc, const char **argv)
|
|
{
|
|
struct data_cmd *cmd;
|
|
const char *cmdstr;
|
|
|
|
/* No command specified. */
|
|
if (argc < 2)
|
|
goto usage;
|
|
|
|
argc = parse_options_subcommand(argc, argv, data_options, data_subcommands, data_usage,
|
|
PARSE_OPT_STOP_AT_NON_OPTION);
|
|
if (argc < 1)
|
|
goto usage;
|
|
|
|
cmdstr = argv[0];
|
|
|
|
for_each_cmd(cmd) {
|
|
if (strcmp(cmd->name, cmdstr))
|
|
continue;
|
|
|
|
return cmd->fn(argc, argv);
|
|
}
|
|
|
|
pr_err("Unknown command: %s\n", cmdstr);
|
|
usage:
|
|
print_usage();
|
|
return -1;
|
|
}
|