perf/core improvements and fixes:
User visible: - Support unnamed union/structure members data collection in 'perf probe' (Masami Hiramatsu) - Support missing -f to override perf.data file ownership (Yunlong Song) Infrastructure: - No need to lookup thread twice when processing samples in 'perf script' (Arnaldo Carvalho de Melo) - No need to pass thread twice to the scripting callbacks (Arnaldo Carvalho de Melo) - No need to pass thread twice to the db-export facility (Arnaldo Carvalho de Melo) Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQEcBAABAgAGBQJVHcIDAAoJEBpxZoYYoA71Nl8IANlwOgKWQtT6Ix/MuD6/ePAZ ce9+J4S7rs1+yr8hlNFSI2cu+s9uaibmOxAlYF30oN+swjkDbbtdw0GHquHAhew8 jsoSpXMW7o4lcqRW96zmmrTVc+6uPaIEobE0OPwJ8EbrXTIMyGzuPTSn6nfqVpGY aAATZ+RR2kAiCKnSczXGTx31tgDchjXZfI8Byg2feXxiNVQfkdUJioOUxvum8VmT Qb10p15DM35AX5FeRN7rWpG2lxrLUEfRBcmzTZDL/EEOJ2m+CZ0VYfyS4nOmHIAS bBjcHLNr8sIuU9YP7xPI3LkZ0D2vKSNvNty6sKNkknVbK/JYVn7CUGAKXvKgmH0= =9d6r -----END PGP SIGNATURE----- Merge tag 'perf-core-for-mingo' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core Pull perf/core improvements and fixes from Arnaldo Carvalho de Melo: User visible changes: - Support unnamed union/structure members data collection in 'perf probe'. (Masami Hiramatsu) - Support missing -f to override perf.data file ownership. (Yunlong Song) Infrastructure changes: - No need to lookup thread twice when processing samples in 'perf script'. (Arnaldo Carvalho de Melo) - No need to pass thread twice to the scripting callbacks. (Arnaldo Carvalho de Melo) - No need to pass thread twice to the db-export facility. (Arnaldo Carvalho de Melo) Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
commit
6645f3187f
|
@ -53,12 +53,14 @@ static int cmd_data_convert(int argc, const char **argv,
|
||||||
const char *prefix __maybe_unused)
|
const char *prefix __maybe_unused)
|
||||||
{
|
{
|
||||||
const char *to_ctf = NULL;
|
const char *to_ctf = NULL;
|
||||||
|
bool force = false;
|
||||||
const struct option options[] = {
|
const struct option options[] = {
|
||||||
OPT_INCR('v', "verbose", &verbose, "be more verbose"),
|
OPT_INCR('v', "verbose", &verbose, "be more verbose"),
|
||||||
OPT_STRING('i', "input", &input_name, "file", "input file name"),
|
OPT_STRING('i', "input", &input_name, "file", "input file name"),
|
||||||
#ifdef HAVE_LIBBABELTRACE_SUPPORT
|
#ifdef HAVE_LIBBABELTRACE_SUPPORT
|
||||||
OPT_STRING(0, "to-ctf", &to_ctf, NULL, "Convert to CTF format"),
|
OPT_STRING(0, "to-ctf", &to_ctf, NULL, "Convert to CTF format"),
|
||||||
#endif
|
#endif
|
||||||
|
OPT_BOOLEAN('f', "force", &force, "don't complain, do it"),
|
||||||
OPT_END()
|
OPT_END()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -76,7 +78,7 @@ static int cmd_data_convert(int argc, const char **argv,
|
||||||
|
|
||||||
if (to_ctf) {
|
if (to_ctf) {
|
||||||
#ifdef HAVE_LIBBABELTRACE_SUPPORT
|
#ifdef HAVE_LIBBABELTRACE_SUPPORT
|
||||||
return bt_convert__perf2ctf(input_name, to_ctf);
|
return bt_convert__perf2ctf(input_name, to_ctf, force);
|
||||||
#else
|
#else
|
||||||
pr_err("The libbabeltrace support is not compiled in.\n");
|
pr_err("The libbabeltrace support is not compiled in.\n");
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -24,6 +24,7 @@ static int __cmd_evlist(const char *file_name, struct perf_attr_details *details
|
||||||
struct perf_data_file file = {
|
struct perf_data_file file = {
|
||||||
.path = file_name,
|
.path = file_name,
|
||||||
.mode = PERF_DATA_MODE_READ,
|
.mode = PERF_DATA_MODE_READ,
|
||||||
|
.force = details->force,
|
||||||
};
|
};
|
||||||
|
|
||||||
session = perf_session__new(&file, 0, NULL);
|
session = perf_session__new(&file, 0, NULL);
|
||||||
|
@ -47,6 +48,7 @@ int cmd_evlist(int argc, const char **argv, const char *prefix __maybe_unused)
|
||||||
"Show all event attr details"),
|
"Show all event attr details"),
|
||||||
OPT_BOOLEAN('g', "group", &details.event_group,
|
OPT_BOOLEAN('g', "group", &details.event_group,
|
||||||
"Show event group information"),
|
"Show event group information"),
|
||||||
|
OPT_BOOLEAN('f', "force", &details.force, "don't complain, do it"),
|
||||||
OPT_END()
|
OPT_END()
|
||||||
};
|
};
|
||||||
const char * const evlist_usage[] = {
|
const char * const evlist_usage[] = {
|
||||||
|
|
|
@ -443,6 +443,7 @@ int cmd_inject(int argc, const char **argv, const char *prefix __maybe_unused)
|
||||||
"be more verbose (show build ids, etc)"),
|
"be more verbose (show build ids, etc)"),
|
||||||
OPT_STRING(0, "kallsyms", &symbol_conf.kallsyms_name, "file",
|
OPT_STRING(0, "kallsyms", &symbol_conf.kallsyms_name, "file",
|
||||||
"kallsyms pathname"),
|
"kallsyms pathname"),
|
||||||
|
OPT_BOOLEAN('f', "force", &file.force, "don't complain, do it"),
|
||||||
OPT_END()
|
OPT_END()
|
||||||
};
|
};
|
||||||
const char * const inject_usage[] = {
|
const char * const inject_usage[] = {
|
||||||
|
|
|
@ -662,6 +662,10 @@ static int __cmd_record(int argc, const char **argv)
|
||||||
int cmd_kmem(int argc, const char **argv, const char *prefix __maybe_unused)
|
int cmd_kmem(int argc, const char **argv, const char *prefix __maybe_unused)
|
||||||
{
|
{
|
||||||
const char * const default_sort_order = "frag,hit,bytes";
|
const char * const default_sort_order = "frag,hit,bytes";
|
||||||
|
struct perf_data_file file = {
|
||||||
|
.path = input_name,
|
||||||
|
.mode = PERF_DATA_MODE_READ,
|
||||||
|
};
|
||||||
const struct option kmem_options[] = {
|
const struct option kmem_options[] = {
|
||||||
OPT_STRING('i', "input", &input_name, "file", "input file name"),
|
OPT_STRING('i', "input", &input_name, "file", "input file name"),
|
||||||
OPT_INCR('v', "verbose", &verbose,
|
OPT_INCR('v', "verbose", &verbose,
|
||||||
|
@ -675,6 +679,7 @@ int cmd_kmem(int argc, const char **argv, const char *prefix __maybe_unused)
|
||||||
parse_sort_opt),
|
parse_sort_opt),
|
||||||
OPT_CALLBACK('l', "line", NULL, "num", "show n lines", parse_line_opt),
|
OPT_CALLBACK('l', "line", NULL, "num", "show n lines", parse_line_opt),
|
||||||
OPT_BOOLEAN(0, "raw-ip", &raw_ip, "show raw ip instead of symbol"),
|
OPT_BOOLEAN(0, "raw-ip", &raw_ip, "show raw ip instead of symbol"),
|
||||||
|
OPT_BOOLEAN('f', "force", &file.force, "don't complain, do it"),
|
||||||
OPT_END()
|
OPT_END()
|
||||||
};
|
};
|
||||||
const char *const kmem_subcommands[] = { "record", "stat", NULL };
|
const char *const kmem_subcommands[] = { "record", "stat", NULL };
|
||||||
|
@ -683,10 +688,6 @@ int cmd_kmem(int argc, const char **argv, const char *prefix __maybe_unused)
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
struct perf_session *session;
|
struct perf_session *session;
|
||||||
struct perf_data_file file = {
|
|
||||||
.path = input_name,
|
|
||||||
.mode = PERF_DATA_MODE_READ,
|
|
||||||
};
|
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
|
|
||||||
argc = parse_options_subcommand(argc, argv, kmem_options,
|
argc = parse_options_subcommand(argc, argv, kmem_options,
|
||||||
|
|
|
@ -1047,6 +1047,7 @@ static int read_events(struct perf_kvm_stat *kvm)
|
||||||
struct perf_data_file file = {
|
struct perf_data_file file = {
|
||||||
.path = kvm->file_name,
|
.path = kvm->file_name,
|
||||||
.mode = PERF_DATA_MODE_READ,
|
.mode = PERF_DATA_MODE_READ,
|
||||||
|
.force = kvm->force,
|
||||||
};
|
};
|
||||||
|
|
||||||
kvm->tool = eops;
|
kvm->tool = eops;
|
||||||
|
@ -1204,6 +1205,7 @@ kvm_events_report(struct perf_kvm_stat *kvm, int argc, const char **argv)
|
||||||
" time (sort by avg time)"),
|
" time (sort by avg time)"),
|
||||||
OPT_STRING('p', "pid", &kvm->opts.target.pid, "pid",
|
OPT_STRING('p', "pid", &kvm->opts.target.pid, "pid",
|
||||||
"analyze events only for given process id(s)"),
|
"analyze events only for given process id(s)"),
|
||||||
|
OPT_BOOLEAN('f', "force", &kvm->force, "don't complain, do it"),
|
||||||
OPT_END()
|
OPT_END()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -846,6 +846,8 @@ static const struct perf_evsel_str_handler lock_tracepoints[] = {
|
||||||
{ "lock:lock_release", perf_evsel__process_lock_release, }, /* CONFIG_LOCKDEP */
|
{ "lock:lock_release", perf_evsel__process_lock_release, }, /* CONFIG_LOCKDEP */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static bool force;
|
||||||
|
|
||||||
static int __cmd_report(bool display_info)
|
static int __cmd_report(bool display_info)
|
||||||
{
|
{
|
||||||
int err = -EINVAL;
|
int err = -EINVAL;
|
||||||
|
@ -857,6 +859,7 @@ static int __cmd_report(bool display_info)
|
||||||
struct perf_data_file file = {
|
struct perf_data_file file = {
|
||||||
.path = input_name,
|
.path = input_name,
|
||||||
.mode = PERF_DATA_MODE_READ,
|
.mode = PERF_DATA_MODE_READ,
|
||||||
|
.force = force,
|
||||||
};
|
};
|
||||||
|
|
||||||
session = perf_session__new(&file, false, &eops);
|
session = perf_session__new(&file, false, &eops);
|
||||||
|
@ -945,6 +948,7 @@ int cmd_lock(int argc, const char **argv, const char *prefix __maybe_unused)
|
||||||
"dump thread list in perf.data"),
|
"dump thread list in perf.data"),
|
||||||
OPT_BOOLEAN('m', "map", &info_map,
|
OPT_BOOLEAN('m', "map", &info_map,
|
||||||
"map of lock instances (address:name table)"),
|
"map of lock instances (address:name table)"),
|
||||||
|
OPT_BOOLEAN('f', "force", &force, "don't complain, do it"),
|
||||||
OPT_END()
|
OPT_END()
|
||||||
};
|
};
|
||||||
const struct option lock_options[] = {
|
const struct option lock_options[] = {
|
||||||
|
@ -956,6 +960,7 @@ int cmd_lock(int argc, const char **argv, const char *prefix __maybe_unused)
|
||||||
const struct option report_options[] = {
|
const struct option report_options[] = {
|
||||||
OPT_STRING('k', "key", &sort_key, "acquired",
|
OPT_STRING('k', "key", &sort_key, "acquired",
|
||||||
"key for sorting (acquired / contended / avg_wait / wait_total / wait_max / wait_min)"),
|
"key for sorting (acquired / contended / avg_wait / wait_total / wait_max / wait_min)"),
|
||||||
|
OPT_BOOLEAN('f', "force", &force, "don't complain, do it"),
|
||||||
/* TODO: type */
|
/* TODO: type */
|
||||||
OPT_END()
|
OPT_END()
|
||||||
};
|
};
|
||||||
|
|
|
@ -15,6 +15,7 @@ struct perf_mem {
|
||||||
char const *input_name;
|
char const *input_name;
|
||||||
bool hide_unresolved;
|
bool hide_unresolved;
|
||||||
bool dump_raw;
|
bool dump_raw;
|
||||||
|
bool force;
|
||||||
int operation;
|
int operation;
|
||||||
const char *cpu_list;
|
const char *cpu_list;
|
||||||
DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS);
|
DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS);
|
||||||
|
@ -120,6 +121,7 @@ static int report_raw_events(struct perf_mem *mem)
|
||||||
struct perf_data_file file = {
|
struct perf_data_file file = {
|
||||||
.path = input_name,
|
.path = input_name,
|
||||||
.mode = PERF_DATA_MODE_READ,
|
.mode = PERF_DATA_MODE_READ,
|
||||||
|
.force = mem->force,
|
||||||
};
|
};
|
||||||
int err = -EINVAL;
|
int err = -EINVAL;
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -290,6 +292,7 @@ int cmd_mem(int argc, const char **argv, const char *prefix __maybe_unused)
|
||||||
"separator",
|
"separator",
|
||||||
"separator for columns, no spaces will be added"
|
"separator for columns, no spaces will be added"
|
||||||
" between columns '.' is reserved."),
|
" between columns '.' is reserved."),
|
||||||
|
OPT_BOOLEAN('f', "force", &mem.force, "don't complain, do it"),
|
||||||
OPT_END()
|
OPT_END()
|
||||||
};
|
};
|
||||||
const char *const mem_subcommands[] = { "record", "report", NULL };
|
const char *const mem_subcommands[] = { "record", "report", NULL };
|
||||||
|
|
|
@ -446,9 +446,9 @@ static void print_sample_bts(union perf_event *event,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void process_event(union perf_event *event, struct perf_sample *sample,
|
static void process_event(union perf_event *event, struct perf_sample *sample,
|
||||||
struct perf_evsel *evsel, struct thread *thread,
|
struct perf_evsel *evsel, struct addr_location *al)
|
||||||
struct addr_location *al)
|
|
||||||
{
|
{
|
||||||
|
struct thread *thread = al->thread;
|
||||||
struct perf_event_attr *attr = &evsel->attr;
|
struct perf_event_attr *attr = &evsel->attr;
|
||||||
|
|
||||||
if (output[attr->type].fields == 0)
|
if (output[attr->type].fields == 0)
|
||||||
|
@ -549,14 +549,6 @@ static int process_sample_event(struct perf_tool *tool __maybe_unused,
|
||||||
struct machine *machine)
|
struct machine *machine)
|
||||||
{
|
{
|
||||||
struct addr_location al;
|
struct addr_location al;
|
||||||
struct thread *thread = machine__findnew_thread(machine, sample->pid,
|
|
||||||
sample->tid);
|
|
||||||
|
|
||||||
if (thread == NULL) {
|
|
||||||
pr_debug("problem processing %d event, skipping it.\n",
|
|
||||||
event->header.type);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (debug_mode) {
|
if (debug_mode) {
|
||||||
if (sample->time < last_timestamp) {
|
if (sample->time < last_timestamp) {
|
||||||
|
@ -581,7 +573,7 @@ static int process_sample_event(struct perf_tool *tool __maybe_unused,
|
||||||
if (cpu_list && !test_bit(sample->cpu, cpu_bitmap))
|
if (cpu_list && !test_bit(sample->cpu, cpu_bitmap))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
scripting_ops->process_event(event, sample, evsel, thread, &al);
|
scripting_ops->process_event(event, sample, evsel, &al);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1523,6 +1515,9 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
|
||||||
.ordering_requires_timestamps = true,
|
.ordering_requires_timestamps = true,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
struct perf_data_file file = {
|
||||||
|
.mode = PERF_DATA_MODE_READ,
|
||||||
|
};
|
||||||
const struct option options[] = {
|
const struct option options[] = {
|
||||||
OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
|
OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
|
||||||
"dump raw trace in ASCII"),
|
"dump raw trace in ASCII"),
|
||||||
|
@ -1550,7 +1545,7 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
|
||||||
"When printing symbols do not display call chain"),
|
"When printing symbols do not display call chain"),
|
||||||
OPT_STRING(0, "symfs", &symbol_conf.symfs, "directory",
|
OPT_STRING(0, "symfs", &symbol_conf.symfs, "directory",
|
||||||
"Look for files with symbols relative to this directory"),
|
"Look for files with symbols relative to this directory"),
|
||||||
OPT_CALLBACK('f', "fields", NULL, "str",
|
OPT_CALLBACK('F', "fields", NULL, "str",
|
||||||
"comma separated output fields prepend with 'type:'. "
|
"comma separated output fields prepend with 'type:'. "
|
||||||
"Valid types: hw,sw,trace,raw. "
|
"Valid types: hw,sw,trace,raw. "
|
||||||
"Fields: comm,tid,pid,time,cpu,event,trace,ip,sym,dso,"
|
"Fields: comm,tid,pid,time,cpu,event,trace,ip,sym,dso,"
|
||||||
|
@ -1574,6 +1569,7 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
|
||||||
"Show the fork/comm/exit events"),
|
"Show the fork/comm/exit events"),
|
||||||
OPT_BOOLEAN('\0', "show-mmap-events", &script.show_mmap_events,
|
OPT_BOOLEAN('\0', "show-mmap-events", &script.show_mmap_events,
|
||||||
"Show the mmap events"),
|
"Show the mmap events"),
|
||||||
|
OPT_BOOLEAN('f', "force", &file.force, "don't complain, do it"),
|
||||||
OPT_END()
|
OPT_END()
|
||||||
};
|
};
|
||||||
const char * const script_subcommands[] = { "record", "report", NULL };
|
const char * const script_subcommands[] = { "record", "report", NULL };
|
||||||
|
@ -1585,9 +1581,6 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
|
||||||
"perf script [<options>] <top-script> [script-args]",
|
"perf script [<options>] <top-script> [script-args]",
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
struct perf_data_file file = {
|
|
||||||
.mode = PERF_DATA_MODE_READ,
|
|
||||||
};
|
|
||||||
|
|
||||||
setup_scripting();
|
setup_scripting();
|
||||||
|
|
||||||
|
|
|
@ -67,6 +67,7 @@ struct timechart {
|
||||||
skip_eagain;
|
skip_eagain;
|
||||||
u64 min_time,
|
u64 min_time,
|
||||||
merge_dist;
|
merge_dist;
|
||||||
|
bool force;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct per_pidcomm;
|
struct per_pidcomm;
|
||||||
|
@ -1598,6 +1599,7 @@ static int __cmd_timechart(struct timechart *tchart, const char *output_name)
|
||||||
struct perf_data_file file = {
|
struct perf_data_file file = {
|
||||||
.path = input_name,
|
.path = input_name,
|
||||||
.mode = PERF_DATA_MODE_READ,
|
.mode = PERF_DATA_MODE_READ,
|
||||||
|
.force = tchart->force,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct perf_session *session = perf_session__new(&file, false,
|
struct perf_session *session = perf_session__new(&file, false,
|
||||||
|
@ -1956,6 +1958,7 @@ int cmd_timechart(int argc, const char **argv,
|
||||||
OPT_CALLBACK(0, "io-merge-dist", &tchart.merge_dist, "time",
|
OPT_CALLBACK(0, "io-merge-dist", &tchart.merge_dist, "time",
|
||||||
"merge events that are merge-dist us apart",
|
"merge events that are merge-dist us apart",
|
||||||
parse_time),
|
parse_time),
|
||||||
|
OPT_BOOLEAN('f', "force", &tchart.force, "don't complain, do it"),
|
||||||
OPT_END()
|
OPT_END()
|
||||||
};
|
};
|
||||||
const char * const timechart_subcommands[] = { "record", NULL };
|
const char * const timechart_subcommands[] = { "record", NULL };
|
||||||
|
|
|
@ -1254,6 +1254,7 @@ struct trace {
|
||||||
bool show_comm;
|
bool show_comm;
|
||||||
bool show_tool_stats;
|
bool show_tool_stats;
|
||||||
bool trace_syscalls;
|
bool trace_syscalls;
|
||||||
|
bool force;
|
||||||
int trace_pgfaults;
|
int trace_pgfaults;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2345,6 +2346,7 @@ static int trace__replay(struct trace *trace)
|
||||||
struct perf_data_file file = {
|
struct perf_data_file file = {
|
||||||
.path = input_name,
|
.path = input_name,
|
||||||
.mode = PERF_DATA_MODE_READ,
|
.mode = PERF_DATA_MODE_READ,
|
||||||
|
.force = trace->force,
|
||||||
};
|
};
|
||||||
struct perf_session *session;
|
struct perf_session *session;
|
||||||
struct perf_evsel *evsel;
|
struct perf_evsel *evsel;
|
||||||
|
@ -2693,6 +2695,7 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)
|
||||||
OPT_CALLBACK_DEFAULT('F', "pf", &trace.trace_pgfaults, "all|maj|min",
|
OPT_CALLBACK_DEFAULT('F', "pf", &trace.trace_pgfaults, "all|maj|min",
|
||||||
"Trace pagefaults", parse_pagefaults, "maj"),
|
"Trace pagefaults", parse_pagefaults, "maj"),
|
||||||
OPT_BOOLEAN(0, "syscalls", &trace.trace_syscalls, "Trace syscalls"),
|
OPT_BOOLEAN(0, "syscalls", &trace.trace_syscalls, "Trace syscalls"),
|
||||||
|
OPT_BOOLEAN('f', "force", &trace.force, "don't complain, do it"),
|
||||||
OPT_END()
|
OPT_END()
|
||||||
};
|
};
|
||||||
const char * const trace_subcommands[] = { "record", NULL };
|
const char * const trace_subcommands[] = { "record", NULL };
|
||||||
|
|
|
@ -791,12 +791,13 @@ err:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int bt_convert__perf2ctf(const char *input, const char *path)
|
int bt_convert__perf2ctf(const char *input, const char *path, bool force)
|
||||||
{
|
{
|
||||||
struct perf_session *session;
|
struct perf_session *session;
|
||||||
struct perf_data_file file = {
|
struct perf_data_file file = {
|
||||||
.path = input,
|
.path = input,
|
||||||
.mode = PERF_DATA_MODE_READ,
|
.mode = PERF_DATA_MODE_READ,
|
||||||
|
.force = force,
|
||||||
};
|
};
|
||||||
struct convert c = {
|
struct convert c = {
|
||||||
.tool = {
|
.tool = {
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
#define __DATA_CONVERT_BT_H
|
#define __DATA_CONVERT_BT_H
|
||||||
#ifdef HAVE_LIBBABELTRACE_SUPPORT
|
#ifdef HAVE_LIBBABELTRACE_SUPPORT
|
||||||
|
|
||||||
int bt_convert__perf2ctf(const char *input_name, const char *to_ctf);
|
int bt_convert__perf2ctf(const char *input_name, const char *to_ctf, bool force);
|
||||||
|
|
||||||
#endif /* HAVE_LIBBABELTRACE_SUPPORT */
|
#endif /* HAVE_LIBBABELTRACE_SUPPORT */
|
||||||
#endif /* __DATA_CONVERT_BT_H */
|
#endif /* __DATA_CONVERT_BT_H */
|
||||||
|
|
|
@ -282,13 +282,13 @@ int db_export__branch_type(struct db_export *dbe, u32 branch_type,
|
||||||
|
|
||||||
int db_export__sample(struct db_export *dbe, union perf_event *event,
|
int db_export__sample(struct db_export *dbe, union perf_event *event,
|
||||||
struct perf_sample *sample, struct perf_evsel *evsel,
|
struct perf_sample *sample, struct perf_evsel *evsel,
|
||||||
struct thread *thread, struct addr_location *al)
|
struct addr_location *al)
|
||||||
{
|
{
|
||||||
|
struct thread* thread = al->thread;
|
||||||
struct export_sample es = {
|
struct export_sample es = {
|
||||||
.event = event,
|
.event = event,
|
||||||
.sample = sample,
|
.sample = sample,
|
||||||
.evsel = evsel,
|
.evsel = evsel,
|
||||||
.thread = thread,
|
|
||||||
.al = al,
|
.al = al,
|
||||||
};
|
};
|
||||||
struct thread *main_thread;
|
struct thread *main_thread;
|
||||||
|
|
|
@ -34,7 +34,6 @@ struct export_sample {
|
||||||
union perf_event *event;
|
union perf_event *event;
|
||||||
struct perf_sample *sample;
|
struct perf_sample *sample;
|
||||||
struct perf_evsel *evsel;
|
struct perf_evsel *evsel;
|
||||||
struct thread *thread;
|
|
||||||
struct addr_location *al;
|
struct addr_location *al;
|
||||||
u64 db_id;
|
u64 db_id;
|
||||||
u64 comm_db_id;
|
u64 comm_db_id;
|
||||||
|
@ -97,7 +96,7 @@ int db_export__branch_type(struct db_export *dbe, u32 branch_type,
|
||||||
const char *name);
|
const char *name);
|
||||||
int db_export__sample(struct db_export *dbe, union perf_event *event,
|
int db_export__sample(struct db_export *dbe, union perf_event *event,
|
||||||
struct perf_sample *sample, struct perf_evsel *evsel,
|
struct perf_sample *sample, struct perf_evsel *evsel,
|
||||||
struct thread *thread, struct addr_location *al);
|
struct addr_location *al);
|
||||||
|
|
||||||
int db_export__branch_types(struct db_export *dbe);
|
int db_export__branch_types(struct db_export *dbe);
|
||||||
|
|
||||||
|
|
|
@ -801,10 +801,16 @@ static int __die_find_member_cb(Dwarf_Die *die_mem, void *data)
|
||||||
{
|
{
|
||||||
const char *name = data;
|
const char *name = data;
|
||||||
|
|
||||||
if ((dwarf_tag(die_mem) == DW_TAG_member) &&
|
if (dwarf_tag(die_mem) == DW_TAG_member) {
|
||||||
die_compare_name(die_mem, name))
|
if (die_compare_name(die_mem, name))
|
||||||
return DIE_FIND_CB_END;
|
return DIE_FIND_CB_END;
|
||||||
|
else if (!dwarf_diename(die_mem)) { /* Unnamed structure */
|
||||||
|
Dwarf_Die type_die, tmp_die;
|
||||||
|
if (die_get_type(die_mem, &type_die) &&
|
||||||
|
die_find_member(&type_die, name, &tmp_die))
|
||||||
|
return DIE_FIND_CB_END;
|
||||||
|
}
|
||||||
|
}
|
||||||
return DIE_FIND_CB_SIBLING;
|
return DIE_FIND_CB_SIBLING;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -335,6 +335,7 @@ struct perf_attr_details {
|
||||||
bool freq;
|
bool freq;
|
||||||
bool verbose;
|
bool verbose;
|
||||||
bool event_group;
|
bool event_group;
|
||||||
|
bool force;
|
||||||
};
|
};
|
||||||
|
|
||||||
int perf_evsel__fprintf(struct perf_evsel *evsel,
|
int perf_evsel__fprintf(struct perf_evsel *evsel,
|
||||||
|
|
|
@ -99,6 +99,7 @@ struct perf_kvm_stat {
|
||||||
int timerfd;
|
int timerfd;
|
||||||
unsigned int display_time;
|
unsigned int display_time;
|
||||||
bool live;
|
bool live;
|
||||||
|
bool force;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct kvm_reg_events_ops {
|
struct kvm_reg_events_ops {
|
||||||
|
|
|
@ -460,7 +460,8 @@ static int convert_variable_fields(Dwarf_Die *vr_die, const char *varname,
|
||||||
" nor array.\n", varname);
|
" nor array.\n", varname);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
if (field->ref) {
|
/* While prcessing unnamed field, we don't care about this */
|
||||||
|
if (field->ref && dwarf_diename(vr_die)) {
|
||||||
pr_err("Semantic error: %s must be referred by '.'\n",
|
pr_err("Semantic error: %s must be referred by '.'\n",
|
||||||
field->name);
|
field->name);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -491,6 +492,11 @@ static int convert_variable_fields(Dwarf_Die *vr_die, const char *varname,
|
||||||
}
|
}
|
||||||
ref->offset += (long)offs;
|
ref->offset += (long)offs;
|
||||||
|
|
||||||
|
/* If this member is unnamed, we need to reuse this field */
|
||||||
|
if (!dwarf_diename(die_mem))
|
||||||
|
return convert_variable_fields(die_mem, varname, field,
|
||||||
|
&ref, die_mem);
|
||||||
|
|
||||||
next:
|
next:
|
||||||
/* Converting next field */
|
/* Converting next field */
|
||||||
if (field->next)
|
if (field->next)
|
||||||
|
|
|
@ -360,10 +360,9 @@ static void perl_process_event_generic(union perf_event *event,
|
||||||
static void perl_process_event(union perf_event *event,
|
static void perl_process_event(union perf_event *event,
|
||||||
struct perf_sample *sample,
|
struct perf_sample *sample,
|
||||||
struct perf_evsel *evsel,
|
struct perf_evsel *evsel,
|
||||||
struct thread *thread,
|
struct addr_location *al)
|
||||||
struct addr_location *al __maybe_unused)
|
|
||||||
{
|
{
|
||||||
perl_process_tracepoint(sample, evsel, thread);
|
perl_process_tracepoint(sample, evsel, al->thread);
|
||||||
perl_process_event_generic(event, sample, evsel);
|
perl_process_event_generic(event, sample, evsel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -381,7 +381,6 @@ exit:
|
||||||
|
|
||||||
static void python_process_tracepoint(struct perf_sample *sample,
|
static void python_process_tracepoint(struct perf_sample *sample,
|
||||||
struct perf_evsel *evsel,
|
struct perf_evsel *evsel,
|
||||||
struct thread *thread,
|
|
||||||
struct addr_location *al)
|
struct addr_location *al)
|
||||||
{
|
{
|
||||||
struct event_format *event = evsel->tp_format;
|
struct event_format *event = evsel->tp_format;
|
||||||
|
@ -395,7 +394,7 @@ static void python_process_tracepoint(struct perf_sample *sample,
|
||||||
int cpu = sample->cpu;
|
int cpu = sample->cpu;
|
||||||
void *data = sample->raw_data;
|
void *data = sample->raw_data;
|
||||||
unsigned long long nsecs = sample->time;
|
unsigned long long nsecs = sample->time;
|
||||||
const char *comm = thread__comm_str(thread);
|
const char *comm = thread__comm_str(al->thread);
|
||||||
|
|
||||||
t = PyTuple_New(MAX_FIELDS);
|
t = PyTuple_New(MAX_FIELDS);
|
||||||
if (!t)
|
if (!t)
|
||||||
|
@ -680,7 +679,7 @@ static int python_export_sample(struct db_export *dbe,
|
||||||
tuple_set_u64(t, 0, es->db_id);
|
tuple_set_u64(t, 0, es->db_id);
|
||||||
tuple_set_u64(t, 1, es->evsel->db_id);
|
tuple_set_u64(t, 1, es->evsel->db_id);
|
||||||
tuple_set_u64(t, 2, es->al->machine->db_id);
|
tuple_set_u64(t, 2, es->al->machine->db_id);
|
||||||
tuple_set_u64(t, 3, es->thread->db_id);
|
tuple_set_u64(t, 3, es->al->thread->db_id);
|
||||||
tuple_set_u64(t, 4, es->comm_db_id);
|
tuple_set_u64(t, 4, es->comm_db_id);
|
||||||
tuple_set_u64(t, 5, es->dso_db_id);
|
tuple_set_u64(t, 5, es->dso_db_id);
|
||||||
tuple_set_u64(t, 6, es->sym_db_id);
|
tuple_set_u64(t, 6, es->sym_db_id);
|
||||||
|
@ -766,7 +765,6 @@ static int python_process_call_return(struct call_return *cr, void *data)
|
||||||
|
|
||||||
static void python_process_general_event(struct perf_sample *sample,
|
static void python_process_general_event(struct perf_sample *sample,
|
||||||
struct perf_evsel *evsel,
|
struct perf_evsel *evsel,
|
||||||
struct thread *thread,
|
|
||||||
struct addr_location *al)
|
struct addr_location *al)
|
||||||
{
|
{
|
||||||
PyObject *handler, *t, *dict, *callchain, *dict_sample;
|
PyObject *handler, *t, *dict, *callchain, *dict_sample;
|
||||||
|
@ -816,7 +814,7 @@ static void python_process_general_event(struct perf_sample *sample,
|
||||||
pydict_set_item_string_decref(dict, "raw_buf", PyString_FromStringAndSize(
|
pydict_set_item_string_decref(dict, "raw_buf", PyString_FromStringAndSize(
|
||||||
(const char *)sample->raw_data, sample->raw_size));
|
(const char *)sample->raw_data, sample->raw_size));
|
||||||
pydict_set_item_string_decref(dict, "comm",
|
pydict_set_item_string_decref(dict, "comm",
|
||||||
PyString_FromString(thread__comm_str(thread)));
|
PyString_FromString(thread__comm_str(al->thread)));
|
||||||
if (al->map) {
|
if (al->map) {
|
||||||
pydict_set_item_string_decref(dict, "dso",
|
pydict_set_item_string_decref(dict, "dso",
|
||||||
PyString_FromString(al->map->dso->name));
|
PyString_FromString(al->map->dso->name));
|
||||||
|
@ -843,22 +841,20 @@ exit:
|
||||||
static void python_process_event(union perf_event *event,
|
static void python_process_event(union perf_event *event,
|
||||||
struct perf_sample *sample,
|
struct perf_sample *sample,
|
||||||
struct perf_evsel *evsel,
|
struct perf_evsel *evsel,
|
||||||
struct thread *thread,
|
|
||||||
struct addr_location *al)
|
struct addr_location *al)
|
||||||
{
|
{
|
||||||
struct tables *tables = &tables_global;
|
struct tables *tables = &tables_global;
|
||||||
|
|
||||||
switch (evsel->attr.type) {
|
switch (evsel->attr.type) {
|
||||||
case PERF_TYPE_TRACEPOINT:
|
case PERF_TYPE_TRACEPOINT:
|
||||||
python_process_tracepoint(sample, evsel, thread, al);
|
python_process_tracepoint(sample, evsel, al);
|
||||||
break;
|
break;
|
||||||
/* Reserve for future process_hw/sw/raw APIs */
|
/* Reserve for future process_hw/sw/raw APIs */
|
||||||
default:
|
default:
|
||||||
if (tables->db_export_mode)
|
if (tables->db_export_mode)
|
||||||
db_export__sample(&tables->dbe, event, sample, evsel,
|
db_export__sample(&tables->dbe, event, sample, evsel, al);
|
||||||
thread, al);
|
|
||||||
else
|
else
|
||||||
python_process_general_event(sample, evsel, thread, al);
|
python_process_general_event(sample, evsel, al);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,6 @@ static int stop_script_unsupported(void)
|
||||||
static void process_event_unsupported(union perf_event *event __maybe_unused,
|
static void process_event_unsupported(union perf_event *event __maybe_unused,
|
||||||
struct perf_sample *sample __maybe_unused,
|
struct perf_sample *sample __maybe_unused,
|
||||||
struct perf_evsel *evsel __maybe_unused,
|
struct perf_evsel *evsel __maybe_unused,
|
||||||
struct thread *thread __maybe_unused,
|
|
||||||
struct addr_location *al __maybe_unused)
|
struct addr_location *al __maybe_unused)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,8 +72,7 @@ struct scripting_ops {
|
||||||
void (*process_event) (union perf_event *event,
|
void (*process_event) (union perf_event *event,
|
||||||
struct perf_sample *sample,
|
struct perf_sample *sample,
|
||||||
struct perf_evsel *evsel,
|
struct perf_evsel *evsel,
|
||||||
struct thread *thread,
|
struct addr_location *al);
|
||||||
struct addr_location *al);
|
|
||||||
int (*generate_script) (struct pevent *pevent, const char *outfile);
|
int (*generate_script) (struct pevent *pevent, const char *outfile);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue