提交 6645f318 编写于 作者: I Ingo Molnar

Merge tag 'perf-core-for-mingo' of...

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: NArnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: NIngo Molnar <mingo@kernel.org>
...@@ -53,12 +53,14 @@ static int cmd_data_convert(int argc, const char **argv, ...@@ -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, ...@@ -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 ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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[] = { ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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 { ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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 { ...@@ -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) ...@@ -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, ...@@ -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 { ...@@ -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) ...@@ -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) ...@@ -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 @@ static int ctf_writer__init(struct ctf_writer *cw, const char *path) ...@@ -791,12 +791,13 @@ static int ctf_writer__init(struct ctf_writer *cw, const char *path)
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 @@ ...@@ -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, ...@@ -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 { ...@@ -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, ...@@ -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) ...@@ -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 { ...@@ -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 { ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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 @@ static PyObject *python_process_callchain(struct perf_sample *sample, ...@@ -381,7 +381,6 @@ static PyObject *python_process_callchain(struct perf_sample *sample,
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, ...@@ -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, ...@@ -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) ...@@ -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, ...@@ -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 @@ static void python_process_general_event(struct perf_sample *sample, ...@@ -843,22 +841,20 @@ static void python_process_general_event(struct perf_sample *sample,
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) ...@@ -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 { ...@@ -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);
}; };
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册