perf updates
Subsystems (3)
Linus,
Please pull the latest perf-urgent-for-linus git tree from:
git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git perf-urgent-for-linus
# HEAD: f282f7a0ecc3e0b8fd8532a6c3e9401534cb907c Merge tag 'perf-core-for-mingo-20160803' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/urgent
Mostly tooling fixes and some late tooling updates, plus two perf related printk message fixes.
Thanks,
Ingo
------------------>
Arnaldo Carvalho de Melo (7):
perf evsel: Introduce constructor for cycles event
perf annotate: Use pipe + fork instead of popen
perf target: str_error_r() always returns the buffer it receives perf annotate: Rename symbol__annotate() to symbol__disassemble() perf annotate: Introduce strerror for handling symbol__disassemble() errors perf annotate: Plug filename string leak
perf tests bpf: Use SyS_epoll_wait alias
David Ahern (1):
perf/core: Change log level for duration warning to KERN_INFO
Jan Stancek (1):
perf tests: objdump output can contain multi byte chunks
Jiri Olsa (7):
tools lib: Add bitmap_alloc function
tools lib: Add bitmap_scnprintf function tools lib: Add bitmap_and function
perf tests: Add test for bitmap_scnprintf function perf tools: Move config/Makefile into Makefile.config perf hists: Introduce output_resort_cb method perf record: Add --sample-cpu option
Juergen Gross (1):
perf/x86: Modify error message in virtualized environment
Namhyung Kim (2):
perf tools: Fix build failure on perl script context tools lib traceevent: Ignore generated library files
arch/x86/events/core.c | 11 ++-
kernel/events/core.c | 2 +-
tools/include/linux/bitmap.h | 37 ++++++++
tools/lib/bitmap.c | 44 +++++++++
tools/lib/traceevent/.gitignore | 1 +
tools/perf/Documentation/perf-record.txt | 3 +
tools/perf/{config/Makefile => Makefile.config} | 0
tools/perf/Makefile.perf | 6 +-
tools/perf/builtin-record.c | 1 +
tools/perf/builtin-top.c | 6 +-
tools/perf/perf.h | 1 +
tools/perf/scripts/perl/Perf-Trace-Util/Build | 4 +-
tools/perf/tests/Build | 1 +
tools/perf/tests/bitmap.c | 53 +++++++++++
tools/perf/tests/bpf-script-example.c | 4 +-
tools/perf/tests/builtin-test.c | 4 +
tools/perf/tests/code-reading.c | 100 ++++++++++++++------
tools/perf/tests/tests.h | 1 +
tools/perf/ui/browsers/annotate.c | 9 +-
tools/perf/ui/gtk/annotate.c | 8 +-
tools/perf/util/annotate.c | 116 +++++++++++++++++-------
tools/perf/util/annotate.h | 22 ++++-
tools/perf/util/evlist.c | 22 +----
tools/perf/util/evsel.c | 30 +++++-
tools/perf/util/evsel.h | 2 +
tools/perf/util/hist.c | 15 ++-
tools/perf/util/hist.h | 4 +
tools/perf/util/target.c | 6 +-
28 files changed, 402 insertions(+), 111 deletions(-)
rename tools/perf/{config/Makefile => Makefile.config} (100%)
create mode 100644 tools/perf/tests/bitmap.carch/x86/events/core.c +7 -4
@@ -262,10 +262,13 @@ static bool check_hw_exists(void)return true; msr_fail: -pr_cont ("Broken PMU hardware detected, using software events only.\n" ); -printk ("%sFailed to access perfctr msr (MSR %x is %Lx)\n" , -boot_cpu_has (X86_FEATURE_HYPERVISOR ) ?KERN_INFO :KERN_ERR , - reg, val_new); +if (boot_cpu_has (X86_FEATURE_HYPERVISOR )) { +pr_cont ("PMU not available due to virtualization, using software events only.\n" ); + }else { +pr_cont ("Broken PMU hardware detected, using software events only.\n" ); +pr_err ("Failed to access perfctr msr (MSR %x is %Lx)\n" , + reg, val_new); + }return false; }
kernel/events/core.c +1 -1
@@ -448,7 +448,7 @@ static u64 __report_allowed;static void perf_duration_warn (struct irq_work *w) { - printk_ratelimited(KERN_WARNING + printk_ratelimited(KERN_INFO "perf: interrupt took too long (%lld > %lld), lowering " "kernel.perf_event_max_sample_rate to %d\n", __report_avg, __report_allowed,
tools/include/linux/bitmap.h +37 -0
@@ -3,6 +3,7 @@#include <string.h> #include <linux/bitops.h> +#include <stdlib.h> #define DECLARE_BITMAP (name,bits) \ unsigned long name[BITS_TO_LONGS(bits)]
@@ -10,6 +11,8 @@int __bitmap_weight (const unsigned long *bitmap,int bits);void __bitmap_or (unsigned long *dst,const unsigned long *bitmap1,const unsigned long *bitmap2,int bits); +int __bitmap_and (unsigned long *dst,const unsigned long *bitmap1, +const unsigned long *bitmap2,unsigned int bits);#define BITMAP_FIRST_WORD_MASK (start) (~0UL << ((start) & (BITS_PER_LONG - 1)))
@@ -65,4 +68,38 @@ static inline int test_and_set_bit(int nr, unsigned long *addr) return (old & mask) != 0; } +/** +* bitmap_alloc - Allocate bitmap +* @nr: Bit to set +*/ +static inline unsigned long *bitmap_alloc (int nbits) +{ +return calloc (1 ,BITS_TO_LONGS (nbits) *sizeof (unsigned long )); +} + +/* +* bitmap_scnprintf - print bitmap list into buffer +* @bitmap: bitmap +* @nbits: size of bitmap +* @buf: buffer to store output +* @size: size of @buf +*/ +size_t bitmap_scnprintf (unsigned long *bitmap,int nbits, +char *buf,size_t size); + +/** +* bitmap_and - Do logical and on bitmaps +* @dst: resulting bitmap +* @src1: operand 1 +* @src2: operand 2 +* @nbits: size of bitmap +*/ +static inline int bitmap_and (unsigned long *dst,const unsigned long *src1, +const unsigned long *src2,unsigned int nbits) +{ +if (small_const_nbits (nbits)) +return (*dst = *src1 & *src2 &BITMAP_LAST_WORD_MASK (nbits)) !=0 ; +return __bitmap_and (dst, src1, src2, nbits); +} +#endif /* _PERF_BITOPS_H */
tools/lib/bitmap.c +44 -0
47 lines not on this page · raw message
tools/lib/traceevent/.gitignore +1 -0
@@ -1,2 +1,3 @@ TRACEEVENT-CFLAGS libtraceevent-dynamic-list +libtraceevent.so.*
tools/perf/Documentation/perf-record.txt +3 -0
@@ -192,6 +192,9 @@ OPTIONS --period:: Record the sample period. +--sample-cpu:: + Record the sample cpu. + -n:: --no-samples:: Don't sample.
tools/perf/Makefile.config renamed from tools/perf/config/Makefile +0 -0
tools/perf/Makefile.perf +3 -3
@@ -161,7 +161,7 @@ TRACE_EVENT_DIR = $(srctree)/tools/lib/traceevent/ BPF_DIR = $(srctree)/tools/lib/bpf/ SUBCMD_DIR = $(srctree)/tools/lib/subcmd/ -# include config/Makefile by default and rule out +# include Makefile.config by default and rule out # non-config cases config := 1
@@ -183,7 +183,7 @@ ifeq ($(filter feature-dump,$(MAKECMDGOALS)),feature-dump) FEATURE_TESTS := all endif endif -include config/Makefile +include Makefile.config endif ifeq ($(config),0)
@@ -706,7 +706,7 @@ install: install-bin try-install-man install-traceevent-plugins ### Cleaning rules # -# This is here, not in config/Makefile, because config/Makefile does +# This is here, not in Makefile.config, because Makefile.config does # not get included for the clean target: # config-clean:
tools/perf/builtin-record.c +1 -0
@@ -1434,6 +1434,7 @@ struct option __record_options[] = {OPT_BOOLEAN ('s' ,"stat" , &record.opts.inherit_stat,"per thread counts" ),OPT_BOOLEAN ('d' ,"data" , &record.opts.sample_address,"Record the sample addresses" ), +OPT_BOOLEAN (0 ,"sample-cpu" , &record.opts.sample_cpu,"Record the sample cpu" ),OPT_BOOLEAN_SET ('T' ,"timestamp" , &record.opts.sample_time, &record.opts.sample_time_set, "Record the sample timestamps"),
tools/perf/builtin-top.c +5 -1
@@ -128,10 +128,14 @@ static int perf_top__parse_source(struct perf_top *top, struct hist_entry *he)return err; } - err =symbol__annotate (sym, map,0 ); + err =symbol__disassemble (sym, map,0 );if (err ==0 ) { out_assign: top->sym_filter_entry = he; + }else { +char msg[BUFSIZ ]; +symbol__strerror_disassemble (sym, map, err, msg,sizeof (msg)); +pr_err ("Couldn't annotate %s: %s\n" , sym->name, msg); }pthread_mutex_unlock (¬es->lock);
tools/perf/perf.h +1 -0
@@ -52,6 +52,7 @@ struct record_opts {bool sample_weight;bool sample_time;bool sample_time_set; +bool sample_cpu;bool period;bool running_time;bool full_auxtrace;
tools/perf/scripts/perl/Perf-Trace-Util/Build +3 -1
@@ -1,3 +1,5 @@ libperf-y += Context.o -CFLAGS_Context.o += $(PERL_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-nested-externs -Wno-undef -Wno-switch-default +CFLAGS_Context.o += $(PERL_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes +CFLAGS_Context.o += -Wno-unused-parameter -Wno-nested-externs -Wno-undef +CFLAGS_Context.o += -Wno-switch-default -Wno-shadow
tools/perf/tests/Build +1 -0
@@ -41,6 +41,7 @@ perf-y += event-times.o perf-y += backward-ring-buffer.o perf-y += sdt.o perf-y += is_printable_array.o +perf-y += bitmap.o $(OUTPUT)tests/llvm-src-base.c: tests/bpf-script-example.c tests/Build $(call rule_mkdir)
tools/perf/tests/bitmap.c new file +53 -0
53 lines not on this page · raw message
tools/perf/tests/bpf-script-example.c +2 -2
@@ -31,8 +31,8 @@ struct bpf_map_def SEC("maps") flip_table = { .max_entries = 1, }; -SEC("func=sys_epoll_wait") -int bpf_func__sys_epoll_wait (void *ctx) +SEC("func=SyS_epoll_wait") +int bpf_func__SyS_epoll_wait (void *ctx) {int ind =0 ;int *flag =bpf_map_lookup_elem (&flip_table, &ind);
tools/perf/tests/builtin-test.c +4 -0
@@ -226,6 +226,10 @@ static struct test generic_tests[] = { .func = test__is_printable_array, }, { + .desc = "Test bitmap print", + .func = test__bitmap_print, + }, + { .func = NULL, }, };
tools/perf/tests/code-reading.c +71 -29
129 lines not on this page · raw message
tools/perf/tests/tests.h +1 -0
@@ -90,6 +90,7 @@ int test__backward_ring_buffer(int subtest);int test__cpu_map_print (int subtest);int test__sdt_event (int subtest);int test__is_printable_array (int subtest); +int test__bitmap_print (int subtest);#if defined(__arm__) || defined(__aarch64__)#ifdef HAVE_DWARF_UNWIND_SUPPORT
tools/perf/ui/browsers/annotate.c +6 -3
@@ -1026,7 +1026,7 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map, .use_navkeypressed = true, }, }; -int ret =-1 ; +int ret =-1 , err;int nr_pcnt =1 ;size_t sizeof_bdl =sizeof (struct browser_disasm_line );
@@ -1050,8 +1050,11 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map, (nr_pcnt -1 ); } -if (symbol__annotate (sym, map, sizeof_bdl) <0 ) { -ui__error ("%s" , ui_helpline__last_msg); + err =symbol__disassemble (sym, map, sizeof_bdl); +if (err) { +char msg[BUFSIZ ]; +symbol__strerror_disassemble (sym, map, err, msg,sizeof (msg)); +ui__error ("Couldn't annotate %s:\n%s" , sym->name, msg); goto out_free_offsets; }
tools/perf/ui/gtk/annotate.c +6 -2
@@ -162,12 +162,16 @@ static int symbol__gtk_annotate(struct symbol *sym, struct map *map,GtkWidget *notebook;GtkWidget *scrolled_window;GtkWidget *tab_label; +int err;if (map->dso->annotate_warned)return -1 ; -if (symbol__annotate (sym, map,0 ) <0 ) { -ui__error ("%s" , ui_helpline__current); + err =symbol__disassemble (sym, map,0 ); +if (err) { +char msg[BUFSIZ ]; +symbol__strerror_disassemble (sym, map, err, msg,sizeof (msg)); +ui__error ("Couldn't annotate %s: %s\n" , sym->name, msg);return -1 ; }
tools/perf/util/annotate.c +81 -35
168 lines not on this page · raw message
tools/perf/util/annotate.h +21 -1
@@ -155,7 +155,27 @@ int hist_entry__inc_addr_samples(struct hist_entry *he, int evidx, u64 addr);int symbol__alloc_hist (struct symbol *sym);void symbol__annotate_zero_histograms (struct symbol *sym); -int symbol__annotate (struct symbol *sym,struct map *map,size_t privsize); +int symbol__disassemble (struct symbol *sym,struct map *map,size_t privsize); + +enum symbol_disassemble_errno { +SYMBOL_ANNOTATE_ERRNO__SUCCESS =0 , + +/* +* Choose an arbitrary negative big number not to clash with standard +* errno since SUS requires the errno has distinct positive values. +* See 'Issue 6' in the link below. +* +* http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/errno.h.html +*/ + __SYMBOL_ANNOTATE_ERRNO__START =-10000 , + +SYMBOL_ANNOTATE_ERRNO__NO_VMLINUX = __SYMBOL_ANNOTATE_ERRNO__START, + + __SYMBOL_ANNOTATE_ERRNO__END, +}; + +int symbol__strerror_disassemble (struct symbol *sym,struct map *map, +int errnum,char *buf,size_t buflen);int symbol__annotate_init (struct map *map,struct symbol *sym); int symbol__annotate_printf(struct symbol *sym, struct map *map,
tools/perf/util/evlist.c +2 -20
@@ -239,31 +239,13 @@ void perf_event_attr__set_max_precise_ip(struct perf_event_attr *attr)int perf_evlist__add_default (struct perf_evlist *evlist) { -struct perf_event_attr attr = { - .type =PERF_TYPE_HARDWARE , - .config =PERF_COUNT_HW_CPU_CYCLES , - }; -struct perf_evsel *evsel; - -event_attr_init (&attr); +struct perf_evsel *evsel =perf_evsel__new_cycles (); -perf_event_attr__set_max_precise_ip (&attr); - - evsel =perf_evsel__new (&attr);if (evsel ==NULL ) - goto error; - -/* use asprintf() because free(evsel) assumes name is allocated */ -if (asprintf (&evsel->name,"cycles%.*s" , - attr.precise_ip ? attr.precise_ip +1 :0 ,":ppp" ) <0 ) - goto error_free; +return -ENOMEM ;perf_evlist__add (evlist, evsel);return 0 ; -error_free: -perf_evsel__delete (evsel); -error: -return -ENOMEM ; }int perf_evlist__add_dummy (struct perf_evlist *evlist)
tools/perf/util/evsel.c +29 -1
@@ -253,6 +253,34 @@ struct perf_evsel *perf_evsel__new_idx(struct perf_event_attr *attr, int idx)return evsel; } +struct perf_evsel *perf_evsel__new_cycles (void ) +{ +struct perf_event_attr attr = { + .type =PERF_TYPE_HARDWARE , + .config =PERF_COUNT_HW_CPU_CYCLES , + }; +struct perf_evsel *evsel; + +event_attr_init (&attr); + +perf_event_attr__set_max_precise_ip (&attr); + + evsel =perf_evsel__new (&attr); +if (evsel ==NULL ) + goto out; + +/* use asprintf() because free(evsel) assumes name is allocated */ +if (asprintf (&evsel->name,"cycles%.*s" , + attr.precise_ip ? attr.precise_ip +1 :0 ,":ppp" ) <0 ) + goto error_free; +out: +return evsel; +error_free: +perf_evsel__delete (evsel); + evsel =NULL ; + goto out; +} +/* * Returns pointer with encoded error via <linux/err.h> interface. */
@@ -854,7 +882,7 @@ void perf_evsel__config(struct perf_evsel *evsel, struct record_opts *opts,perf_evsel__set_sample_bit (evsel,REGS_INTR ); } -if (target__has_cpu (&opts->target)) +if (target__has_cpu (&opts->target) || opts->sample_cpu)perf_evsel__set_sample_bit (evsel,CPU );if (opts->period)
tools/perf/util/evsel.h +2 -0
@@ -175,6 +175,8 @@ static inline struct perf_evsel *perf_evsel__newtp(const char *sys, const char *return perf_evsel__newtp_idx (sys, name,0 ); } +struct perf_evsel *perf_evsel__new_cycles (void ); +struct event_format *event_format__new (const char *sys,const char *name); void perf_evsel__init(struct perf_evsel *evsel,
tools/perf/util/hist.c +12 -3
@@ -1672,7 +1672,7 @@ static void __hists__insert_output_entry(struct rb_root *entries, }static void output_resort (struct hists *hists,struct ui_progress *prog, -bool use_callchain) +bool use_callchain,hists__resort_cb_t cb) {struct rb_root *root;struct rb_node *next;
@@ -1711,6 +1711,9 @@ static void output_resort(struct hists *hists, struct ui_progress *prog, n = rb_entry(next, struct hist_entry, rb_node_in); next =rb_next (&n->rb_node_in); +if (cb &&cb (n)) +continue ; +__hists__insert_output_entry (&hists->entries, n, min_callchain_hits, use_callchain);hists__inc_stats (hists, n);
@@ -1731,12 +1734,18 @@ void perf_evsel__output_resort(struct perf_evsel *evsel, struct ui_progress *proelse use_callchain = symbol_conf.use_callchain; -output_resort (evsel__hists (evsel), prog, use_callchain); +output_resort (evsel__hists (evsel), prog, use_callchain,NULL ); }void hists__output_resort (struct hists *hists,struct ui_progress *prog) { -output_resort (hists, prog, symbol_conf.use_callchain); +output_resort (hists, prog, symbol_conf.use_callchain,NULL ); +} + +void hists__output_resort_cb (struct hists *hists,struct ui_progress *prog, +hists__resort_cb_t cb) +{ +output_resort (hists, prog, symbol_conf.use_callchain, cb); }static bool can_goto_child (struct hist_entry *he,enum hierarchy_move_dir hmd)
tools/perf/util/hist.h +4 -0
@@ -153,8 +153,12 @@ int hist_entry__snprintf_alignment(struct hist_entry *he, struct perf_hpp *hpp, struct perf_hpp_fmt *fmt, int printed);void hist_entry__delete (struct hist_entry *he); +typedef int (*hists__resort_cb_t )(struct hist_entry *he); +void perf_evsel__output_resort (struct perf_evsel *evsel,struct ui_progress *prog);void hists__output_resort (struct hists *hists,struct ui_progress *prog); +void hists__output_resort_cb (struct hists *hists,struct ui_progress *prog, +hists__resort_cb_t cb);int hists__collapse_resort (struct hists *hists,struct ui_progress *prog);void hists__decay_entries (struct hists *hists,bool zap_user,bool zap_kernel);
tools/perf/util/target.c +1 -5
@@ -122,11 +122,7 @@ int target__strerror(struct target *target, int errnum,BUG_ON (buflen ==0 );if (errnum >=0 ) { -const char *err =str_error_r (errnum, buf, buflen); - -if (err != buf) -scnprintf (buf, buflen,"%s" , err); - +str_error_r (errnum, buf, buflen);return 0 ; }