perf tools: Assorted fixes
Jiri Olsa
reviewercover perf tools: Assorted fixes
hi,
sending few fixes that pilled up.
It's also available at:
git://git.kernel.org/pub/scm/linux/kernel/git/jolsa/perf.git perf/fixes
thanks,
jirka
---
Jiri Olsa (9):
perf tools: Fix crash in perf_hpp__reset_output_field
perf tools: Add extra integrity checks to fmt_free
perf tools: Rename struct perf_data_file to perf_data
perf tools: Add struct perf_data_file
perf tools: Add perf_data_file__write function
perf stat: Move the shadow stats scale computation in perf_stat__update_shadow_stats perf stat: Make --per-thread update shadow stats to show metrics
perf tools: Check wether the eBPF file exists in event parsing
perf tools: Unwind properly location after REJECT
tools/perf/builtin-annotate.c | 10 +++++----- tools/perf/builtin-buildid-cache.c | 8 ++++---- tools/perf/builtin-buildid-list.c | 16 +++++++++------- tools/perf/builtin-c2c.c | 10 +++++----- tools/perf/builtin-diff.c | 18 +++++++++--------- tools/perf/builtin-evlist.c | 12 +++++++----- tools/perf/builtin-inject.c | 36 +++++++++++++++++++----------------- tools/perf/builtin-kmem.c | 8 ++++---- tools/perf/builtin-kvm.c | 14 ++++++++------ tools/perf/builtin-lock.c | 12 +++++++----- tools/perf/builtin-mem.c | 12 +++++++----- tools/perf/builtin-record.c | 50 +++++++++++++++++++++++++------------------------- tools/perf/builtin-report.c | 14 +++++++------- tools/perf/builtin-sched.c | 24 ++++++++++++++---------- tools/perf/builtin-script.c | 20 +++++++++++--------- tools/perf/builtin-stat.c | 35 +++++++++++++++++------------------ tools/perf/builtin-timechart.c | 14 ++++++++------ tools/perf/builtin-trace.c | 12 +++++++----- tools/perf/tests/topology.c | 22 +++++++++++++--------- tools/perf/ui/hist.c | 9 ++++++++- tools/perf/util/auxtrace.c | 4 ++-- tools/perf/util/data-convert-bt.c | 12 ++++++------ tools/perf/util/data.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++-------------------------------------------- tools/perf/util/data.h | 38 ++++++++++++++++++++++---------------- tools/perf/util/header.c | 20 ++++++++++---------- tools/perf/util/intel-bts.c | 6 +++--- tools/perf/util/intel-pt.c | 6 +++--- tools/perf/util/jit.h | 2 +- tools/perf/util/jitdump.c | 10 +++++----- tools/perf/util/parse-events.l | 25 +++++++++++++++++++++---- tools/perf/util/session.c | 44 ++++++++++++++++++++++---------------------- tools/perf/util/session.h | 4 ++-- tools/perf/util/stat-shadow.c | 48 +++++++++++++++++++++++++----------------------- tools/perf/util/stat.c | 8 ++++---- tools/perf/util/stat.h | 2 +- 35 files changed, 371 insertions(+), 308 deletions(-)
Jiri Olsa
reviewerPATCH 1/9 perf tools: Fix crash in perf_hpp__reset_output_field
Du Changbin reported crash [1] when calling perf_hpp__reset_output_field after unregistering field via perf_hpp__column_unregister.
This ends up in calling following list_del* sequence on the same format:
perf_hpp__column_unregister:
list_del(&format->list);
perf_hpp__reset_output_field:
list_del_init(&fmt->list);where the later list_del_init might touch already
freed formats.
Fixing this by replacing list_del with list_del_init in perf_hpp__column_unregister.
[1] http://marc.info/?l=linux-kernel&m=149059595826019&w=2
--- tools/perf/ui/hist.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/ui/hist.c +1 -1
@@ -532,7 +532,7 @@ void perf_hpp_list__prepend_sort_field(struct perf_hpp_list *list,void perf_hpp__column_unregister (struct perf_hpp_fmt *format) { -list_del (&format->list); +list_del_init (&format->list); }void perf_hpp__cancel_cumulate (void )
Signature · 1 line
2.13.6
tip-bot for Jiri Olsa
merge bot[tip:perf/urgent] perf hists: Fix crash in perf_hpp__reset_output_field()
perf hists: Fix crash in perf_hpp__reset_output_field()
Commit-ID: 70b01dfd765dd2196d51f33a49df23954416f34a Gitweb: https://git.kernel.org/tip/70b01dfd765dd2196d51f33a49df23954416f34a Author: Jiri Olsa <[email protected]> AuthorDate: Fri, 13 Oct 2017 10:37:28 +0200 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Fri, 13 Oct 2017 16:43:33 -0300
perf hists: Fix crash in perf_hpp__reset_output_field()
Du Changbin reported crash [1] when calling perf_hpp__reset_output_field() after unregistering field via perf_hpp__column_unregister().
This ends up in calling following list_del* sequence on the same format:
perf_hpp__column_unregister:
list_del(&format->list);
perf_hpp__reset_output_field:
list_del_init(&fmt->list);where the later list_del_init might touch already freed formats.
Fixing this by replacing list_del() with list_del_init() in perf_hpp__column_unregister().
[1] http://marc.info/?l=linux-kernel&m=149059595826019&w=2
--- tools/perf/ui/hist.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/ui/hist.c +1 -1
@@ -532,7 +532,7 @@ void perf_hpp_list__prepend_sort_field(struct perf_hpp_list *list,void perf_hpp__column_unregister (struct perf_hpp_fmt *format) { -list_del (&format->list); +list_del_init (&format->list); }void perf_hpp__cancel_cumulate (void )
Jiri Olsa
reviewerPATCH 2/9 perf tools: Add extra integrity checks to fmt_free
In reply to Jiri OlsaMake sure the struct perf_hpp_fmt is properly
unhooked before we free it.
--- tools/perf/ui/hist.c | 7 +++++++ 1 file changed, 7 insertions(+)
tools/perf/ui/hist.c +7 -0
@@ -606,6 +606,13 @@ void perf_hpp__append_sort_keys(struct perf_hpp_list *list)static void fmt_free (struct perf_hpp_fmt *fmt) { +/* +* At this point fmt should be completely +* unhooked, if not it's a bug. +*/ +BUG_ON (!list_empty (&fmt->list)); +BUG_ON (!list_empty (&fmt->sort_list)); +if (fmt->free) fmt->free (fmt); }
Signature · 1 line
2.13.6
tip-bot for Jiri Olsa
merge bot[tip:perf/urgent] perf hists: Add extra integrity checks to fmt_free()
perf hists: Add extra integrity checks to fmt_free()
Commit-ID: d0e35234f647631ddfa5fa8c8ec66c9bc698f0ab Gitweb: https://git.kernel.org/tip/d0e35234f647631ddfa5fa8c8ec66c9bc698f0ab Author: Jiri Olsa <[email protected]> AuthorDate: Fri, 13 Oct 2017 10:37:29 +0200 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Fri, 13 Oct 2017 16:43:42 -0300
perf hists: Add extra integrity checks to fmt_free()
Make sure the struct perf_hpp_fmt is properly unhooked before we free it.
--- tools/perf/ui/hist.c | 7 +++++++ 1 file changed, 7 insertions(+)
tools/perf/ui/hist.c +7 -0
@@ -606,6 +606,13 @@ next:static void fmt_free (struct perf_hpp_fmt *fmt) { +/* +* At this point fmt should be completely +* unhooked, if not it's a bug. +*/ +BUG_ON (!list_empty (&fmt->list)); +BUG_ON (!list_empty (&fmt->sort_list)); +if (fmt->free) fmt->free (fmt); }
Jiri Olsa
reviewerPATCH 3/9 perf tools: Rename struct perf_data_file to perf_data
In reply to Jiri OlsaRenaming struct perf_data_file to perf_data, because we will add the possibility to have multiple files under perf.data, so the 'perf_data' name fits better.
--- tools/perf/builtin-annotate.c | 10 ++--- tools/perf/builtin-buildid-cache.c | 8 ++-- tools/perf/builtin-buildid-list.c | 8 ++-- tools/perf/builtin-c2c.c | 10 ++--- tools/perf/builtin-diff.c | 18 ++++---- tools/perf/builtin-evlist.c | 4 +- tools/perf/builtin-inject.c | 26 +++++------ tools/perf/builtin-kmem.c | 8 ++-- tools/perf/builtin-kvm.c | 6 +-- tools/perf/builtin-lock.c | 4 +- tools/perf/builtin-mem.c | 4 +- tools/perf/builtin-record.c | 50 ++++++++++----------- tools/perf/builtin-report.c | 14 +++--- tools/perf/builtin-sched.c | 8 ++-- tools/perf/builtin-script.c | 14 +++--- tools/perf/builtin-stat.c | 32 ++++++------- tools/perf/builtin-timechart.c | 6 +-- tools/perf/builtin-trace.c | 4 +- tools/perf/tests/topology.c | 10 ++--- tools/perf/util/auxtrace.c | 4 +- tools/perf/util/data-convert-bt.c | 6 +-- tools/perf/util/data.c | 92 +++++++++++++++++++------------------- tools/perf/util/data.h | 32 ++++++------- tools/perf/util/header.c | 20 ++++----- tools/perf/util/intel-bts.c | 6 +-- tools/perf/util/intel-pt.c | 6 +-- tools/perf/util/jit.h | 2 +- tools/perf/util/jitdump.c | 10 ++--- tools/perf/util/session.c | 44 +++++++++--------- tools/perf/util/session.h | 4 +- 30 files changed, 235 insertions(+), 235 deletions(-)
tools/perf/builtin-annotate.c +5 -5
@@ -356,7 +356,7 @@ static int __cmd_annotate(struct perf_annotate *ann) }if (total_nr_samples ==0 ) { -ui__error ("The %s file has no samples!\n" , session->file->path); +ui__error ("The %s file has no samples!\n" , session->data->path); goto out; }
@@ -400,7 +400,7 @@ int cmd_annotate(int argc, const char **argv) .ordering_requires_timestamps = true, }, }; -struct perf_data_file file = { +struct perf_data data = { .mode =PERF_DATA_MODE_READ , }; struct option options[] = {
@@ -410,7 +410,7 @@ int cmd_annotate(int argc, const char **argv) "only consider symbols in these dsos"),OPT_STRING ('s' ,"symbol" , &annotate.sym_hist_filter,"symbol" ,"symbol to annotate" ), -OPT_BOOLEAN ('f' ,"force" , &file.force,"don't complain, do it" ), +OPT_BOOLEAN ('f' ,"force" , &data.force,"don't complain, do it" ),OPT_INCR ('v' ,"verbose" , &verbose,"be more verbose (show symbol address, etc)" ), OPT_BOOLEAN('q', "quiet", &quiet, "do now show any message"),
@@ -482,9 +482,9 @@ int cmd_annotate(int argc, const char **argv)if (quiet)perf_quiet_option (); - file.path = input_name; + data.path = input_name; - annotate.session =perf_session__new (&file, false, &annotate.tool); + annotate.session =perf_session__new (&data, false, &annotate.tool);if (annotate.session ==NULL )return -1 ;
tools/perf/builtin-buildid-cache.c +4 -4
@@ -311,7 +311,7 @@ int cmd_buildid_cache(int argc, const char **argv) *kcore_filename =NULL ;char sbuf[STRERR_BUFSIZE ]; -struct perf_data_file file = { +struct perf_data data = { .mode =PERF_DATA_MODE_READ , };struct perf_session *session =NULL ;
@@ -352,10 +352,10 @@ int cmd_buildid_cache(int argc, const char **argv) nsi =nsinfo__new (ns_id);if (missing_filename) { - file.path = missing_filename; - file.force = force; + data.path = missing_filename; + data.force = force; - session =perf_session__new (&file, false,NULL ); + session =perf_session__new (&data, false,NULL );if (session ==NULL )return -1 ; }
tools/perf/builtin-buildid-list.c +4 -4
@@ -50,7 +50,7 @@ static bool dso__skip_buildid(struct dso *dso, int with_hits)static int perf_session__list_build_ids (bool force,bool with_hits) {struct perf_session *session; -struct perf_data_file file = { +struct perf_data data = { .path = input_name, .mode =PERF_DATA_MODE_READ , .force = force,
@@ -63,7 +63,7 @@ static int perf_session__list_build_ids(bool force, bool with_hits)if (filename__fprintf_build_id (input_name, stdout) >0 ) goto out; - session =perf_session__new (&file, false, &build_id__mark_dso_hit_ops); + session =perf_session__new (&data, false, &build_id__mark_dso_hit_ops);if (session ==NULL )return -1 ;
@@ -71,7 +71,7 @@ static int perf_session__list_build_ids(bool force, bool with_hits)* We take all buildids when the file contains AUX area tracing data * because we do not decode the trace because it would take too long. */ -if (!perf_data_file__is_pipe (&file) && +if (!perf_data__is_pipe (&data) &&perf_header__has_feat (&session->header,HEADER_AUXTRACE )) with_hits = false;
@@ -79,7 +79,7 @@ static int perf_session__list_build_ids(bool force, bool with_hits)* in pipe-mode, the only way to get the buildids is to parse * the record stream. Buildids are stored as RECORD_HEADER_BUILD_ID */ -if (with_hits ||perf_data_file__is_pipe (&file)) +if (with_hits ||perf_data__is_pipe (&data))perf_session__process_events (session);perf_session__fprintf_dsos_buildid (session, stdout, dso__skip_buildid, with_hits);
tools/perf/builtin-c2c.c +5 -5
@@ -2523,7 +2523,7 @@ static int perf_c2c__report(int argc, const char **argv) {struct perf_session *session;struct ui_progress prog; -struct perf_data_file file = { +struct perf_data data = { .mode =PERF_DATA_MODE_READ , };char callchain_default_opt[] =CALLCHAIN_DEFAULT_OPT ;
@@ -2572,8 +2572,8 @@ static int perf_c2c__report(int argc, const char **argv)if (!input_name || !strlen (input_name)) input_name ="perf.data" ; - file.path = input_name; - file.force = symbol_conf.force; + data.path = input_name; + data.force = symbol_conf.force; err =setup_display (display);if (err)
@@ -2591,7 +2591,7 @@ static int perf_c2c__report(int argc, const char **argv) goto out; } - session =perf_session__new (&file,0 , &c2c.tool); + session =perf_session__new (&data,0 , &c2c.tool);if (session ==NULL ) {pr_debug ("No memory for session\n" ); goto out;
@@ -2611,7 +2611,7 @@ static int perf_c2c__report(int argc, const char **argv) goto out_session;/* No pipe support at the moment. */ -if (perf_data_file__is_pipe (session->file)) { +if (perf_data__is_pipe (session->data)) {pr_debug ("No pipe support at the moment.\n" ); goto out_session; }
tools/perf/builtin-diff.c +9 -9
@@ -47,7 +47,7 @@ struct diff_hpp_fmt {struct data__file {struct perf_session *session; -struct perf_data_file file; +struct perf_data data;int idx;struct hists *hists;struct diff_hpp_fmt fmt[PERF_HPP_DIFF__MAX_INDEX ];
@@ -707,7 +707,7 @@ static void data__fprintf(void)data__for_each_file (i, d)fprintf (stdout,"# [%d] %s %s\n" , - d->idx, d->file.path, + d->idx, d->data.path, !d->idx ?"(Baseline)" :"" );fprintf (stdout,"#\n" );
@@ -776,16 +776,16 @@ static int __cmd_diff(void)int ret = -EINVAL , i;data__for_each_file (i, d) { - d->session =perf_session__new (&d->file, false, &tool); + d->session =perf_session__new (&d->data, false, &tool);if (!d->session) { -pr_err ("Failed to open %s\n" , d->file.path); +pr_err ("Failed to open %s\n" , d->data.path); ret =-1 ; goto out_delete; } ret =perf_session__process_events (d->session);if (ret) { -pr_err ("Failed to process %s\n" , d->file.path); +pr_err ("Failed to process %s\n" , d->data.path); goto out_delete; }
@@ -1286,11 +1286,11 @@ static int data_init(int argc, const char **argv)return -ENOMEM ;data__for_each_file (i, d) { -struct perf_data_file *file = &d->file; +struct perf_data *data = &d->data; - file->path = use_default ? defaults[i] : argv[i]; - file->mode =PERF_DATA_MODE_READ , - file->force = force, + data->path = use_default ? defaults[i] : argv[i]; + data->mode =PERF_DATA_MODE_READ , + data->force = force, d->idx = i; }
tools/perf/builtin-evlist.c +2 -2
@@ -21,14 +21,14 @@ static int __cmd_evlist(const char *file_name, struct perf_attr_details *details {struct perf_session *session;struct perf_evsel *pos; -struct perf_data_file file = { +struct perf_data data = { .path = file_name, .mode =PERF_DATA_MODE_READ , .force = details->force, };bool has_tracepoint = false; - session =perf_session__new (&file,0 ,NULL ); + session =perf_session__new (&data,0 ,NULL );if (session ==NULL )return -1 ;
tools/perf/builtin-inject.c +13 -13
@@ -35,7 +35,7 @@ struct perf_inject {bool strip;bool jit_mode;const char *input_name; -struct perf_data_file output; +struct perf_data output;u64 bytes_written;u64 aux_id;struct list_head samples;
@@ -52,7 +52,7 @@ static int output_bytes(struct perf_inject *inject, void *buf, size_t sz) {ssize_t size; - size =perf_data_file__write (&inject->output, buf, sz); + size =perf_data__write (&inject->output, buf, sz);if (size <0 )return -errno;
@@ -154,11 +154,11 @@ static s64 perf_event__repipe_auxtrace(struct perf_tool *tool,return ret; } -if (perf_data_file__is_pipe (session->file) || !session->one_mmap) { +if (perf_data__is_pipe (session->data) || !session->one_mmap) { ret =output_bytes (inject, event, event->header.size);if (ret <0 )return ret; - ret =copy_bytes (inject,perf_data_file__fd (session->file), + ret =copy_bytes (inject,perf_data__fd (session->data), event->auxtrace.size); }else { ret = output_bytes(inject, event,
@@ -637,8 +637,8 @@ static int __cmd_inject(struct perf_inject *inject) {int ret = -EINVAL ;struct perf_session *session = inject->session; -struct perf_data_file *file_out = &inject->output; -int fd =perf_data_file__fd (file_out); +struct perf_data *data_out = &inject->output; +int fd =perf_data__fd (data_out);u64 output_data_offset;signal (SIGINT , sig_handler);
@@ -693,14 +693,14 @@ static int __cmd_inject(struct perf_inject *inject)if (!inject->itrace_synth_opts.set)auxtrace_index__free (&session->auxtrace_index); -if (!file_out->is_pipe) +if (!data_out->is_pipe)lseek (fd, output_data_offset,SEEK_SET ); ret =perf_session__process_events (session);if (ret)return ret; -if (!file_out->is_pipe) { +if (!data_out->is_pipe) {if (inject->build_ids)perf_header__set_feat (&session->header,HEADER_BUILD_ID );
@@ -779,7 +779,7 @@ int cmd_inject(int argc, const char **argv) .mode = PERF_DATA_MODE_WRITE, }, }; -struct perf_data_file file = { +struct perf_data data = { .mode =PERF_DATA_MODE_READ , };int ret;
@@ -801,7 +801,7 @@ int cmd_inject(int argc, const char **argv) "be more verbose (show build ids, etc)"),OPT_STRING (0 ,"kallsyms" , &symbol_conf.kallsyms_name,"file" ,"kallsyms pathname" ), -OPT_BOOLEAN ('f' ,"force" , &file.force,"don't complain, do it" ), +OPT_BOOLEAN ('f' ,"force" , &data.force,"don't complain, do it" ),OPT_CALLBACK_OPTARG (0 ,"itrace" , &inject.itrace_synth_opts,NULL ,"opts" ,"Instruction Tracing options" , itrace_parse_synth_opts),
@@ -829,15 +829,15 @@ int cmd_inject(int argc, const char **argv)return -1 ; } -if (perf_data_file__open (&inject.output)) { +if (perf_data__open (&inject.output)) {perror ("failed to create output file" );return -1 ; } inject.tool.ordered_events = inject.sched_stat; - file.path = inject.input_name; - inject.session =perf_session__new (&file, true, &inject.tool); + data.path = inject.input_name; + inject.session =perf_session__new (&data, true, &inject.tool);if (inject.session ==NULL )return -1 ;
tools/perf/builtin-kmem.c +4 -4
@@ -1893,7 +1893,7 @@ int cmd_kmem(int argc, const char **argv) {const char *const default_slab_sort ="frag,hit,bytes" ;const char *const default_page_sort ="bytes,hit" ; -struct perf_data_file file = { +struct perf_data data = { .mode =PERF_DATA_MODE_READ , };const struct option kmem_options[] = {
@@ -1909,7 +1909,7 @@ int cmd_kmem(int argc, const char **argv) "page, order, migtype, gfp", parse_sort_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 ('f' ,"force" , &file.force,"don't complain, do it" ), +OPT_BOOLEAN ('f' ,"force" , &data.force,"don't complain, do it" ),OPT_CALLBACK_NOOPT (0 ,"slab" ,NULL ,NULL ,"Analyze slab allocator" , parse_slab_opt), OPT_CALLBACK_NOOPT(0, "page", NULL, NULL, "Analyze page allocator",
@@ -1949,9 +1949,9 @@ int cmd_kmem(int argc, const char **argv)return __cmd_record (argc, argv); } - file.path = input_name; + data.path = input_name; - kmem_session = session =perf_session__new (&file, false, &perf_kmem); + kmem_session = session =perf_session__new (&data, false, &perf_kmem);if (session ==NULL )return -1 ;
tools/perf/builtin-kvm.c +3 -3
@@ -1067,7 +1067,7 @@ static int read_events(struct perf_kvm_stat *kvm) .namespaces = perf_event__process_namespaces, .ordered_events = true, }; -struct perf_data_file file = { +struct perf_data file = { .path = kvm->file_name, .mode =PERF_DATA_MODE_READ , .force = kvm->force,
@@ -1358,7 +1358,7 @@ static int kvm_events_live(struct perf_kvm_stat *kvm,"perf kvm stat live [<options>]" , NULL }; -struct perf_data_file file = { +struct perf_data data = { .mode =PERF_DATA_MODE_WRITE , };
@@ -1432,7 +1432,7 @@ static int kvm_events_live(struct perf_kvm_stat *kvm,/* * perf session */ - kvm->session =perf_session__new (&file, false, &kvm->tool); + kvm->session =perf_session__new (&data, false, &kvm->tool);if (kvm->session ==NULL ) { err =-1 ; goto out;
tools/perf/builtin-lock.c +2 -2
@@ -864,13 +864,13 @@ static int __cmd_report(bool display_info) .namespaces = perf_event__process_namespaces, .ordered_events = true, }; -struct perf_data_file file = { +struct perf_data data = { .path = input_name, .mode =PERF_DATA_MODE_READ , .force = force, }; - session =perf_session__new (&file, false, &eops); + session =perf_session__new (&data, false, &eops);if (!session) {pr_err ("Initializing perf session failed\n" );return -1 ;
tools/perf/builtin-mem.c +2 -2
@@ -236,13 +236,13 @@ static int process_sample_event(struct perf_tool *tool,static int report_raw_events (struct perf_mem *mem) { -struct perf_data_file file = { +struct perf_data data = { .path = input_name, .mode =PERF_DATA_MODE_READ , .force = mem->force, };int ret; -struct perf_session *session =perf_session__new (&file, false, +struct perf_session *session =perf_session__new (&data, false, &mem->tool);if (session ==NULL )
tools/perf/builtin-record.c +25 -25
162 lines not on this page · raw message
tools/perf/builtin-report.c +7 -7
@@ -257,7 +257,7 @@ static int report__setup_sample_type(struct report *rep) {struct perf_session *session = rep->session;u64 sample_type =perf_evlist__combined_sample_type (session->evlist); -bool is_pipe =perf_data_file__is_pipe (session->file); +bool is_pipe =perf_data__is_pipe (session->data); if (session->itrace_synth_opts->callchain || (!is_pipe &&
@@ -568,7 +568,7 @@ static int __cmd_report(struct report *rep)int ret;struct perf_session *session = rep->session;struct perf_evsel *pos; -struct perf_data_file *file = session->file; +struct perf_data *data = session->data;signal (SIGINT , sig_handler);
@@ -637,7 +637,7 @@ static int __cmd_report(struct report *rep) rep->nr_entries +=evsel__hists (pos)->nr_entries;if (rep->nr_entries ==0 ) { -ui__error ("The %s file has no samples!\n" , file->path); +ui__error ("The %s file has no samples!\n" , data->path);return 0 ; }
@@ -879,7 +879,7 @@ int cmd_report(int argc, const char **argv) "Show inline function"), OPT_END() }; -struct perf_data_file file = { +struct perf_data data = { .mode =PERF_DATA_MODE_READ , };int ret =hists__init ();
@@ -940,11 +940,11 @@ int cmd_report(int argc, const char **argv) input_name ="perf.data" ; } - file.path = input_name; - file.force = symbol_conf.force; + data.path = input_name; + data.force = symbol_conf.force; repeat: - session =perf_session__new (&file, false, &report.tool); + session =perf_session__new (&data, false, &report.tool);if (session ==NULL )return -1 ;
tools/perf/builtin-sched.c +4 -4
@@ -1700,14 +1700,14 @@ static int perf_sched__read_events(struct perf_sched *sched) { "sched:sched_migrate_task", process_sched_migrate_task_event, }, };struct perf_session *session; -struct perf_data_file file = { +struct perf_data data = { .path = input_name, .mode =PERF_DATA_MODE_READ , .force = sched->force, };int rc =-1 ; - session =perf_session__new (&file, false, &sched->tool); + session =perf_session__new (&data, false, &sched->tool);if (session ==NULL ) {pr_debug ("No Memory for session\n" );return -1 ;
@@ -2902,7 +2902,7 @@ static int perf_sched__timehist(struct perf_sched *sched)const struct perf_evsel_str_handler migrate_handlers[] = { {"sched:sched_migrate_task" , timehist_migrate_task_event, }, }; -struct perf_data_file file = { +struct perf_data data = { .path = input_name, .mode =PERF_DATA_MODE_READ , .force = sched->force,
@@ -2930,7 +2930,7 @@ static int perf_sched__timehist(struct perf_sched *sched) symbol_conf.use_callchain = sched->show_callchain; - session =perf_session__new (&file, false, &sched->tool); + session =perf_session__new (&data, false, &sched->tool);if (session ==NULL )return -ENOMEM ;
tools/perf/builtin-script.c +7 -7
@@ -2446,14 +2446,14 @@ int find_scripts(char **scripts_array, char **scripts_path_array)char scripts_path[MAXPATHLEN ], lang_path[MAXPATHLEN ];DIR *scripts_dir, *lang_dir;struct perf_session *session; -struct perf_data_file file = { +struct perf_data data = { .path = input_name, .mode =PERF_DATA_MODE_READ , };char *temp;int i =0 ; - session =perf_session__new (&file, false,NULL ); + session =perf_session__new (&data, false,NULL );if (!session)return -1 ;
@@ -2731,7 +2731,7 @@ int cmd_script(int argc, const char **argv) .ordering_requires_timestamps = true, }, }; -struct perf_data_file file = { +struct perf_data data = { .mode =PERF_DATA_MODE_READ , }; const struct option options[] = {
@@ -2836,8 +2836,8 @@ int cmd_script(int argc, const char **argv) argc =parse_options_subcommand (argc, argv, options, script_subcommands, script_usage,PARSE_OPT_STOP_AT_NON_OPTION ); - file.path = input_name; - file.force = symbol_conf.force; + data.path = input_name; + data.force = symbol_conf.force;if (argc >1 && !strncmp (argv[0 ],"rec" ,strlen ("rec" ))) { rec_script_path =get_script_path (argv[1 ],RECORD_SUFFIX );
@@ -3004,7 +3004,7 @@ int cmd_script(int argc, const char **argv)if (!script_name)setup_pager (); - session =perf_session__new (&file, false, &script.tool); + session =perf_session__new (&data, false, &script.tool);if (session ==NULL )return -1 ;
@@ -3059,7 +3059,7 @@ int cmd_script(int argc, const char **argv) goto out_delete; } - input =open (file.path,O_RDONLY );/* input_name */ + input =open (data.path,O_RDONLY );/* input_name */ if (input <0 ) { err = -errno;perror ("failed to open file" );
tools/perf/builtin-stat.c +16 -16
@@ -175,7 +175,7 @@ static int print_free_counters_hint;struct perf_stat {bool record; -struct perf_data_file file; +struct perf_data data;struct perf_session *session;u64 bytes_written;struct perf_tool tool;
@@ -253,7 +253,7 @@ static int create_perf_stat_counter(struct perf_evsel *evsel)* by attr->sample_type != 0, and we can't run it on * stat sessions. */ -if (!(STAT_RECORD && perf_stat.file.is_pipe)) +if (!(STAT_RECORD && perf_stat.data.is_pipe)) attr->sample_type =PERF_SAMPLE_IDENTIFIER ;/*
@@ -295,7 +295,7 @@ static int process_synthesized_event(struct perf_tool *tool __maybe_unused, struct perf_sample *sample __maybe_unused, struct machine *machine __maybe_unused) { - if (perf_data_file__write(&perf_stat.file, event, event->header.size) < 0) { + if (perf_data__write(&perf_stat.data, event, event->header.size) < 0) { pr_err("failed to write perf data, error: %m\n");return -1 ; }
@@ -628,7 +628,7 @@ static int __run_perf_stat(int argc, const char **argv)size_t l;int status =0 ;const bool forks = (argc >0 ); -bool is_pipe =STAT_RECORD ? perf_stat.file.is_pipe : false; +bool is_pipe =STAT_RECORD ? perf_stat.data.is_pipe : false;struct perf_evsel_config_term *err_term;if (interval) {
@@ -719,10 +719,10 @@ static int __run_perf_stat(int argc, const char **argv) }if (STAT_RECORD ) { -int err, fd =perf_data_file__fd (&perf_stat.file); +int err, fd =perf_data__fd (&perf_stat.data);if (is_pipe) { - err =perf_header__write_pipe (perf_data_file__fd (&perf_stat.file)); + err =perf_header__write_pipe (perf_data__fd (&perf_stat.data)); }else { err =perf_session__write_header (perf_stat.session, evsel_list, fd, false);
@@ -1696,7 +1696,7 @@ static void print_counters(struct timespec *ts, int argc, const char **argv)char buf[64 ], *prefix =NULL ;/* Do not print anything if we record to the pipe. */ -if (STAT_RECORD && perf_stat.file.is_pipe) +if (STAT_RECORD && perf_stat.data.is_pipe)return ;if (interval)
@@ -2406,20 +2406,20 @@ static void init_features(struct perf_session *session)static int __cmd_record (int argc,const char **argv) {struct perf_session *session; -struct perf_data_file *file = &perf_stat.file; +struct perf_data *data = &perf_stat.data; argc =parse_options (argc, argv, stat_options, stat_record_usage,PARSE_OPT_STOP_AT_NON_OPTION );if (output_name) - file->path = output_name; + data->path = output_name;if (run_count !=1 || forever) {pr_err ("Cannot use -r option with perf stat record.\n" );return -1 ; } - session =perf_session__new (file, false,NULL ); + session =perf_session__new (data, false,NULL );if (session ==NULL ) {pr_err ("Perf session creation failed.\n" );return -1 ;
@@ -2477,7 +2477,7 @@ int process_stat_config_event(struct perf_tool *tool,if (st->aggr_mode !=AGGR_UNSET ) stat_config.aggr_mode = st->aggr_mode; -if (perf_stat.file.is_pipe) +if (perf_stat.data.is_pipe)perf_stat_init_aggr_mode ();else perf_stat_init_aggr_mode_file (st);
@@ -2585,10 +2585,10 @@ static int __cmd_report(int argc, const char **argv) input_name ="perf.data" ; } - perf_stat.file.path = input_name; - perf_stat.file.mode =PERF_DATA_MODE_READ ; + perf_stat.data.path = input_name; + perf_stat.data.mode =PERF_DATA_MODE_READ ; - session =perf_session__new (&perf_stat.file, false, &perf_stat.tool); + session =perf_session__new (&perf_stat.data, false, &perf_stat.tool);if (session ==NULL )return -1 ;
@@ -2859,7 +2859,7 @@ int cmd_stat(int argc, const char **argv)* records, but the need to suppress the kptr_restrict messages in older * tools remain -acme */ -int fd =perf_data_file__fd (&perf_stat.file); +int fd =perf_data__fd (&perf_stat.data);int err =perf_event__synthesize_kernel_mmap ((void *)&perf_stat, process_synthesized_event, &perf_stat.session->machines.host);
@@ -2873,7 +2873,7 @@ int cmd_stat(int argc, const char **argv)pr_err ("failed to write stat round event\n" ); } -if (!perf_stat.file.is_pipe) { +if (!perf_stat.data.is_pipe) { perf_stat.session->header.data_size += perf_stat.bytes_written;perf_session__write_header (perf_stat.session, evsel_list, fd, true); }
tools/perf/builtin-timechart.c +3 -3
@@ -1601,13 +1601,13 @@ static int __cmd_timechart(struct timechart *tchart, const char *output_name) { "syscalls:sys_exit_pselect6", process_exit_poll }, { "syscalls:sys_exit_select", process_exit_poll }, }; -struct perf_data_file file = { +struct perf_data data = { .path = input_name, .mode =PERF_DATA_MODE_READ , .force = tchart->force, }; -struct perf_session *session =perf_session__new (&file, false, +struct perf_session *session =perf_session__new (&data, false, &tchart->tool);int ret = -EINVAL ;
@@ -1617,7 +1617,7 @@ static int __cmd_timechart(struct timechart *tchart, const char *output_name)symbol__init (&session->header.env); (void )perf_header__process_sections (&session->header, -perf_data_file__fd (session->file), +perf_data__fd (session->data), tchart, process_header);
tools/perf/builtin-trace.c +2 -2
@@ -2529,7 +2529,7 @@ static int trace__replay(struct trace *trace)const struct perf_evsel_str_handler handlers[] = { {"probe:vfs_getname" , trace__vfs_getname, }, }; -struct perf_data_file file = { +struct perf_data data = { .path = input_name, .mode =PERF_DATA_MODE_READ , .force = trace->force,
@@ -2555,7 +2555,7 @@ static int trace__replay(struct trace *trace)/* add tid to output */ trace->multiple_threads = true; - session =perf_session__new (&file, false, &trace->tool); + session =perf_session__new (&data, false, &trace->tool);if (session ==NULL )return -1 ;
tools/perf/tests/topology.c +5 -5
@@ -29,12 +29,12 @@ static int get_temp(char *path)static int session_write_header (char *path) {struct perf_session *session; -struct perf_data_file file = { +struct perf_data data = { .path = path, .mode =PERF_DATA_MODE_WRITE , }; - session =perf_session__new (&file, false,NULL ); + session =perf_session__new (&data, false,NULL );TEST_ASSERT_VAL ("can't get session" , session); session->evlist =perf_evlist__new_default ();
@@ -46,7 +46,7 @@ static int session_write_header(char *path) session->header.data_size +=DATA_SIZE ;TEST_ASSERT_VAL ("failed to write header" , - !perf_session__write_header (session, session->evlist, file.fd, true)); + !perf_session__write_header (session, session->evlist, data.fd, true));perf_session__delete (session);
@@ -56,13 +56,13 @@ static int session_write_header(char *path)static int check_cpu_topology (char *path,struct cpu_map *map) {struct perf_session *session; -struct perf_data_file file = { +struct perf_data data = { .path = path, .mode =PERF_DATA_MODE_READ , };int i; - session =perf_session__new (&file, false,NULL ); + session =perf_session__new (&data, false,NULL );TEST_ASSERT_VAL ("can't get session" , session);for (i =0 ; i < session->header.env.nr_cpus_avail; i++) {
tools/perf/util/auxtrace.c +2 -2
@@ -208,7 +208,7 @@ static int auxtrace_queues__grow(struct auxtrace_queues *queues,static void *auxtrace_copy_data (u64 size,struct perf_session *session) { -int fd =perf_data_file__fd (session->file); +int fd =perf_data__fd (session->data);void *p;ssize_t ret;
@@ -305,7 +305,7 @@ static int auxtrace_queues__add_event_buffer(struct auxtrace_queues *queues,if (session->one_mmap) { buffer->data = buffer->data_offset - session->one_mmap_offset + session->one_mmap_addr; - }else if (perf_data_file__is_pipe (session->file)) { + }else if (perf_data__is_pipe (session->data)) { buffer->data =auxtrace_copy_data (buffer->size, session);if (!buffer->data)return -ENOMEM ;
tools/perf/util/data-convert-bt.c +3 -3
@@ -1577,7 +1577,7 @@ int bt_convert__perf2ctf(const char *input, const char *path, struct perf_data_convert_opts *opts) {struct perf_session *session; -struct perf_data_file file = { +struct perf_data data = { .path = input, .mode =PERF_DATA_MODE_READ , .force = opts->force,
@@ -1619,7 +1619,7 @@ int bt_convert__perf2ctf(const char *input, const char *path, err =-1 ;/* perf.data session */ - session =perf_session__new (&file,0 , &c.tool); + session =perf_session__new (&data,0 , &c.tool);if (!session) goto free_writer;
@@ -1650,7 +1650,7 @@ int bt_convert__perf2ctf(const char *input, const char *path,fprintf (stderr,"[ perf data convert: Converted '%s' into CTF data '%s' ]\n" , - file.path, path); + data.path, path); fprintf(stderr, "[ perf data convert: Converted and wrote %.3f MB (%" PRIu64 " samples",
tools/perf/util/data.c +46 -46
214 lines not on this page · raw message
tools/perf/util/data.h +16 -16
@@ -8,7 +8,7 @@ enum perf_data_mode { PERF_DATA_MODE_READ, }; -struct perf_data_file { +struct perf_data {const char *path;int fd;bool is_pipe;
@@ -17,43 +17,43 @@ struct perf_data_file {enum perf_data_mode mode; }; -static inline bool perf_data_file__is_read (struct perf_data_file *file) +static inline bool perf_data__is_read (struct perf_data *data) { -return file->mode ==PERF_DATA_MODE_READ ; +return data->mode ==PERF_DATA_MODE_READ ; } -static inline bool perf_data_file__is_write (struct perf_data_file *file) +static inline bool perf_data__is_write (struct perf_data *data) { -return file->mode ==PERF_DATA_MODE_WRITE ; +return data->mode ==PERF_DATA_MODE_WRITE ; } -static inline int perf_data_file__is_pipe (struct perf_data_file *file) +static inline int perf_data__is_pipe (struct perf_data *data) { -return file->is_pipe; +return data->is_pipe; } -static inline int perf_data_file__fd (struct perf_data_file *file) +static inline int perf_data__fd (struct perf_data *data) { -return file->fd; +return data->fd; } -static inline unsigned long perf_data_file__size (struct perf_data_file *file) +static inline unsigned long perf_data__size (struct perf_data *data) { -return file->size; +return data->size; } -int perf_data_file__open (struct perf_data_file *file); -void perf_data_file__close (struct perf_data_file *file); -ssize_t perf_data_file__write (struct perf_data_file *file, +int perf_data__open (struct perf_data *data); +void perf_data__close (struct perf_data *data); +ssize_t perf_data__write (struct perf_data *data,void *buf,size_t size);/* * If at_exit is set, only rename current perf.data to -* perf.data.<postfix>, continue write on original file. +* perf.data.<postfix>, continue write on original data. * Set at_exit when flushing the last output. * * Return value is fd of new output. */ -int perf_data_file__switch (struct perf_data_file *file, +int perf_data__switch (struct perf_data *data,const char *postfix,size_t pos,bool at_exit);#endif /* __PERF_DATA_H */
tools/perf/util/header.c +10 -10
@@ -1762,7 +1762,7 @@ process_event_desc(struct feat_fd *ff, void *data __maybe_unused) session = container_of(ff->ph, struct perf_session, header); -if (session->file->is_pipe) { +if (session->data->is_pipe) {/* Save events for reading later by print_event_desc, * since they can't be read again in pipe mode. */ ff->events = events;
@@ -1771,7 +1771,7 @@ process_event_desc(struct feat_fd *ff, void *data __maybe_unused)for (evsel = events; evsel->attr.size; evsel++)perf_evlist__set_event_name (session->evlist, evsel); -if (!session->file->is_pipe) +if (!session->data->is_pipe)free_event_desc (events);return 0 ;
@@ -2248,7 +2248,7 @@ int perf_header__fprintf_info(struct perf_session *session, FILE *fp, bool full) {struct header_print_data hd;struct perf_header *header = &session->header; -int fd =perf_data_file__fd (session->file); +int fd =perf_data__fd (session->data);struct stat st;int ret, bit;
@@ -2264,7 +2264,7 @@ int perf_header__fprintf_info(struct perf_session *session, FILE *fp, bool full)perf_header__process_sections (header, fd, &hd, perf_file_section__fprintf_info); -if (session->file->is_pipe) +if (session->data->is_pipe)return 0 ;fprintf (fp,"# missing features: " );
@@ -2757,7 +2757,7 @@ static int perf_header__read_pipe(struct perf_session *session)struct perf_pipe_file_header f_header;if (perf_file_header__read_pipe (&f_header, header, -perf_data_file__fd (session->file), +perf_data__fd (session->data), session->repipe) <0 ) {pr_debug ("incompatible file format\n" );return -EINVAL ;
@@ -2860,13 +2860,13 @@ static int perf_evlist__prepare_tracepoint_events(struct perf_evlist *evlist,int perf_session__read_header (struct perf_session *session) { -struct perf_data_file *file = session->file; +struct perf_data *data = session->data;struct perf_header *header = &session->header;struct perf_file_header f_header;struct perf_file_attr f_attr;u64 f_id;int nr_attrs, nr_ids, i, j; -int fd =perf_data_file__fd (file); +int fd =perf_data__fd (data); session->evlist =perf_evlist__new ();if (session->evlist ==NULL )
@@ -2874,7 +2874,7 @@ int perf_session__read_header(struct perf_session *session) session->evlist->env = &header->env; session->machines.host.env = &header->env; -if (perf_data_file__is_pipe (file)) +if (perf_data__is_pipe (data))return perf_header__read_pipe (session);if (perf_file_header__read (&f_header, header, fd) <0 )
@@ -2889,7 +2889,7 @@ int perf_session__read_header(struct perf_session *session)if (f_header.data.size ==0 ) {pr_warning ("WARNING: The %s file's data size field is 0 which is unexpected.\n" "Was the 'perf record' command properly terminated?\n" , - file->path); + data->path); } nr_attrs = f_header.attrs.size / f_header.attr_size;
@@ -3397,7 +3397,7 @@ int perf_event__process_tracing_data(struct perf_tool *tool __maybe_unused, struct perf_session *session) {ssize_t size_read, padding, size = event->tracing_data.size; -int fd =perf_data_file__fd (session->file); +int fd =perf_data__fd (session->data);off_t offset =lseek (fd,0 ,SEEK_CUR );char buf[BUFSIZ ];
tools/perf/util/intel-bts.c +3 -3
@@ -500,7 +500,7 @@ static int intel_bts_process_queue(struct intel_bts_queue *btsq, u64 *timestamp) }if (!buffer->data) { -int fd =perf_data_file__fd (btsq->bts->session->file); +int fd =perf_data__fd (btsq->bts->session->data); buffer->data =auxtrace_buffer__get_data (buffer, fd);if (!buffer->data) {
@@ -664,10 +664,10 @@ static int intel_bts_process_auxtrace_event(struct perf_session *session,if (!bts->data_queued) {struct auxtrace_buffer *buffer;off_t data_offset; -int fd =perf_data_file__fd (session->file); +int fd =perf_data__fd (session->data);int err; -if (perf_data_file__is_pipe (session->file)) { +if (perf_data__is_pipe (session->data)) { data_offset =0 ; }else { data_offset =lseek (fd,0 ,SEEK_CUR );
tools/perf/util/intel-pt.c +3 -3
@@ -271,7 +271,7 @@ static int intel_pt_get_trace(struct intel_pt_buffer *b, void *data) ptq->buffer = buffer;if (!buffer->data) { -int fd =perf_data_file__fd (ptq->pt->session->file); +int fd =perf_data__fd (ptq->pt->session->data); buffer->data =auxtrace_buffer__get_data (buffer, fd);if (!buffer->data)
@@ -2084,10 +2084,10 @@ static int intel_pt_process_auxtrace_event(struct perf_session *session,if (!pt->data_queued) {struct auxtrace_buffer *buffer;off_t data_offset; -int fd =perf_data_file__fd (session->file); +int fd =perf_data__fd (session->data);int err; -if (perf_data_file__is_pipe (session->file)) { +if (perf_data__is_pipe (session->data)) { data_offset =0 ; }else { data_offset =lseek (fd,0 ,SEEK_CUR );
tools/perf/util/jit.h +1 -1
@@ -3,7 +3,7 @@#include <data.h> -int jit_process (struct perf_session *session,struct perf_data_file *output, +int jit_process (struct perf_session *session,struct perf_data *output,struct machine *machine,char *filename,pid_t pid,u64 *nbytes);int jit_inject_record (const char *filename);
tools/perf/util/jitdump.c +5 -5
@@ -29,7 +29,7 @@#include "sane_ctype.h" struct jit_buf_desc { -struct perf_data_file *output; +struct perf_data *output;struct perf_session *session;struct machine *machine;union jr_entry *entry;
@@ -60,8 +60,8 @@ struct debug_line_info {struct jit_tool {struct perf_tool tool; -struct perf_data_file output; -struct perf_data_file input; +struct perf_data output; +struct perf_data input;u64 bytes_written; };
@@ -356,7 +356,7 @@ jit_inject_event(struct jit_buf_desc *jd, union perf_event *event) {ssize_t size; - size =perf_data_file__write (jd->output, event, event->header.size); + size =perf_data__write (jd->output, event, event->header.size);if (size <0 )return -1 ;
@@ -751,7 +751,7 @@ jit_detect(char *mmap_name, pid_t pid) int jit_process(struct perf_session *session, - struct perf_data_file *output, + struct perf_data *output, struct machine *machine, char *filename, pid_t pid,
tools/perf/util/session.c +22 -22
144 lines not on this page · raw message
tools/perf/util/session.h +2 -2
@@ -32,13 +32,13 @@ struct perf_session {void *one_mmap_addr;u64 one_mmap_offset;struct ordered_events ordered_events; -struct perf_data_file *file; +struct perf_data *data;struct perf_tool *tool; };struct perf_tool ; -struct perf_session *perf_session__new (struct perf_data_file *file, +struct perf_session *perf_session__new (struct perf_data *data,bool repipe,struct perf_tool *tool);void perf_session__delete (struct perf_session *session);
Signature · 1 line
2.13.6
Jiri Olsa
reviewerPATCH 4/9 perf tools: Add struct perf_data_file
In reply to Jiri OlsaAdding struct perf_data_file represent single file within perf_data struct.
--- tools/perf/builtin-annotate.c | 4 ++-- tools/perf/builtin-buildid-cache.c | 4 ++-- tools/perf/builtin-buildid-list.c | 8 ++++--- tools/perf/builtin-c2c.c | 4 ++-- tools/perf/builtin-diff.c | 12 +++++----- tools/perf/builtin-evlist.c | 8 ++++--- tools/perf/builtin-inject.c | 12 ++++++---- tools/perf/builtin-kmem.c | 2 +- tools/perf/builtin-kvm.c | 8 ++++--- tools/perf/builtin-lock.c | 8 ++++--- tools/perf/builtin-mem.c | 8 ++++--- tools/perf/builtin-record.c | 6 ++--- tools/perf/builtin-report.c | 6 ++--- tools/perf/builtin-sched.c | 16 ++++++++----- tools/perf/builtin-script.c | 12 ++++++---- tools/perf/builtin-stat.c | 6 ++--- tools/perf/builtin-timechart.c | 8 ++++--- tools/perf/builtin-trace.c | 8 ++++--- tools/perf/tests/topology.c | 14 +++++++---- tools/perf/util/data-convert-bt.c | 8 +++---- tools/perf/util/data.c | 48 +++++++++++++++++++------------------- tools/perf/util/data.h | 10 +++++--- tools/perf/util/header.c | 2 +- 23 files changed, 126 insertions(+), 96 deletions(-)
tools/perf/builtin-annotate.c +2 -2
@@ -356,7 +356,7 @@ static int __cmd_annotate(struct perf_annotate *ann) }if (total_nr_samples ==0 ) { -ui__error ("The %s file has no samples!\n" , session->data->path); +ui__error ("The %s file has no samples!\n" , session->data->file.path); goto out; }
@@ -482,7 +482,7 @@ int cmd_annotate(int argc, const char **argv)if (quiet)perf_quiet_option (); - data.path = input_name; + data.file.path = input_name; annotate.session =perf_session__new (&data, false, &annotate.tool);if (annotate.session ==NULL )
tools/perf/builtin-buildid-cache.c +2 -2
@@ -352,8 +352,8 @@ int cmd_buildid_cache(int argc, const char **argv) nsi =nsinfo__new (ns_id);if (missing_filename) { - data.path = missing_filename; - data.force = force; + data.file.path = missing_filename; + data.force = force; session =perf_session__new (&data, false,NULL );if (session ==NULL )
tools/perf/builtin-buildid-list.c +5 -3
@@ -51,9 +51,11 @@ static int perf_session__list_build_ids(bool force, bool with_hits) {struct perf_session *session;struct perf_data data = { - .path = input_name, - .mode =PERF_DATA_MODE_READ , - .force = force, + .file = { + .path = input_name, + }, + .mode =PERF_DATA_MODE_READ , + .force = force, };symbol__elf_init ();
tools/perf/builtin-c2c.c +2 -2
@@ -2572,8 +2572,8 @@ static int perf_c2c__report(int argc, const char **argv)if (!input_name || !strlen (input_name)) input_name ="perf.data" ; - data.path = input_name; - data.force = symbol_conf.force; + data.file.path = input_name; + data.force = symbol_conf.force; err =setup_display (display);if (err)
tools/perf/builtin-diff.c +6 -6
@@ -707,7 +707,7 @@ static void data__fprintf(void)data__for_each_file (i, d)fprintf (stdout,"# [%d] %s %s\n" , - d->idx, d->data.path, + d->idx, d->data.file.path, !d->idx ?"(Baseline)" :"" );fprintf (stdout,"#\n" );
@@ -778,14 +778,14 @@ static int __cmd_diff(void)data__for_each_file (i, d) { d->session =perf_session__new (&d->data, false, &tool);if (!d->session) { -pr_err ("Failed to open %s\n" , d->data.path); +pr_err ("Failed to open %s\n" , d->data.file.path); ret =-1 ; goto out_delete; } ret =perf_session__process_events (d->session);if (ret) { -pr_err ("Failed to process %s\n" , d->data.path); +pr_err ("Failed to process %s\n" , d->data.file.path); goto out_delete; }
@@ -1288,9 +1288,9 @@ static int data_init(int argc, const char **argv)data__for_each_file (i, d) {struct perf_data *data = &d->data; - data->path = use_default ? defaults[i] : argv[i]; - data->mode =PERF_DATA_MODE_READ , - data->force = force, + data->file.path = use_default ? defaults[i] : argv[i]; + data->mode =PERF_DATA_MODE_READ , + data->force = force, d->idx = i; }
tools/perf/builtin-evlist.c +5 -3
@@ -22,9 +22,11 @@ static int __cmd_evlist(const char *file_name, struct perf_attr_details *detailsstruct perf_session *session;struct perf_evsel *pos;struct perf_data data = { - .path = file_name, - .mode =PERF_DATA_MODE_READ , - .force = details->force, + .file = { + .path = file_name, + }, + .mode =PERF_DATA_MODE_READ , + .force = details->force, };bool has_tracepoint = false;
tools/perf/builtin-inject.c +7 -5
@@ -145,7 +145,7 @@ static s64 perf_event__repipe_auxtrace(struct perf_tool *tool,if (!inject->output.is_pipe) {off_t offset; - offset =lseek (inject->output.fd,0 ,SEEK_CUR ); + offset =lseek (inject->output.file.fd,0 ,SEEK_CUR );if (offset ==-1 )return -errno; ret = auxtrace_index__auxtrace_event(&session->auxtrace_index,
@@ -775,8 +775,10 @@ int cmd_inject(int argc, const char **argv) .input_name = "-", .samples = LIST_HEAD_INIT(inject.samples), .output = { - .path = "-", - .mode = PERF_DATA_MODE_WRITE, + .file = { + .path = "-", + }, + .mode = PERF_DATA_MODE_WRITE, }, };struct perf_data data = {
@@ -789,7 +791,7 @@ int cmd_inject(int argc, const char **argv) "Inject build-ids into the output stream"),OPT_STRING ('i' ,"input" , &inject.input_name,"file" ,"input file name" ), -OPT_STRING ('o' ,"output" , &inject.output.path,"file" , +OPT_STRING ('o' ,"output" , &inject.output.file.path,"file" ,"output file name" ),OPT_BOOLEAN ('s' ,"sched-stat" , &inject.sched_stat, "Merge sched-stat and sched-switch for getting events "
@@ -836,7 +838,7 @@ int cmd_inject(int argc, const char **argv) inject.tool.ordered_events = inject.sched_stat; - data.path = inject.input_name; + data.file.path = inject.input_name; inject.session =perf_session__new (&data, true, &inject.tool);if (inject.session ==NULL )return -1 ;
tools/perf/builtin-kmem.c +1 -1
@@ -1949,7 +1949,7 @@ int cmd_kmem(int argc, const char **argv)return __cmd_record (argc, argv); } - data.path = input_name; + data.file.path = input_name; kmem_session = session =perf_session__new (&data, false, &perf_kmem);if (session ==NULL )
tools/perf/builtin-kvm.c +5 -3
@@ -1068,9 +1068,11 @@ static int read_events(struct perf_kvm_stat *kvm) .ordered_events = true, };struct perf_data file = { - .path = kvm->file_name, - .mode =PERF_DATA_MODE_READ , - .force = kvm->force, + .file = { + .path = kvm->file_name, + }, + .mode =PERF_DATA_MODE_READ , + .force = kvm->force, }; kvm->tool = eops;
tools/perf/builtin-lock.c +5 -3
@@ -865,9 +865,11 @@ static int __cmd_report(bool display_info) .ordered_events = true, };struct perf_data data = { - .path = input_name, - .mode =PERF_DATA_MODE_READ , - .force = force, + .file = { + .path = input_name, + }, + .mode =PERF_DATA_MODE_READ , + .force = force, }; session =perf_session__new (&data, false, &eops);
tools/perf/builtin-mem.c +5 -3
@@ -237,9 +237,11 @@ static int process_sample_event(struct perf_tool *tool,static int report_raw_events (struct perf_mem *mem) {struct perf_data data = { - .path = input_name, - .mode =PERF_DATA_MODE_READ , - .force = mem->force, + .file = { + .path = input_name, + }, + .mode =PERF_DATA_MODE_READ , + .force = mem->force, };int ret; struct perf_session *session = perf_session__new(&data, false,
tools/perf/builtin-record.c +3 -3
@@ -618,7 +618,7 @@ record__switch_output(struct record *rec, bool at_exit)if (!quiet)fprintf (stderr,"[ perf record: Dump %s.%s ]\n" , - data->path, timestamp); + data->file.path, timestamp);/* Output tracking events */ if (!at_exit) {
@@ -1118,7 +1118,7 @@ static int __cmd_record(struct record *rec, int argc, const char **argv)fprintf (stderr,"[ perf record: Captured and wrote %.3f MB %s%s%s ]\n" ,perf_data__size (data) /1024.0 /1024.0 , - data->path, postfix, samples); + data->file.path, postfix, samples); } out_delete_session:
@@ -1482,7 +1482,7 @@ static struct option __record_options[] = {OPT_STRING ('C' ,"cpu" , &record.opts.target.cpu_list,"cpu" ,"list of cpus to monitor" ),OPT_U64 ('c' ,"count" , &record.opts.user_interval,"event period to sample" ), -OPT_STRING ('o' ,"output" , &record.data.path,"file" , +OPT_STRING ('o' ,"output" , &record.data.file.path,"file" ,"output file name" ), OPT_BOOLEAN_SET('i', "no-inherit", &record.opts.no_inherit, &record.opts.no_inherit_set,
tools/perf/builtin-report.c +3 -3
@@ -637,7 +637,7 @@ static int __cmd_report(struct report *rep) rep->nr_entries +=evsel__hists (pos)->nr_entries;if (rep->nr_entries ==0 ) { -ui__error ("The %s file has no samples!\n" , data->path); +ui__error ("The %s file has no samples!\n" , data->file.path);return 0 ; }
@@ -940,8 +940,8 @@ int cmd_report(int argc, const char **argv) input_name ="perf.data" ; } - data.path = input_name; - data.force = symbol_conf.force; + data.file.path = input_name; + data.force = symbol_conf.force; repeat: session =perf_session__new (&data, false, &report.tool);
tools/perf/builtin-sched.c +10 -6
@@ -1701,9 +1701,11 @@ static int perf_sched__read_events(struct perf_sched *sched) };struct perf_session *session;struct perf_data data = { - .path = input_name, - .mode =PERF_DATA_MODE_READ , - .force = sched->force, + .file = { + .path = input_name, + }, + .mode =PERF_DATA_MODE_READ , + .force = sched->force, };int rc =-1 ;
@@ -2903,9 +2905,11 @@ static int perf_sched__timehist(struct perf_sched *sched) { "sched:sched_migrate_task", timehist_migrate_task_event, }, };struct perf_data data = { - .path = input_name, - .mode =PERF_DATA_MODE_READ , - .force = sched->force, + .file = { + .path = input_name, + }, + .mode =PERF_DATA_MODE_READ , + .force = sched->force, };struct perf_session *session;
tools/perf/builtin-script.c +7 -5
@@ -2447,8 +2447,10 @@ int find_scripts(char **scripts_array, char **scripts_path_array)DIR *scripts_dir, *lang_dir;struct perf_session *session;struct perf_data data = { - .path = input_name, - .mode =PERF_DATA_MODE_READ , + .file = { + .path = input_name, + }, + .mode =PERF_DATA_MODE_READ , };char *temp;int i =0 ;
@@ -2836,8 +2838,8 @@ int cmd_script(int argc, const char **argv) argc =parse_options_subcommand (argc, argv, options, script_subcommands, script_usage,PARSE_OPT_STOP_AT_NON_OPTION ); - data.path = input_name; - data.force = symbol_conf.force; + data.file.path = input_name; + data.force = symbol_conf.force;if (argc >1 && !strncmp (argv[0 ],"rec" ,strlen ("rec" ))) { rec_script_path =get_script_path (argv[1 ],RECORD_SUFFIX );
@@ -3059,7 +3061,7 @@ int cmd_script(int argc, const char **argv) goto out_delete; } - input =open (data.path,O_RDONLY );/* input_name */ + input =open (data.file.path,O_RDONLY );/* input_name */ if (input <0 ) { err = -errno;perror ("failed to open file" );
tools/perf/builtin-stat.c +3 -3
@@ -2412,7 +2412,7 @@ static int __cmd_record(int argc, const char **argv) PARSE_OPT_STOP_AT_NON_OPTION);if (output_name) - data->path = output_name; + data->file.path = output_name;if (run_count !=1 || forever) {pr_err ("Cannot use -r option with perf stat record.\n" );
@@ -2585,8 +2585,8 @@ static int __cmd_report(int argc, const char **argv) input_name ="perf.data" ; } - perf_stat.data.path = input_name; - perf_stat.data.mode =PERF_DATA_MODE_READ ; + perf_stat.data.file.path = input_name; + perf_stat.data.mode =PERF_DATA_MODE_READ ; session =perf_session__new (&perf_stat.data, false, &perf_stat.tool);if (session ==NULL )
tools/perf/builtin-timechart.c +5 -3
@@ -1602,9 +1602,11 @@ static int __cmd_timechart(struct timechart *tchart, const char *output_name) { "syscalls:sys_exit_select", process_exit_poll }, };struct perf_data data = { - .path = input_name, - .mode =PERF_DATA_MODE_READ , - .force = tchart->force, + .file = { + .path = input_name, + }, + .mode =PERF_DATA_MODE_READ , + .force = tchart->force, }; struct perf_session *session = perf_session__new(&data, false,
tools/perf/builtin-trace.c +5 -3
@@ -2530,9 +2530,11 @@ static int trace__replay(struct trace *trace) { "probe:vfs_getname", trace__vfs_getname, }, };struct perf_data data = { - .path = input_name, - .mode =PERF_DATA_MODE_READ , - .force = trace->force, + .file = { + .path = input_name, + }, + .mode =PERF_DATA_MODE_READ , + .force = trace->force, };struct perf_session *session;struct perf_evsel *evsel;
tools/perf/tests/topology.c +9 -5
@@ -30,8 +30,10 @@ static int session_write_header(char *path) {struct perf_session *session;struct perf_data data = { - .path = path, - .mode =PERF_DATA_MODE_WRITE , + .file = { + .path = path, + }, + .mode =PERF_DATA_MODE_WRITE , }; session =perf_session__new (&data, false,NULL );
@@ -46,7 +48,7 @@ static int session_write_header(char *path) session->header.data_size +=DATA_SIZE ;TEST_ASSERT_VAL ("failed to write header" , - !perf_session__write_header (session, session->evlist, data.fd, true)); + !perf_session__write_header (session, session->evlist, data.file.fd, true));perf_session__delete (session);
@@ -57,8 +59,10 @@ static int check_cpu_topology(char *path, struct cpu_map *map) {struct perf_session *session;struct perf_data data = { - .path = path, - .mode =PERF_DATA_MODE_READ , + .file = { + .path = path, + }, + .mode =PERF_DATA_MODE_READ , };int i;
tools/perf/util/data-convert-bt.c +4 -4
@@ -1578,9 +1578,9 @@ int bt_convert__perf2ctf(const char *input, const char *path, {struct perf_session *session;struct perf_data data = { - .path = input, - .mode =PERF_DATA_MODE_READ , - .force = opts->force, + .file.path = input, + .mode =PERF_DATA_MODE_READ , + .force = opts->force, };struct convert c = { .tool = {
@@ -1650,7 +1650,7 @@ int bt_convert__perf2ctf(const char *input, const char *path,fprintf (stderr,"[ perf data convert: Converted '%s' into CTF data '%s' ]\n" , - data.path, path); + data.file.path, path); fprintf(stderr, "[ perf data convert: Converted and wrote %.3f MB (%" PRIu64 " samples",
tools/perf/util/data.c +24 -24
148 lines not on this page · raw message
tools/perf/util/data.h +7 -3
@@ -8,9 +8,13 @@ enum perf_data_mode { PERF_DATA_MODE_READ, }; +struct perf_data_file { +const char *path; +int fd; +}; +struct perf_data { -const char *path; -int fd; +struct perf_data_file file;bool is_pipe;bool force;unsigned long size;
@@ -34,7 +38,7 @@ static inline int perf_data__is_pipe(struct perf_data *data)static inline int perf_data__fd (struct perf_data *data) { -return data->fd; +return data->file.fd; }static inline unsigned long perf_data__size (struct perf_data *data)
tools/perf/util/header.c +1 -1
@@ -2889,7 +2889,7 @@ int perf_session__read_header(struct perf_session *session)if (f_header.data.size ==0 ) {pr_warning ("WARNING: The %s file's data size field is 0 which is unexpected.\n" "Was the 'perf record' command properly terminated?\n" , - data->path); + data->file.path); } nr_attrs = f_header.attrs.size / f_header.attr_size;
Signature · 1 line
2.13.6
Jiri Olsa
reviewerPATCH 5/9 perf tools: Add perf_data_file__write function
In reply to Jiri OlsaAdding perf_data_file__write function to provide
single file write operation.
--- tools/perf/util/data.c | 8 +++++++- tools/perf/util/data.h | 2 ++ 2 files changed, 9 insertions(+), 1 deletion(-)
tools/perf/util/data.c +7 -1
@@ -144,10 +144,16 @@ void perf_data__close(struct perf_data *data)close (data->file.fd); } +ssize_t perf_data_file__write (struct perf_data_file *file, +void *buf,size_t size) +{ +return writen (file->fd, buf, size); +} +ssize_t perf_data__write (struct perf_data *data,void *buf,size_t size) { -return writen (data->file.fd, buf, size); +return perf_data_file__write (&data->file, buf, size); } int perf_data__switch(struct perf_data *data,
tools/perf/util/data.h +2 -0
@@ -50,6 +50,8 @@ int perf_data__open(struct perf_data *data);void perf_data__close (struct perf_data *data);ssize_t perf_data__write (struct perf_data *data,void *buf,size_t size); +ssize_t perf_data_file__write (struct perf_data_file *file, +void *buf,size_t size);/* * If at_exit is set, only rename current perf.data to * perf.data.<postfix>, continue write on original data.
Signature · 1 line
2.13.6
Jiri Olsa
reviewerPATCH 6/9 perf stat: Move the shadow stats scale computation in perf_stat__update_shadow_stats
In reply to Jiri OlsaMoving the shadow stats scale computation under perf_stat__update_shadow_stats function, so it's centralized and we don't forget to do it. It also saves few lines of code.
--- tools/perf/builtin-stat.c | 3 +-- tools/perf/util/stat-shadow.c | 48 ++++++++++++++++++++++--------------------- tools/perf/util/stat.c | 6 ++---- tools/perf/util/stat.h | 2 +- 4 files changed, 29 insertions(+), 30 deletions(-)
tools/perf/builtin-stat.c +1 -2
@@ -1267,8 +1267,7 @@ static void aggr_update_shadow(void)continue ; val +=perf_counts (counter->counts, cpu,0 )->val; } - val = val * counter->scale; -perf_stat__update_shadow_stats (counter, &val, +perf_stat__update_shadow_stats (counter, val,first_shadow_cpu (counter, id)); } }
tools/perf/util/stat-shadow.c +25 -23
83 lines not on this page · raw message
tools/perf/util/stat.c +2 -4
@@ -277,7 +277,7 @@ process_counter_values(struct perf_stat_config *config, struct perf_evsel *evselperf_evsel__compute_deltas (evsel, cpu, thread, count);perf_counts_values__scale (count, config->scale,NULL );if (config->aggr_mode ==AGGR_NONE ) -perf_stat__update_shadow_stats (evsel, count->values, cpu); +perf_stat__update_shadow_stats (evsel, count->val, cpu);break ;case AGGR_GLOBAL : aggr->val += count->val;
@@ -320,7 +320,6 @@ int perf_stat_process_counter(struct perf_stat_config *config,struct perf_counts_values *aggr = &counter->counts->aggr;struct perf_stat_evsel *ps = counter->priv;u64 *count = counter->counts->aggr.values; -u64 val;int i, ret; aggr->val = aggr->ena = aggr->run =0 ;
@@ -360,8 +359,7 @@ int perf_stat_process_counter(struct perf_stat_config *config,/* * Save the full runtime - to allow normalization during printout: */ - val = counter->scale * *count; -perf_stat__update_shadow_stats (counter, &val,0 ); +perf_stat__update_shadow_stats (counter, *count,0 );return 0 ; }
tools/perf/util/stat.h +1 -1
@@ -82,7 +82,7 @@ typedef void (*new_line_t )(void *ctx);void perf_stat__init_shadow_stats (void );void perf_stat__reset_shadow_stats (void ); -void perf_stat__update_shadow_stats (struct perf_evsel *counter,u64 *count, +void perf_stat__update_shadow_stats (struct perf_evsel *counter,u64 count,int cpu);struct perf_stat_output_ctx {void *ctx;
Signature · 1 line
2.13.6
Jiri Olsa
reviewerPATCH 7/9 perf stat: Make --per-thread update shadow stats to show metrics
In reply to Jiri OlsaWe should support this because it would allow easily to collect metrics for different threads in applications.
Original patch from posted by Jin Yao in here [1].
1. Current output, for example:
root@skl:/tmp# perf stat --per-thread -p 21623 ^C Performance counter stats for process id '21623':
vmstat-21623 0.517479 task-clock (msec) # 0.000 CPUs utilized
vmstat-21623 1 context-switches
vmstat-21623 0 cpu-migrations
vmstat-21623 0 page-faults
vmstat-21623 461,306 cycles
vmstat-21623 630,724 instructions
vmstat-21623 136,265 branches
vmstat-21623 2,520 branch-misses1.444020756 seconds time elapsed
root@skl:/tmp# perf stat --per-thread --metrics ipc -p 21623 ^C Performance counter stats for process id '21623':
vmstat-21623 631,185 inst_retired.any
vmstat-21623 605,893 cpu_clk_unhalted.thread1.415679293 seconds time elapsed
2. With this patch, the result would be:
root@skl:/tmp# perf stat --per-thread -p 21623 ^C Performance counter stats for process id '21623':
vmstat-21623 0.533759 task-clock (msec) # 0.000 CPUs utilized
vmstat-21623 1 context-switches # 0.002 M/sec
vmstat-21623 0 cpu-migrations # 0.000 K/sec
vmstat-21623 0 page-faults # 0.000 K/sec
vmstat-21623 473,896 cycles # 0.888 GHz
vmstat-21623 631,072 instructions # 1.33 insn per cycle
vmstat-21623 136,307 branches # 255.372 M/sec
vmstat-21623 2,524 branch-misses # 1.85% of all branches1.544862861 seconds time elapsed
root@skl:/tmp# perf stat --per-thread --metrics ipc -p 21623 ^C Performance counter stats for process id '21623':
vmstat-21623 1,259,104 inst_retired.any # 1.2 IPC
vmstat-21623 1,056,756 cpu_clk_unhalted.thread2.040954502 seconds time elapsed
[1] https://marc.info/?l=linux-kernel&m=150777054620511&w=2
Originally-from: Jin Yao <[email protected]>
--- tools/perf/util/stat.c | 2 ++ 1 file changed, 2 insertions(+)
tools/perf/util/stat.c +2 -0
@@ -278,6 +278,8 @@ process_counter_values(struct perf_stat_config *config, struct perf_evsel *evselperf_counts_values__scale (count, config->scale,NULL );if (config->aggr_mode ==AGGR_NONE )perf_stat__update_shadow_stats (evsel, count->val, cpu); +if (config->aggr_mode ==AGGR_THREAD ) +perf_stat__update_shadow_stats (evsel, count->val,0 );break ;case AGGR_GLOBAL : aggr->val += count->val;
Signature · 1 line
2.13.6
Jiri Olsa
reviewerPATCH 8/9 perf tools: Check wether the eBPF file exists in event parsing
In reply to Jiri OlsaFrom: Jiri Olsa <[email protected]>
Adding the check wether the eBPF file exists, to consider it as eBPF input file. This way we can differentiate eBPF events from events that end up with same suffix as eBPF file.
Before:
$ perf stat -e 'cpu/uops_executed.core/' true
bpf: builtin compilation failed: -95, try external compiler
WARNING: unable to get correct kernel building directory.
Hint: Set correct kbuild directory using 'kbuild-dir' option in [llvm]
section of ~/.perfconfig or set it to "" to suppress kbuild
detection. event syntax error: 'cpu/uops_executed.core/'
\___ Failed to load cpu/uops_executed.c from source: 'version' section incorrect or lost
After:
$ perf stat -e 'cpu/uops_executed.core/' true
Performance counter stats for 'true':
181,533 cpu/uops_executed.core/:u
0.002795447 seconds time elapsedIf user makes type in the eBPF file, we prioritize the event syntax and show following warning:
$ perf stat -e 'krava.c//' true
event syntax error: 'krava.c//'
\___ Cannot find PMU `krava.c'. Missing kernel support?--- tools/perf/util/parse-events.l | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-)
tools/perf/util/parse-events.l +15 -2
@@ -8,6 +8,9 @@ %{ #include <errno.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> #include "../perf.h" #include "parse-events.h" #include "parse-events-bison.h"
@@ -53,9 +56,8 @@ static int str(yyscan_t scanner, int token) return token; } -static bool isbpf(yyscan_t scanner) +static bool isbpf_suffix(char *text) { - char *text = parse_events_get_text(scanner); int len = strlen(text); if (len < 2)
@@ -68,6 +70,17 @@ static bool isbpf(yyscan_t scanner) return false; } +static bool isbpf(yyscan_t scanner) +{ + char *text = parse_events_get_text(scanner); + struct stat st; + + if (!isbpf_suffix(text)) + return false; + + return stat(text, &st) == 0; +} + /* * This function is called when the parser gets two kind of input: *
Signature · 1 line
2.13.6
tip-bot for Jiri Olsa
merge bot[tip:perf/urgent] perf tools: Check wether the eBPF file exists in event parsing
perf tools: Check wether the eBPF file exists in event parsing
Commit-ID: 29479bfe83bafb8aa37f36ca132ee8349d11da0c Gitweb: https://git.kernel.org/tip/29479bfe83bafb8aa37f36ca132ee8349d11da0c Author: Jiri Olsa <[email protected]> AuthorDate: Fri, 13 Oct 2017 10:37:35 +0200 Committer: Arnaldo Carvalho de Melo <[email protected]> CommitDate: Fri, 13 Oct 2017 16:45:04 -0300
perf tools: Check wether the eBPF file exists in event parsing
Adding the check wether the eBPF file exists, to consider it as eBPF input file. This way we can differentiate eBPF events from events that end up with same suffix as eBPF file.
Before:
$ perf stat -e 'cpu/uops_executed.core/' true
bpf: builtin compilation failed: -95, try external compiler
WARNING: unable to get correct kernel building directory.
Hint: Set correct kbuild directory using 'kbuild-dir' option in [llvm]
section of ~/.perfconfig or set it to "" to suppress kbuild
detection. event syntax error: 'cpu/uops_executed.core/'
\___ Failed to load cpu/uops_executed.c from source: 'version' section incorrect or lost
After:
$ perf stat -e 'cpu/uops_executed.core/' true
Performance counter stats for 'true':
181,533 cpu/uops_executed.core/:u
0.002795447 seconds time elapsedIf user makes type in the eBPF file, we prioritize the event syntax and show following warning:
$ perf stat -e 'krava.c//' true
event syntax error: 'krava.c//'
\___ Cannot find PMU `krava.c'. Missing kernel support?--- tools/perf/util/parse-events.l | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-)
tools/perf/util/parse-events.l +15 -2
@@ -8,6 +8,9 @@ %{ #include <errno.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> #include "../perf.h" #include "parse-events.h" #include "parse-events-bison.h"
@@ -53,9 +56,8 @@ static int str(yyscan_t scanner, int token) return token; } -static bool isbpf(yyscan_t scanner) +static bool isbpf_suffix(char *text) { - char *text = parse_events_get_text(scanner); int len = strlen(text); if (len < 2)
@@ -68,6 +70,17 @@ static bool isbpf(yyscan_t scanner) return false; } +static bool isbpf(yyscan_t scanner) +{ + char *text = parse_events_get_text(scanner); + struct stat st; + + if (!isbpf_suffix(text)) + return false; + + return stat(text, &st) == 0; +} + /* * This function is called when the parser gets two kind of input: *
Jiri Olsa
reviewerPATCH 9/9 perf tools: Unwind properly location after REJECT
In reply to Jiri OlsaWe have defined YY_USER_ACTION to keep trace of the column location during events parsing, but we need to clean it up when we call REJECT.
When REJECT is called, the lexer shrinks the text and re-runs the matching, so we need to address it in resuming the previous location value.
--- tools/perf/util/parse-events.l | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
tools/perf/util/parse-events.l +6 -2
@@ -154,6 +154,10 @@ do { \ yycolumn += yyleng; \ } while (0); +#define USER_REJECT \ + yycolumn -= yyleng; \ + REJECT + %} %x mem
@@ -336,8 +340,8 @@ r{num_raw_hex} { return raw(yyscanner); } {num_hex} { return value(yyscanner, 16); } {modifier_event} { return str(yyscanner, PE_MODIFIER_EVENT); } -{bpf_object} { if (!isbpf(yyscanner)) REJECT; return str(yyscanner, PE_BPF_OBJECT); } -{bpf_source} { if (!isbpf(yyscanner)) REJECT; return str(yyscanner, PE_BPF_SOURCE); } +{bpf_object} { if (!isbpf(yyscanner)) USER_REJECT; return str(yyscanner, PE_BPF_OBJECT); } +{bpf_source} { if (!isbpf(yyscanner)) USER_REJECT; return str(yyscanner, PE_BPF_SOURCE); } {name} { return pmu_str_check(yyscanner); } "/" { BEGIN(config); return '/'; } - { return '-'; }
Signature · 1 line
2.13.6
Arnaldo Carvalho de Melo
maintainerRe: [PATCH 9/9] perf tools: Unwind properly location after REJECT
Em Fri, Oct 13, 2017 at 10:37:36AM +0200, Jiri Olsa escreveu:
Quoted 7 lines
We have defined
YY_USER_ACTIONto keep trace of the column location during events parsing, but we need to clean it up when we call REJECT.When REJECT is called, the lexer shrinks the text and re-runs the matching, so we need to address it in resuming the previous location value.
What is this fixing? Please state that, below I show what it is breaking :-/
Before:
[root@jouet ~]# perf trace --no-syscalls -e ~acme/bpf/sys_read.c/max-stack=5/ sleep 1
bpf: builtin compilation failed: -95, try external compiler
0.000 perf_bpf_probe:func:(ffffffffbb2634e0))
sys_read ([kernel.kallsyms])
entry_SYSCALL_64_fastpath ([kernel.kallsyms])
__read (/usr/lib64/ld-2.25.so)
_dl_map_object (/usr/lib64/ld-2.25.so)After:
[root@jouet ~]# perf trace --no-syscalls -e ~acme/bpf/sys_read.c/max-stack=5/ sleep 1 event syntax error: '/home/acme/bpf/sys_read.c/max-stack=5/'
\___ parser error
Run 'perf list' for a list of valid events
Usage: perf trace [<options>] [<command>]
or: perf trace [<options>] -- <command> [<options>]
or: perf trace record [<options>] [<command>]
or: perf trace record [<options>] -- <command> [<options>]
-e, --event <event> event/syscall selector. use 'perf list' to list available events
[root@jouet ~]#
PATCH v2 9/9 perf tools: Unwind properly location after REJECT
Quoted 29 lines · Arnaldo Carvalho de Melo
Em Fri, Oct 13, 2017 at 10:37:36AM +0200, Jiri Olsa escreveu:
Quoted 7 lines
We have defined
YY_USER_ACTIONto keep trace of the column location during events parsing, but we need to clean it up when we call REJECT.When REJECT is called, the lexer shrinks the text and re-runs the matching, so we need to address it in resuming the previous location value.
What is this fixing? Please state that, below I show what it is breaking :-/
Before:
[root@jouet ~]# perf trace --no-syscalls -e ~acme/bpf/sys_read.c/max-stack=5/ sleep 1
bpf: builtin compilation failed: -95, try external compiler0.000 perf_bpf_probe:func:(ffffffffbb2634e0)) sys_read ([kernel.kallsyms]) entry_SYSCALL_64_fastpath ([kernel.kallsyms]) __read (/usr/lib64/ld-2.25.so) _dl_map_object (/usr/lib64/ld-2.25.so)After:
[root@jouet ~]# perf trace --no-syscalls -e ~acme/bpf/sys_read.c/max-stack=5/ sleep 1 event syntax error: '/home/acme/bpf/sys_read.c/max-stack=5/'
\___ parser error
Run 'perf list' for a list of valid events
Quoted 8 lines
Usage: perf trace [<options>] [<command>]
or: perf trace [<options>] -- <command> [<options>]
or: perf trace record [<options>] [<command>]
or: perf trace record [<options>] -- <command> [<options>]-e, --event <event> event/syscall selector. use 'perf list' to list available events
[root@jouet ~]#
v2 with updated changelog attached,
also I rebased the rest of the fixes and pushed
them into perf/fixes branch
thanks,
jirka
---
We have defined YY_USER_ACTION to keep trace of the column location during events parsing, but we need to clean it up when we call REJECT.
When REJECT is called, the lexer shrinks the text and re-runs the matching, so we need to address it in resuming the previous location value to keep it correct for error display, like:
Before:
$ perf stat -e 'cpu/uops_executed.core,krava/' true
event syntax error: '..38;5;9:mi=01;05;37;41:su=48;5;196;38;5;15:sg=48;5;1\
1;38;5;16:ca=48;5;196;38;5;226:tw=48;5;10;38;5;16:ow=48;5;10;38;5;21:st=48;5;\
21;38;50
�'
\___ unknown termAfter:
$ ./perf stat -e 'cpu/uops_executed.core,krava/' true
event syntax error: '..cuted.core,krava/'
\___ unknown term--- tools/perf/util/parse-events.l | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
tools/perf/util/parse-events.l +6 -2
@@ -154,6 +154,10 @@ do { \ yycolumn += yyleng; \ } while (0); +#define USER_REJECT \ + yycolumn -= yyleng; \ + REJECT + %} %x mem
@@ -336,8 +340,8 @@ r{num_raw_hex} { return raw(yyscanner); } {num_hex} { return value(yyscanner, 16); } {modifier_event} { return str(yyscanner, PE_MODIFIER_EVENT); } -{bpf_object} { if (!isbpf(yyscanner)) REJECT; return str(yyscanner, PE_BPF_OBJECT); } -{bpf_source} { if (!isbpf(yyscanner)) REJECT; return str(yyscanner, PE_BPF_SOURCE); } +{bpf_object} { if (!isbpf(yyscanner)) USER_REJECT; return str(yyscanner, PE_BPF_OBJECT); } +{bpf_source} { if (!isbpf(yyscanner)) USER_REJECT; return str(yyscanner, PE_BPF_SOURCE); } {name} { return pmu_str_check(yyscanner); } "/" { BEGIN(config); return '/'; } - { return '-'; }
Signature · 1 line
2.13.6
Re: [PATCHv2 9/9] perf tools: Unwind properly location after REJECT
Quoted 35 lines · Jiri Olsa
Quoted 34 lines · Arnaldo Carvalho de Melo
Em Fri, Oct 13, 2017 at 10:37:36AM +0200, Jiri Olsa escreveu:
Quoted 7 lines
We have defined
YY_USER_ACTIONto keep trace of the column location during events parsing, but we need to clean it up when we call REJECT.When REJECT is called, the lexer shrinks the text and re-runs the matching, so we need to address it in resuming the previous location value.
What is this fixing? Please state that, below I show what it is breaking :-/
Before:
[root@jouet ~]# perf trace --no-syscalls -e ~acme/bpf/sys_read.c/max-stack=5/ sleep 1
bpf: builtin compilation failed: -95, try external compiler0.000 perf_bpf_probe:func:(ffffffffbb2634e0)) sys_read ([kernel.kallsyms]) entry_SYSCALL_64_fastpath ([kernel.kallsyms]) __read (/usr/lib64/ld-2.25.so) _dl_map_object (/usr/lib64/ld-2.25.so)After:
[root@jouet ~]# perf trace --no-syscalls -e ~acme/bpf/sys_read.c/max-stack=5/ sleep 1 event syntax error: '/home/acme/bpf/sys_read.c/max-stack=5/'
\___ parser error
Run 'perf list' for a list of valid eventsUsage: perf trace [<options>] [<command>]
or: perf trace [<options>] -- <command> [<options>]
or: perf trace record [<options>] [<command>]
or: perf trace record [<options>] -- <command> [<options>]
Quoted 8 lines
Quoted 3 lines
-e, --event <event> event/syscall selector. use 'perf list' to list available events
[root@jouet ~]#v2 with updated changelog attached,
also I rebased the rest of the fixes and pushed
them into perf/fixes branch
and I just rebased/pushed that once again.. we are too fast ;-)
thanks,
jirka