Skip to contentSkip to conversation

perf/core improvements and fixes

GIT PULL In review Arnaldo Carvalho de Melo 6 participants 25 messages Sep 29, 2011 – Jun 20, 2012

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

Hi Ingo,

Please consider pulling from:

git://github.com/acmel/linux.git perf/core

This was rebased against your perf/core on tesla.

Regards,

- Arnaldo

Andi Kleen (2):
perf tools: Make stat/record print fatal signals of the target program
perf: Support setting the disassembler style

Arnaldo Carvalho de Melo (6):
perf symbols: Stop using 'self' in map_groups__ methods perf buildid-list: Add option to show the running kernel build id perf buildid-list: Support showing the build id in an ELF file perf top browser: Fix up line width calculation
perf top: Improve lost events warning
perf report: Fix stdio event name header printing

Jim Cromie (5):
perf stat: Add --log-fd <N> option to redirect stderr elsewhere perf stat: Fix +- nan% in --no-aggr runs
perf stat: Suppress printing std-dev when its 0
perf stat: Allow tab as cvs delimiter
perf stat: Fix spelling in comment

Jiri Olsa (2):
perf sched: Fix script command documentation
perf symbols: Treat all memory maps without dso file as loaded

Neil Horman (1):
perf script: Add drop monitor script

 tools/perf/Documentation/perf-annotate.txt         |    3 +
 tools/perf/Documentation/perf-buildid-list.txt     |    6 +
 tools/perf/Documentation/perf-report.txt           |    3 +
 tools/perf/Documentation/perf-sched.txt            |    6 +-
 tools/perf/Documentation/perf-stat.txt             |   11 ++-
 tools/perf/builtin-annotate.c                      |    2 +
 tools/perf/builtin-buildid-list.c                  |   52 ++++++++++-
 tools/perf/builtin-record.c                        |   19 ++++-
 tools/perf/builtin-report.c                        |    7 +-
 tools/perf/builtin-stat.c                          |   35 ++++++-
 tools/perf/builtin-top.c                           |   34 ++++----
 .../perf/scripts/python/bin/net_dropmonitor-record |    2 +
 .../perf/scripts/python/bin/net_dropmonitor-report |    4 +
 tools/perf/scripts/python/net_dropmonitor.py       |   72 ++++++++++++++
 tools/perf/util/annotate.c                         |    6 +-
 tools/perf/util/annotate.h                         |    2 +
 tools/perf/util/map.c                              |   98 +++++++++++---------
 tools/perf/util/map.h                              |   42 ++++----
 tools/perf/util/top.h                              |    3 +
 tools/perf/util/ui/browsers/top.c                  |   28 +++++-
 20 files changed, 333 insertions(+), 102 deletions(-)
 create mode 100755 tools/perf/scripts/python/bin/net_dropmonitor-record
 create mode 100755 tools/perf/scripts/python/bin/net_dropmonitor-report
 create mode 100755 tools/perf/scripts/python/net_dropmonitor.py
#1 lore raw

PATCH 1/16 perf symbols: Stop using 'self' in map_groups__ methods

From: Arnaldo Carvalho de Melo <[email protected]>

Stop using this python/OOP convention, doesn't really helps. Will do more from time to time till we get it cleaned up in all of /perf.

---
 tools/perf/util/map.c |   74 ++++++++++++++++++++++++------------------------
 tools/perf/util/map.h |   42 ++++++++++++++--------------
 2 files changed, 58 insertions(+), 58 deletions(-)
tools/perf/util/map.c +37 -37
index a16ecab..aa2f9fd 100644
@@ -220,55 +220,55 @@ u64 map__objdump_2ip(struct map *map, u64 addr)
 	return ip;
 }
 
-void map_groups__init(struct map_groups *self)
+void map_groups__init(struct map_groups *mg)
 {
 	int i;
 	for (i = 0; i < MAP__NR_TYPES; ++i) {
-		self->maps[i] = RB_ROOT;
-		INIT_LIST_HEAD(&self->removed_maps[i]);
+		mg->maps[i] = RB_ROOT;
+		INIT_LIST_HEAD(&mg->removed_maps[i]);
 	}
-	self->machine = NULL;
+	mg->machine = NULL;
 }
 
-static void maps__delete(struct rb_root *self)
+static void maps__delete(struct rb_root *maps)
 {
-	struct rb_node *next = rb_first(self);
+	struct rb_node *next = rb_first(maps);
 
 	while (next) {
 		struct map *pos = rb_entry(next, struct map, rb_node);
 
 		next = rb_next(&pos->rb_node);
-		rb_erase(&pos->rb_node, self);
+		rb_erase(&pos->rb_node, maps);
 		map__delete(pos);
 	}
 }
 
-static void maps__delete_removed(struct list_head *self)
+static void maps__delete_removed(struct list_head *maps)
 {
 	struct map *pos, *n;
 
-	list_for_each_entry_safe(pos, n, self, node) {
+	list_for_each_entry_safe(pos, n, maps, node) {
 		list_del(&pos->node);
 		map__delete(pos);
 	}
 }
 
-void map_groups__exit(struct map_groups *self)
+void map_groups__exit(struct map_groups *mg)
 {
 	int i;
 
 	for (i = 0; i < MAP__NR_TYPES; ++i) {
-		maps__delete(&self->maps[i]);
-		maps__delete_removed(&self->removed_maps[i]);
+		maps__delete(&mg->maps[i]);
+		maps__delete_removed(&mg->removed_maps[i]);
 	}
 }
 
-void map_groups__flush(struct map_groups *self)
+void map_groups__flush(struct map_groups *mg)
 {
 	int type;
 
 	for (type = 0; type < MAP__NR_TYPES; type++) {
-		struct rb_root *root = &self->maps[type];
+		struct rb_root *root = &mg->maps[type];
 		struct rb_node *next = rb_first(root);
 
 		while (next) {
@@ -280,17 +280,17 @@ void map_groups__flush(struct map_groups *self)
 			 * instance in some hist_entry instances, so
 			 * just move them to a separate list.
 			 */
-			list_add_tail(&pos->node, &self->removed_maps[pos->type]);
+			list_add_tail(&pos->node, &mg->removed_maps[pos->type]);
 		}
 	}
 }
 
-struct symbol *map_groups__find_symbol(struct map_groups *self,
+struct symbol *map_groups__find_symbol(struct map_groups *mg,
 				       enum map_type type, u64 addr,
 				       struct map **mapp,
 				       symbol_filter_t filter)
 {
-	struct map *map = map_groups__find(self, type, addr);
+	struct map *map = map_groups__find(mg, type, addr);
 
 	if (map != NULL) {
 		if (mapp != NULL)
@@ -301,7 +301,7 @@ struct symbol *map_groups__find_symbol(struct map_groups *self,
 	return NULL;
 }
 
-struct symbol *map_groups__find_symbol_by_name(struct map_groups *self,
+struct symbol *map_groups__find_symbol_by_name(struct map_groups *mg,
 					       enum map_type type,
 					       const char *name,
 					       struct map **mapp,
@@ -309,7 +309,7 @@ struct symbol *map_groups__find_symbol_by_name(struct map_groups *self,
 {
 	struct rb_node *nd;
 
-	for (nd = rb_first(&self->maps[type]); nd; nd = rb_next(nd)) {
+	for (nd = rb_first(&mg->maps[type]); nd; nd = rb_next(nd)) {
 		struct map *pos = rb_entry(nd, struct map, rb_node);
 		struct symbol *sym = map__find_symbol_by_name(pos, name, filter);
 
@@ -323,13 +323,13 @@ struct symbol *map_groups__find_symbol_by_name(struct map_groups *self,
 	return NULL;
 }
 
-size_t __map_groups__fprintf_maps(struct map_groups *self,
+size_t __map_groups__fprintf_maps(struct map_groups *mg,
 				  enum map_type type, int verbose, FILE *fp)
 {
 	size_t printed = fprintf(fp, "%s:\n", map_type__name[type]);
 	struct rb_node *nd;
 
-	for (nd = rb_first(&self->maps[type]); nd; nd = rb_next(nd)) {
+	for (nd = rb_first(&mg->maps[type]); nd; nd = rb_next(nd)) {
 		struct map *pos = rb_entry(nd, struct map, rb_node);
 		printed += fprintf(fp, "Map:");
 		printed += map__fprintf(pos, fp);
@@ -342,22 +342,22 @@ size_t __map_groups__fprintf_maps(struct map_groups *self,
 	return printed;
 }
 
-size_t map_groups__fprintf_maps(struct map_groups *self, int verbose, FILE *fp)
+size_t map_groups__fprintf_maps(struct map_groups *mg, int verbose, FILE *fp)
 {
 	size_t printed = 0, i;
 	for (i = 0; i < MAP__NR_TYPES; ++i)
-		printed += __map_groups__fprintf_maps(self, i, verbose, fp);
+		printed += __map_groups__fprintf_maps(mg, i, verbose, fp);
 	return printed;
 }
 
-static size_t __map_groups__fprintf_removed_maps(struct map_groups *self,
+static size_t __map_groups__fprintf_removed_maps(struct map_groups *mg,
 						 enum map_type type,
 						 int verbose, FILE *fp)
 {
 	struct map *pos;
 	size_t printed = 0;
 
-	list_for_each_entry(pos, &self->removed_maps[type], node) {
+	list_for_each_entry(pos, &mg->removed_maps[type], node) {
 		printed += fprintf(fp, "Map:");
 		printed += map__fprintf(pos, fp);
 		if (verbose > 1) {
@@ -368,26 +368,26 @@ static size_t __map_groups__fprintf_removed_maps(struct map_groups *self,
 	return printed;
 }
 
-static size_t map_groups__fprintf_removed_maps(struct map_groups *self,
+static size_t map_groups__fprintf_removed_maps(struct map_groups *mg,
 					       int verbose, FILE *fp)
 {
 	size_t printed = 0, i;
 	for (i = 0; i < MAP__NR_TYPES; ++i)
-		printed += __map_groups__fprintf_removed_maps(self, i, verbose, fp);
+		printed += __map_groups__fprintf_removed_maps(mg, i, verbose, fp);
 	return printed;
 }
 
-size_t map_groups__fprintf(struct map_groups *self, int verbose, FILE *fp)
+size_t map_groups__fprintf(struct map_groups *mg, int verbose, FILE *fp)
 {
-	size_t printed = map_groups__fprintf_maps(self, verbose, fp);
+	size_t printed = map_groups__fprintf_maps(mg, verbose, fp);
 	printed += fprintf(fp, "Removed maps:\n");
-	return printed + map_groups__fprintf_removed_maps(self, verbose, fp);
+	return printed + map_groups__fprintf_removed_maps(mg, verbose, fp);
 }
 
-int map_groups__fixup_overlappings(struct map_groups *self, struct map *map,
+int map_groups__fixup_overlappings(struct map_groups *mg, struct map *map,
 				   int verbose, FILE *fp)
 {
-	struct rb_root *root = &self->maps[map->type];
+	struct rb_root *root = &mg->maps[map->type];
 	struct rb_node *next = rb_first(root);
 	int err = 0;
 
@@ -418,7 +418,7 @@ int map_groups__fixup_overlappings(struct map_groups *self, struct map *map,
 			}
 
 			before->end = map->start - 1;
-			map_groups__insert(self, before);
+			map_groups__insert(mg, before);
 			if (verbose >= 2)
 				map__fprintf(before, fp);
 		}
@@ -432,7 +432,7 @@ int map_groups__fixup_overlappings(struct map_groups *self, struct map *map,
 			}
 
 			after->start = map->end + 1;
-			map_groups__insert(self, after);
+			map_groups__insert(mg, after);
 			if (verbose >= 2)
 				map__fprintf(after, fp);
 		}
@@ -441,7 +441,7 @@ move_map:
 		 * If we have references, just move them to a separate list.
 		 */
 		if (pos->referenced)
-			list_add_tail(&pos->node, &self->removed_maps[map->type]);
+			list_add_tail(&pos->node, &mg->removed_maps[map->type]);
 		else
 			map__delete(pos);
 
@@ -455,7 +455,7 @@ move_map:
 /*
  * XXX This should not really _copy_ te maps, but refcount them.
  */
-int map_groups__clone(struct map_groups *self,
+int map_groups__clone(struct map_groups *mg,
 		      struct map_groups *parent, enum map_type type)
 {
 	struct rb_node *nd;
@@ -464,7 +464,7 @@ int map_groups__clone(struct map_groups *self,
 		struct map *new = map__clone(map);
 		if (new == NULL)
 			return -ENOMEM;
-		map_groups__insert(self, new);
+		map_groups__insert(mg, new);
 	}
 	return 0;
 }
tools/perf/util/map.h +21 -21

91 lines not on this page · raw message

Signature · 1 line
1.6.2.5
#2 lore raw

PATCH 2/16 perf script: Add drop monitor script

In reply to Arnaldo Carvalho de Melo

From: Neil Horman <[email protected]>

A while back I created the dropmonitor protocol, which allowed users to get reports of dropped frames communicated to them via a netlink socket.

While useful, several people have now asked that I integrate the ability to do drop monitoring with perf, so they don't have to run additional tools.

This patch adds a drop monitor script to the perf suite, and provides the same output that the netlink socket does.

---
 .../perf/scripts/python/bin/net_dropmonitor-record |    2 +
 .../perf/scripts/python/bin/net_dropmonitor-report |    4 +
 tools/perf/scripts/python/net_dropmonitor.py       |   72 ++++++++++++++++++++
 3 files changed, 78 insertions(+), 0 deletions(-)
 create mode 100755 tools/perf/scripts/python/bin/net_dropmonitor-record
 create mode 100755 tools/perf/scripts/python/bin/net_dropmonitor-report
 create mode 100755 tools/perf/scripts/python/net_dropmonitor.py
tools/perf/scripts/python/bin/net_dropmonitor-record new file +2 -0
new file mode 100755
index 0000000..423fb81
@@ -0,0 +1,2 @@
+#!/bin/bash
+perf record -e skb:kfree_skb $@
tools/perf/scripts/python/bin/net_dropmonitor-report new file +4 -0
new file mode 100755
index 0000000..8d698f5
@@ -0,0 +1,4 @@
+#!/bin/bash
+# description: display a table of dropped frames
+
+perf script -s "$PERF_EXEC_PATH"/scripts/python/net_dropmonitor.py $@
tools/perf/scripts/python/net_dropmonitor.py new file +72 -0

72 lines not on this page · raw message

Signature · 1 line
1.6.2.5
#3 lore raw

PATCH 3/16 perf buildid-list: Add option to show the running kernel build id

In reply to Arnaldo Carvalho de Melo

From: Arnaldo Carvalho de Melo <[email protected]>

[root@emilia ~]# perf buildid-list -k 07b0c016a2b30004e86132d0239945b1e88f5d75

Useful when diagnosing build id problems in debuginfo packages, etc.

Cc David Ahern <[email protected]>
Cc Frederic Weisbecker <[email protected]>
Cc Mike Galbraith <[email protected]>
Cc Paul Mackerras <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Stephane Eranian <[email protected]>
---
 tools/perf/Documentation/perf-buildid-list.txt |    5 ++++
 tools/perf/builtin-buildid-list.c              |   31 ++++++++++++++++++++++-
 2 files changed, 34 insertions(+), 2 deletions(-)
tools/perf/Documentation/perf-buildid-list.txt +5 -0
index 5eaac6f..770a7f3 100644
@@ -16,6 +16,8 @@ This command displays the buildids found in a perf.data file, so that other
 tools can be used to fetch packages with matching symbol tables for use by
 perf report.
 
+It can also be used to show the build id of the running kernel.
+
 OPTIONS
 -------
 -H::
@@ -27,6 +29,9 @@ OPTIONS
 -f::
 --force::
 	Don't do ownership validation.
+-k::
+--kernel::
+	Show running kernel build id.
 -v::
 --verbose::
 	Be more verbose.
tools/perf/builtin-buildid-list.c +29 -2
index 5af32ae..4102ead 100644
@@ -1,7 +1,8 @@
 /*
  * builtin-buildid-list.c
  *
- * Builtin buildid-list command: list buildids in perf.data
+ * Builtin buildid-list command: list buildids in perf.data or in the running
+ * kernel.
  *
  * Copyright (C) 2009, Red Hat Inc.
  * Copyright (C) 2009, Arnaldo Carvalho de Melo <[email protected]>
@@ -17,6 +18,7 @@
 
 static char const *input_name = "perf.data";
 static bool force;
+static bool show_kernel;
 static bool with_hits;
 
 static const char * const buildid_list_usage[] = {
@@ -29,12 +31,13 @@ static const struct option options[] = {
 	OPT_STRING('i', "input", &input_name, "file",
 		    "input file name"),
 	OPT_BOOLEAN('f', "force", &force, "don't complain, do it"),
+	OPT_BOOLEAN('k', "kernel", &show_kernel, "Show current kernel build id"),
 	OPT_INCR('v', "verbose", &verbose,
 		    "be more verbose"),
 	OPT_END()
 };
 
-static int __cmd_buildid_list(void)
+static int perf_session__list_build_ids(void)
 {
 	struct perf_session *session;
 
@@ -52,6 +55,30 @@ static int __cmd_buildid_list(void)
 	return 0;
 }
 
+static int sysfs__fprintf_build_id(FILE *fp)
+{
+	u8 kallsyms_build_id[BUILD_ID_SIZE];
+	char sbuild_id[BUILD_ID_SIZE * 2 + 1];
+
+	if (sysfs__read_build_id("/sys/kernel/notes", kallsyms_build_id,
+				 sizeof(kallsyms_build_id)) != 0)
+		return -1;
+
+	build_id__sprintf(kallsyms_build_id, sizeof(kallsyms_build_id),
+			  sbuild_id);
+	fprintf(fp, "%s\n", sbuild_id);
+	return 0;
+}
+
+static int __cmd_buildid_list(void)
+{
+
+	if (show_kernel)
+		return sysfs__fprintf_build_id(stdout);
+
+	return perf_session__list_build_ids();
+}
+
 int cmd_buildid_list(int argc, const char **argv, const char *prefix __used)
 {
 	argc = parse_options(argc, argv, options, buildid_list_usage, 0);
Signature · 1 line
1.6.2.5
#4 lore raw

PATCH 4/16 perf buildid-list: Support showing the build id in an ELF file

In reply to Arnaldo Carvalho de Melo

From: Arnaldo Carvalho de Melo <[email protected]>

Try first reading the build id, validating that it is an ELF file, etc. Cheap as libelf will bail out as soon as the magic number check fails.

Useful when investigating debuginfo packaging problems like this one:

[root@emilia ~]# perf buildid-list -i /usr/lib/debug/lib/modules/uname -r/vmlinux 77bb4ea591a602d455ace759a377c9adfff1aba3
[root@emilia ~]# perf buildid-list -k 07b0c016a2b30004e86132d0239945b1e88f5d75
[root@emilia ~]#

Cc David Ahern <[email protected]>
Cc Frederic Weisbecker <[email protected]>
Cc Mike Galbraith <[email protected]>
Cc Paul Mackerras <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Stephane Eranian <[email protected]>
---
 tools/perf/Documentation/perf-buildid-list.txt |    3 +-
 tools/perf/builtin-buildid-list.c              |   27 +++++++++++++++++++++--
 2 files changed, 26 insertions(+), 4 deletions(-)
tools/perf/Documentation/perf-buildid-list.txt +2 -1
index 770a7f3..cc22325 100644
@@ -16,7 +16,8 @@ This command displays the buildids found in a perf.data file, so that other
 tools can be used to fetch packages with matching symbol tables for use by
 perf report.
 
-It can also be used to show the build id of the running kernel.
+It can also be used to show the build id of the running kernel or in an ELF
+file using -i/--input.
 
 OPTIONS
 -------
tools/perf/builtin-buildid-list.c +24 -3
index 4102ead..cb690a6 100644
@@ -1,8 +1,8 @@
 /*
  * builtin-buildid-list.c
  *
- * Builtin buildid-list command: list buildids in perf.data or in the running
- * kernel.
+ * Builtin buildid-list command: list buildids in perf.data, in the running
+ * kernel and in ELF files.
  *
  * Copyright (C) 2009, Red Hat Inc.
  * Copyright (C) 2009, Arnaldo Carvalho de Melo <[email protected]>
@@ -16,6 +16,8 @@
 #include "util/session.h"
 #include "util/symbol.h"
 
+#include <libelf.h>
+
 static char const *input_name = "perf.data";
 static bool force;
 static bool show_kernel;
@@ -70,12 +72,31 @@ static int sysfs__fprintf_build_id(FILE *fp)
 	return 0;
 }
 
-static int __cmd_buildid_list(void)
+static int filename__fprintf_build_id(const char *name, FILE *fp)
 {
+	u8 build_id[BUILD_ID_SIZE];
+	char sbuild_id[BUILD_ID_SIZE * 2 + 1];
 
+	if (filename__read_build_id(name, build_id,
+				    sizeof(build_id)) != sizeof(build_id))
+		return 0;
+
+	build_id__sprintf(build_id, sizeof(build_id), sbuild_id);
+	return fprintf(fp, "%s\n", sbuild_id);
+}
+
+static int __cmd_buildid_list(void)
+{
 	if (show_kernel)
 		return sysfs__fprintf_build_id(stdout);
 
+	elf_version(EV_CURRENT);
+	/*
+ 	 * See if this is an ELF file first:
+ 	 */
+	if (filename__fprintf_build_id(input_name, stdout))
+		return 0;
+
 	return perf_session__list_build_ids();
 }
 
Signature · 1 line
1.6.2.5
#5 lore raw

PATCH 5/16 perf top browser: Fix up line width calculation

In reply to Arnaldo Carvalho de Melo

From: Arnaldo Carvalho de Melo <[email protected]>

Fixing an artifact where the last 3 chars of a long DSO name would remain on the screen sometimes.

Cc David Ahern <[email protected]>
Cc Frederic Weisbecker <[email protected]>
Cc Mike Galbraith <[email protected]>
Cc Paul Mackerras <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Stephane Eranian <[email protected]>
---
 tools/perf/util/ui/browsers/top.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)
tools/perf/util/ui/browsers/top.c +2 -2
index 88403cf..9d93810 100644
@@ -43,10 +43,10 @@ static void perf_top_browser__write(struct ui_browser *browser, void *entry, int
 
 	if (top->evlist->nr_entries == 1 || !top->display_weighted) {
 		slsmg_printf("%20.2f ", syme->weight);
-		width -= 24;
+		width -= 21;
 	} else {
 		slsmg_printf("%9.1f %10ld ", syme->weight, syme->snap_count);
-		width -= 23;
+		width -= 20;
 	}
 
 	slsmg_printf("%4.1f%%", pcnt);
Signature · 1 line
1.6.2.5
#6 lore raw

PATCH 6/16 perf top: Improve lost events warning

In reply to Arnaldo Carvalho de Melo

From: Arnaldo Carvalho de Melo <[email protected]>

Now it warns everytime that new events are lost.

And the TUI also warns now.

Cc David Ahern <[email protected]>
Cc Frederic Weisbecker <[email protected]>
Cc Mike Galbraith <[email protected]>
Cc Paul Mackerras <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Stephane Eranian <[email protected]>
---
 tools/perf/builtin-top.c          |   34 +++++++++++++++++-----------------
 tools/perf/util/top.h             |    3 +++
 tools/perf/util/ui/browsers/top.c |   24 ++++++++++++++++++++++++
 3 files changed, 44 insertions(+), 17 deletions(-)
tools/perf/builtin-top.c +17 -17
index a43433f..23c4f71 100644
@@ -250,7 +250,7 @@ static void __list_insert_active_sym(struct sym_entry *syme)
 	list_add(&syme->node, &top.active_symbols);
 }
 
-static void print_sym_table(struct perf_session *session)
+static void print_sym_table(void)
 {
 	char bf[160];
 	int printed = 0;
@@ -270,10 +270,11 @@ static void print_sym_table(struct perf_session *session)
 
 	printf("%-*.*s\n", win_width, win_width, graph_dotted_line);
 
-	if (session->hists.stats.total_lost != 0) {
+	if (top.total_lost_warned != top.session->hists.stats.total_lost) {
+		top.total_lost_warned = top.session->hists.stats.total_lost;
 		color_fprintf(stdout, PERF_COLOR_RED, "WARNING:");
 		printf(" LOST %" PRIu64 " events, Check IO/CPU overload\n",
-		       session->hists.stats.total_lost);
+		       top.total_lost_warned);
 	}
 
 	if (top.sym_filter_entry) {
@@ -474,7 +475,7 @@ static int key_mapped(int c)
 	return 0;
 }
 
-static void handle_keypress(struct perf_session *session, int c)
+static void handle_keypress(int c)
 {
 	if (!key_mapped(c)) {
 		struct pollfd stdin_poll = { .fd = 0, .events = POLLIN };
@@ -550,7 +551,7 @@ static void handle_keypress(struct perf_session *session, int c)
 		case 'Q':
 			printf("exiting.\n");
 			if (dump_symtab)
-				perf_session__fprintf_dsos(session, stderr);
+				perf_session__fprintf_dsos(top.session, stderr);
 			exit(0);
 		case 's':
 			prompt_symbol(&top.sym_filter_entry, "Enter details symbol");
@@ -602,7 +603,6 @@ static void *display_thread(void *arg __used)
 	struct pollfd stdin_poll = { .fd = 0, .events = POLLIN };
 	struct termios tc, save;
 	int delay_msecs, c;
-	struct perf_session *session = (struct perf_session *) arg;
 
 	tcgetattr(0, &save);
 	tc = save;
@@ -617,13 +617,13 @@ repeat:
 	getc(stdin);
 
 	do {
-		print_sym_table(session);
+		print_sym_table();
 	} while (!poll(&stdin_poll, 1, delay_msecs) == 1);
 
 	c = getc(stdin);
 	tcsetattr(0, TCSAFLUSH, &save);
 
-	handle_keypress(session, c);
+	handle_keypress(c);
 	goto repeat;
 
 	return NULL;
@@ -935,27 +935,27 @@ static int __cmd_top(void)
 	 * FIXME: perf_session__new should allow passing a O_MMAP, so that all this
 	 * mmap reading, etc is encapsulated in it. Use O_WRONLY for now.
 	 */
-	struct perf_session *session = perf_session__new(NULL, O_WRONLY, false, false, NULL);
-	if (session == NULL)
+	top.session = perf_session__new(NULL, O_WRONLY, false, false, NULL);
+	if (top.session == NULL)
 		return -ENOMEM;
 
 	if (top.target_tid != -1)
 		perf_event__synthesize_thread_map(top.evlist->threads,
-						  perf_event__process, session);
+						  perf_event__process, top.session);
 	else
-		perf_event__synthesize_threads(perf_event__process, session);
+		perf_event__synthesize_threads(perf_event__process, top.session);
 
 	start_counters(top.evlist);
-	session->evlist = top.evlist;
-	perf_session__update_sample_type(session);
+	top.session->evlist = top.evlist;
+	perf_session__update_sample_type(top.session);
 
 	/* Wait for a minimal set of events before starting the snapshot */
 	poll(top.evlist->pollfd, top.evlist->nr_fds, 100);
 
-	perf_session__mmap_read(session);
+	perf_session__mmap_read(top.session);
 
 	if (pthread_create(&thread, NULL, (use_browser > 0 ? display_thread_tui :
-							     display_thread), session)) {
+							     display_thread), NULL)) {
 		printf("Could not create display thread.\n");
 		exit(-1);
 	}
@@ -973,7 +973,7 @@ static int __cmd_top(void)
 	while (1) {
 		u64 hits = top.samples;
 
-		perf_session__mmap_read(session);
+		perf_session__mmap_read(top.session);
 
 		if (hits == top.samples)
 			ret = poll(top.evlist->pollfd, top.evlist->nr_fds, 100);
tools/perf/util/top.h +3 -0
index bfbf95b..b07b041 100644
@@ -10,6 +10,7 @@
 
 struct perf_evlist;
 struct perf_evsel;
+struct perf_session;
 
 struct sym_entry {
 	struct rb_node		rb_node;
@@ -38,6 +39,7 @@ struct perf_top {
 	u64		   kernel_samples, us_samples;
 	u64		   exact_samples;
 	u64		   guest_us_samples, guest_kernel_samples;
+	u64		   total_lost_warned;
 	int		   print_entries, count_filter, delay_secs;
 	int		   display_weighted, freq, rb_entries;
 	pid_t		   target_pid, target_tid;
@@ -45,6 +47,7 @@ struct perf_top {
 	const char	   *cpu_list;
 	struct sym_entry   *sym_filter_entry;
 	struct perf_evsel  *sym_evsel;
+	struct perf_session *session;
 };
 
 size_t perf_top__header_snprintf(struct perf_top *top, char *bf, size_t size);
tools/perf/util/ui/browsers/top.c +24 -0
index 9d93810..9b6b43b 100644
@@ -11,10 +11,12 @@
 #include "../helpline.h"
 #include "../libslang.h"
 #include "../util.h"
+#include "../ui.h"
 #include "../../evlist.h"
 #include "../../hist.h"
 #include "../../sort.h"
 #include "../../symbol.h"
+#include "../../session.h"
 #include "../../top.h"
 
 struct perf_top_browser {
@@ -143,6 +145,25 @@ do_annotation:
 	symbol__tui_annotate(sym, syme->map, 0, top->delay_secs * 1000);
 }
 
+static void perf_top_browser__warn_lost(struct perf_top_browser *browser)
+{
+	struct perf_top *top = browser->b.priv;
+	char msg[128];
+	int len;
+
+	top->total_lost_warned = top->session->hists.stats.total_lost;
+	pthread_mutex_lock(&ui__lock);
+	ui_browser__set_color(&browser->b, HE_COLORSET_TOP);
+	len = snprintf(msg, sizeof(msg),
+		      " WARNING: LOST %" PRIu64 " events, Check IO/CPU overload",
+		      top->total_lost_warned);
+	if (len > browser->b.width)
+		len = browser->b.width;
+	SLsmg_gotorc(0, browser->b.width - len);
+	slsmg_write_nstring(msg, len);
+	pthread_mutex_unlock(&ui__lock);
+}
+
 static int perf_top_browser__run(struct perf_top_browser *browser)
 {
 	int key;
@@ -174,6 +195,9 @@ static int perf_top_browser__run(struct perf_top_browser *browser)
 			ui_browser__set_color(&browser->b, NEWT_COLORSET_ROOT);
 			SLsmg_gotorc(0, 0);
 			slsmg_write_nstring(title, browser->b.width);
+
+			if (top->total_lost_warned != top->session->hists.stats.total_lost)
+				perf_top_browser__warn_lost(browser);
 			break;
 		case 'a':
 		case NEWT_KEY_RIGHT:
Signature · 1 line
1.6.2.5
#7 lore raw

PATCH 7/16 perf stat: Add --log-fd <N> option to redirect stderr elsewhere

In reply to Arnaldo Carvalho de Melo

From: Jim Cromie <[email protected]>

This perf stat option emulates valgrind's --log-fd option, allowing the user to send perf results elsewhere, and leaving stderr for use by the program under test. This complements --output file option, and is mutually exclusive with it.

   3>results  perf stat --log-fd 3          -- $cmd
   3>>results perf stat --log-fd 3 --append -- $cmd

The perl distro's make test.valgrind target uses valgrind's --log-fd option, I've adapted it to invoke perf also, and tested this patch there.

---
 tools/perf/Documentation/perf-stat.txt |   11 ++++++++++-
 tools/perf/builtin-stat.c              |   14 ++++++++++++++
 2 files changed, 24 insertions(+), 1 deletions(-)
tools/perf/Documentation/perf-stat.txt +10 -1
index 08394c4..8966b9a 100644
@@ -95,12 +95,21 @@ corresponding events, i.e., they always refer to events defined earlier on the c
 line.
 
 -o file::
--output file::
+--output file::
 Print the output into the designated file.
 
 --append::
 Append to the output file designated with the -o option. Ignored if -o is not specified.
 
+--log-fd::
+
+Log output to fd, instead of stderr.  Complementary to --output, and mutually exclusive
+with it.  --append may be used here.  Examples:
+     3>results  perf stat --log-fd 3          -- $cmd
+     3>>results perf stat --log-fd 3 --append -- $cmd
+
+
+
 EXAMPLES
 --------
 
tools/perf/builtin-stat.c +14 -0
index bec64a9..a43c680 100644
@@ -196,6 +196,7 @@ static bool			csv_output			= false;
 static bool			group				= false;
 static const char		*output_name			= NULL;
 static FILE			*output				= NULL;
+static int			output_fd;
 
 static volatile int done = 0;
 
@@ -1080,6 +1081,8 @@ static const struct option options[] = {
 	OPT_STRING('o', "output", &output_name, "file",
 		    "output file name"),
 	OPT_BOOLEAN(0, "append", &append_file, "append to the output file"),
+	OPT_INTEGER(0, "log-fd", &output_fd,
+		    "log output to fd, instead of stderr"),
 	OPT_END()
 };
 
@@ -1166,6 +1169,10 @@ int cmd_stat(int argc, const char **argv, const char *prefix __used)
 	if (output_name && strcmp(output_name, "-"))
 		output = NULL;
 
+	if (output_name && output_fd) {
+		fprintf(stderr, "cannot use both --output and --log-fd\n");
+		usage_with_options(stat_usage, options);
+	}
 	if (!output) {
 		struct timespec tm;
 		mode = append_file ? "a" : "w";
@@ -1177,6 +1184,13 @@ int cmd_stat(int argc, const char **argv, const char *prefix __used)
 		}
 		clock_gettime(CLOCK_REALTIME, &tm);
 		fprintf(output, "# started on %s\n", ctime(&tm.tv_sec));
+	} else if (output_fd != 2) {
+		mode = append_file ? "a" : "w";
+		output = fdopen(output_fd, mode);
+		if (!output) {
+			perror("Failed opening logfd");
+			return -errno;
+		}
 	}
 
 	if (csv_sep)
Signature · 1 line
1.6.2.5
#8 lore raw

PATCH 1/1 perf stat: Fix default logfd to use stderr

Quoted 10 lines · Arnaldo Carvalho de Melo

From: Jim Cromie <[email protected]>

This perf stat option emulates valgrind's --log-fd option, allowing the user to send perf results elsewhere, and leaving stderr for use by the program under test. This complements --output file option, and is mutually exclusive with it.

   3>results  perf stat --log-fd 3          -- $cmd
   3>>results perf stat --log-fd 3 --append -- $cmd
Quoted 8 lines

The perl distro's make test.valgrind target uses valgrind's --log-fd option, I've adapted it to invoke perf also, and tested this patch there.

With certain shell redirections this (56f3bae) fails with a log fd setup failure. Fix below.

-Robert

Quoted 1 line

From fd83259163c8022f9264a119d5ef7df594702f3a Mon Sep 17 00:00:00 2001

From: Robert Richter <[email protected]>
Date: Thu, 7 Jun 2012 17:41:52 +0200
Subject: [PATCH] perf stat: Fix default logfd to use stderr

When running perf-stat in certain shell environments with stdout redirection there is a logging file descriptor setup failure:

Failed opening logfd: Invalid argument

Fixing this by setting the default fd to the correct value of 2.

---
 tools/perf/builtin-stat.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
tools/perf/builtin-stat.c +1 -1
index 2625899..c47e7d3 100644
@@ -195,7 +195,7 @@ static bool			csv_output			= false;
 static bool			group				= false;
 static const char		*output_name			= NULL;
 static FILE			*output				= NULL;
-static int			output_fd;
+static int			output_fd			=  2;
 
 static volatile int done = 0;
 
Signature · 7 lines
1.7.8.4



-- 
Advanced Micro Devices, Inc.
Operating System Research Center
maintainer
#9 lore raw

Re: [PATCH] perf stat: Fix default logfd to use stderr

Hi, Robert

Quoted 15 lines · Robert Richter
Quoted 14 lines · Arnaldo Carvalho de Melo

From: Jim Cromie <[email protected]>

This perf stat option emulates valgrind's --log-fd option, allowing the user to send perf results elsewhere, and leaving stderr for use by the program under test. This complements --output file option, and is mutually exclusive with it.

   3>results  perf stat --log-fd 3          -- $cmd
   3>>results perf stat --log-fd 3 --append -- $cmd

The perl distro's make test.valgrind target uses valgrind's --log-fd option, I've adapted it to invoke perf also, and tested this patch there.

Quoted 8 lines
Quoted 4 lines

With certain shell redirections this (56f3bae) fails with a log fd setup failure. Fix below.

It looks somewhat related to Stephane's patch. Can you we check it too?

http://lkml.indiana.edu/hypermail/linux/kernel/1205.1/04232.html

Thanks,
Namhyung

#10 lore raw

Re: [PATCH] perf stat: Fix default logfd to use stderr

Quoted 23 lines · Namhyung Kim

Hi, Robert

Quoted 20 lines · Robert Richter
Quoted 18 lines · Arnaldo Carvalho de Melo

From: Jim Cromie <[email protected]>

This perf stat option emulates valgrind's --log-fd option, allowing the user to send perf results elsewhere, and leaving stderr for use by the program under test.  This complements --output file option, and is mutually exclusive with it.

   3>results  perf stat --log-fd 3          -- $cmd 3>>results perf stat --log-fd 3 --append -- $cmd

The perl distro's make test.valgrind target uses valgrind's --log-fd option, I've adapted it to invoke perf also, and tested this patch there.

Quoted 8 lines
Quoted 3 lines

With certain shell redirections this (56f3bae) fails with a log fd setup failure. Fix below.

It looks somewhat related to Stephane's patch. Can you we check it too?

http://lkml.indiana.edu/hypermail/linux/kernel/1205.1/04232.html

Yes, my patch is needed and it was posted over a month ago now..... Arnaldo, please apply my patch.

Quoted 2 lines

Thanks,
Namhyung

#11 lore raw

Re: [PATCH] perf stat: Fix default logfd to use stderr

Quoted 24 lines · Stephane Eranian
Quoted 23 lines · Namhyung Kim

Hi, Robert

Quoted 20 lines · Robert Richter
Quoted 18 lines · Arnaldo Carvalho de Melo

From: Jim Cromie <[email protected]>

This perf stat option emulates valgrind's --log-fd option, allowing the user to send perf results elsewhere, and leaving stderr for use by the program under test. �This complements --output file option, and is mutually exclusive with it.

� �3>results �perf stat --log-fd 3 � � � � �-- $cmd � �3>>results perf stat --log-fd 3 --append -- $cmd

The perl distro's make test.valgrind target uses valgrind's --log-fd option, I've adapted it to invoke perf also, and tested this patch there.

Quoted 7 lines
Quoted 7 lines
Quoted 3 lines

With certain shell redirections this (56f3bae) fails with a log fd setup failure. Fix below.

It looks somewhat related to Stephane's patch. Can you we check it too?

http://lkml.indiana.edu/hypermail/linux/kernel/1205.1/04232.html

I applied the patch to my tree and this works too. Both patches basically avoid fdopen() if a log-fd option is not given.

After reviewing the code again I noticed my code breaks the -o option. So Stephane's patch is fine for me too, except for the fact that --log-fd 0 is ignored. Maybe we change this by initializing output_fd with -1 and modify the checks of output_fd?

Quoted 2 lines

Yes, my patch is needed and it was posted over a month ago now..... Arnaldo, please apply my patch.

It is in the pull request for Ingo.

-Robert

Signature · 2 lines
Advanced Micro Devices, Inc.
Operating System Research Center
#12 lore raw

Re: [PATCH] perf stat: Fix default logfd to use stderr

In reply to Stephane Eranian

Em Tue, Jun 19, 2012 at 08:09:31AM +0200, Stephane Eranian escreveu:

Quoted 11 lines · Namhyung Kim
Quoted 7 lines · Robert Richter
Quoted 2 lines

With certain shell redirections this (56f3bae) fails with a log fd setup failure. Fix below.

It looks somewhat related to Stephane's patch. Can you we check it too?

http://lkml.indiana.edu/hypermail/linux/kernel/1205.1/04232.html

Yes, my patch is needed and it was posted over a month ago now..... Arnaldo, please apply my patch.

It was applied a week ago, was merged already by Ingo, should go to Linus soon:

http://git.kernel.org/?p=linux/kernel/git/tip/tip.git;a=commit;h=fc3e4d077d5c7a7bc1ad5bc143895b4e070e5a8b

- Arnaldo

#13 lore raw

Re: [PATCH] perf stat: Fix default logfd to use stderr

Ok, I see it now.
thanks.
the only one left at this point is the pipe mode meta-data patch to add header in pipe mode.

Quoted 19 lines · Arnaldo Carvalho de Melo

Em Tue, Jun 19, 2012 at 08:09:31AM +0200, Stephane Eranian escreveu:

Quoted 11 lines · Namhyung Kim
Quoted 7 lines · Robert Richter
Quoted 2 lines

With certain shell redirections this (56f3bae) fails with a log fd setup failure. Fix below.

It looks somewhat related to Stephane's patch. Can you we check it too?

http://lkml.indiana.edu/hypermail/linux/kernel/1205.1/04232.html

Yes, my patch is needed and it was posted over a month ago now..... Arnaldo, please apply my patch.

It was applied a week ago, was merged already by Ingo, should go to Linus soon:

http://git.kernel.org/?p=linux/kernel/git/tip/tip.git;a=commit;h=fc3e4d077d5c7a7bc1ad5bc143895b4e070e5a8b

- Arnaldo

#14 lore raw

PATCH 8/16 perf stat: Fix +- nan% in --no-aggr runs

In reply to Arnaldo Carvalho de Melo

From: Jim Cromie <[email protected]>

Without this patch, running:

$ sudo ./perf stat -r20 --no-aggr -a perl -e '$i++ for 1..100000'

I get computations like this:

CPU0             12.488247 task-clock                #    1.224 CPUs utilized            ( +-  -nan% )
CPU1             12.488909 task-clock                #    1.225 CPUs utilized            ( +-  -nan% )
CPU2             12.500221 task-clock                #    1.226 CPUs utilized            ( +-  -nan% )
CPU3             12.481713 task-clock                #    1.224 CPUs utilized            ( +-  -nan% )

but with patch, I get:

CPU0              8.233682 task-clock                #    0.754 CPUs utilized            ( +-  0.00% )
CPU1              8.226318 task-clock                #    0.754 CPUs utilized            ( +-  0.00% )
CPU2              8.210737 task-clock                #    0.752 CPUs utilized            ( +-  0.00% )
CPU3              8.201691 task-clock                #    0.751 CPUs utilized            ( +-  0.00% )

Note that without --no-aggr, I get non-0 statistics both before and after patch:

        231.986022 task-clock                #    4.030 CPUs utilized            ( +-  0.97% )
               212 context-switches          #    0.001 M/sec                    ( +- 12.07% )
                 9 CPU-migrations            #    0.000 M/sec                    ( +- 25.80% )
               466 page-faults               #    0.002 M/sec                    ( +-  3.23% )
       174,318,593 cycles                    #    0.751 GHz                      ( +-  1.06% )

I couldnt see anything wrong in the caller, so fixed it in stddev_stats(). ISTM that 0.00 is better than nan, since perf stat was passed -A (--no-aggr) so no standard deviation should be expected, and nan is suggestive of a deeper error.

When running with --no-aggr, perhaps we should suppress the statistics printing entirely, or do so when they are 0.00.

---
 tools/perf/builtin-stat.c |    9 +++++++--
 1 files changed, 7 insertions(+), 2 deletions(-)
tools/perf/builtin-stat.c +7 -2
index a43c680..af0d65b 100644
@@ -254,8 +254,13 @@ static double avg_stats(struct stats *stats)
  */
 static double stddev_stats(struct stats *stats)
 {
-	double variance = stats->M2 / (stats->n - 1);
-	double variance_mean = variance / stats->n;
+	double variance, variance_mean;
+
+	if (!stats->n)
+		return 0.0;
+
+	variance = stats->M2 / (stats->n - 1);
+	variance_mean = variance / stats->n;
 
 	return sqrt(variance_mean);
 }
Signature · 1 line
1.6.2.5
#15 lore raw

PATCH 9/16 perf stat: Suppress printing std-dev when its 0

In reply to Arnaldo Carvalho de Melo

From: Jim Cromie <[email protected]>

For pretty output only (preserve column for cvs output), dont print std-deviation when its 0.00. Do this based upon value, instead of checking for --no-aggr, since the stats could conceivably be computed over the runs on each CPU, and theres no reason to preclude that.

---
 tools/perf/builtin-stat.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
tools/perf/builtin-stat.c +1 -1
index af0d65b..076eda5 100644
@@ -528,7 +528,7 @@ static void print_noise_pct(double total, double avg)
 
 	if (csv_output)
 		fprintf(output, "%s%.2f%%", csv_sep, pct);
-	else
+	else if (pct)
 		fprintf(output, "  ( +-%6.2f%% )", pct);
 }
 
Signature · 1 line
1.6.2.5
#16 lore raw

PATCH 10/16 perf stat: Allow tab as cvs delimiter

In reply to Arnaldo Carvalho de Melo

From: Jim Cromie <[email protected]>

If option -x '\t' is given, convert '\t' to "\t". This makes cvs printing more flexible.

---
 tools/perf/builtin-stat.c |    6 ++++--
 1 files changed, 4 insertions(+), 2 deletions(-)
tools/perf/builtin-stat.c +4 -2
index 076eda5..0ffbd97 100644
@@ -1198,9 +1198,11 @@ int cmd_stat(int argc, const char **argv, const char *prefix __used)
 		}
 	}
 
-	if (csv_sep)
+	if (csv_sep) {
 		csv_output = true;
-	else
+		if (!strcmp(csv_sep, "\\t"))
+			csv_sep = "\t";
+	} else
 		csv_sep = DEFAULT_SEPARATOR;
 
 	/*
Signature · 1 line
1.6.2.5
#17 lore raw

Re: [PATCH 10/16] perf stat: Allow tab as cvs delimiter

Quoted 4 lines · Arnaldo Carvalho de Melo

From: Jim Cromie <[email protected]>

If option -x '\t' is given, convert '\t' to "\t". This makes cvs printing more flexible.

I found this message when I searched my mail for occurences of 'cvs'. Is it still possible to change 'cvs' to 'csv' in the commit summary and message? That would keep the result for grepping of either term (in commit summaries or messages) correct.

Paul Bolle

#18 lore raw

PATCH 11/16 perf stat: Fix spelling in comment

In reply to Arnaldo Carvalho de Melo

From: Jim Cromie <[email protected]>

---
 tools/perf/builtin-stat.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
tools/perf/builtin-stat.c +1 -1
index 0ffbd97..b567319 100644
@@ -1209,7 +1209,7 @@ int cmd_stat(int argc, const char **argv, const char *prefix __used)
 	 * let the spreadsheet do the pretty-printing
 	 */
 	if (csv_output) {
-		/* User explicitely passed -B? */
+		/* User explicitly passed -B? */
 		if (big_num_opt == 1) {
 			fprintf(stderr, "-B option not supported with -x\n");
 			usage_with_options(stat_usage, options);
Signature · 1 line
1.6.2.5
#19 lore raw

PATCH 12/16 perf tools: Make stat/record print fatal signals of the target program

In reply to Arnaldo Carvalho de Melo

From: Andi Kleen <[email protected]>

When a program crashes under perf there is no message about it, unlike when running it from bash. This can be confusing and lead to wrong actions during debugging.

Print fatal signals in perf stat/record.

Thanks to Furat Afram for finding the problem originally

---
 tools/perf/builtin-record.c |   19 +++++++++++++++++--
 tools/perf/builtin-stat.c   |    2 ++
 2 files changed, 19 insertions(+), 2 deletions(-)
tools/perf/builtin-record.c +17 -2
index 6b0519f..042117f 100644
@@ -73,6 +73,7 @@ static off_t			post_processing_offset;
 
 static struct perf_session	*session;
 static const char		*cpu_list;
+static const char               *progname;
 
 static void advance_output(size_t size)
 {
@@ -137,17 +138,29 @@ static void mmap_read(struct perf_mmap *md)
 
 static volatile int done = 0;
 static volatile int signr = -1;
+static volatile int child_finished = 0;
 
 static void sig_handler(int sig)
 {
+	if (sig == SIGCHLD)
+		child_finished = 1;
+
 	done = 1;
 	signr = sig;
 }
 
 static void sig_atexit(void)
 {
-	if (child_pid > 0)
-		kill(child_pid, SIGTERM);
+	int status;
+
+	if (child_pid > 0) {
+		if (!child_finished)
+			kill(child_pid, SIGTERM);
+
+		wait(&status);
+		if (WIFSIGNALED(status))
+			psignal(WTERMSIG(status), progname);
+	}
 
 	if (signr == -1 || signr == SIGUSR1)
 		return;
@@ -445,6 +458,8 @@ static int __cmd_record(int argc, const char **argv)
 	char buf;
 	struct machine *machine;
 
+	progname = argv[0];
+
 	page_size = sysconf(_SC_PAGE_SIZE);
 
 	atexit(sig_atexit);
tools/perf/builtin-stat.c +2 -0
index b567319..7ce65f5 100644
@@ -495,6 +495,8 @@ static int run_perf_stat(int argc __used, const char **argv)
 	if (forks) {
 		close(go_pipe[1]);
 		wait(&status);
+		if (WIFSIGNALED(status))
+			psignal(WTERMSIG(status), argv[0]);
 	} else {
 		while(!done) sleep(1);
 	}
Signature · 1 line
1.6.2.5
#20 lore raw

PATCH 13/16 perf: Support setting the disassembler style

In reply to Arnaldo Carvalho de Melo

From: Andi Kleen <[email protected]>

Add -M option to report/annotate to pass directly to objdump. This allows to use -M intel for intel style disassembler syntax, which is useful for people who are very used to the Intel syntax.

[committer note: Add missing Documentation bits, fixup conflicts with 3e6a2a7]
Cc Frederic Weisbecker <[email protected]>
Cc Stephane Eranian <[email protected]>
---
 tools/perf/Documentation/perf-annotate.txt |    3 +++
 tools/perf/Documentation/perf-report.txt   |    3 +++
 tools/perf/builtin-annotate.c              |    2 ++
 tools/perf/builtin-report.c                |    2 ++
 tools/perf/util/annotate.c                 |    6 +++++-
 tools/perf/util/annotate.h                 |    2 ++
 6 files changed, 17 insertions(+), 1 deletions(-)
tools/perf/Documentation/perf-annotate.txt +3 -0
index 98a31e3..0102d83 100644
@@ -83,6 +83,9 @@ OPTIONS
 --symfs=<directory>::
         Look for files with symbols relative to this directory.
 
+-M::
+--disassembler-style=:: Set disassembler style for objdump.
+
 SEE ALSO
 --------
 linkperf:perf-record[1], linkperf:perf-report[1]
tools/perf/Documentation/perf-report.txt +3 -0
index 04253c0..6349b6c 100644
@@ -134,6 +134,9 @@ OPTIONS
 	CPUs are specified with -: 0-2. Default is to report samples on all
 	CPUs.
 
+-M::
+--disassembler-style=:: Set disassembler style for objdump.
+
 SEE ALSO
 --------
 linkperf:perf-stat[1]
tools/perf/builtin-annotate.c +2 -0
index c5be288..cf68819 100644
@@ -273,6 +273,8 @@ static const struct option options[] = {
 		    "Interleave source code with assembly code (default)"),
 	OPT_BOOLEAN('0', "asm-raw", &symbol_conf.annotate_asm_raw,
 		    "Display raw encoding of assembly instructions (default)"),
+	OPT_STRING('M', "disassembler-style", &disassembler_style, "disassembler style",
+		   "Specify disassembler style (e.g. -M intel for intel syntax)"),
 	OPT_END()
 };
 
tools/perf/builtin-report.c +2 -0
index d7ff277..a0673ee 100644
@@ -487,6 +487,8 @@ static const struct option options[] = {
 	OPT_STRING(0, "symfs", &symbol_conf.symfs, "directory",
 		    "Look for files with symbols relative to this directory"),
 	OPT_STRING('c', "cpu", &cpu_list, "cpu", "list of cpus to profile"),
+	OPT_STRING('M', "disassembler-style", &disassembler_style, "disassembler style",
+		   "Specify disassembler style (e.g. -M intel for intel syntax)"),
 	OPT_END()
 };
 
tools/perf/util/annotate.c +5 -1
index 01d36ba..bc8f477 100644
@@ -16,6 +16,8 @@
 #include "annotate.h"
 #include <pthread.h>
 
+const char 	*disassembler_style;
+
 int symbol__annotate_init(struct map *map __used, struct symbol *sym)
 {
 	struct annotation *notes = symbol__annotation(sym);
@@ -323,9 +325,11 @@ fallback:
 		 dso, dso->long_name, sym, sym->name);
 
 	snprintf(command, sizeof(command),
-		 "objdump --start-address=0x%016" PRIx64
+		 "objdump %s%s --start-address=0x%016" PRIx64
 		 " --stop-address=0x%016" PRIx64
 		 " -d %s %s -C %s|grep -v %s|expand",
+		 disassembler_style ? "-M " : "",
+		 disassembler_style ? disassembler_style : "",
 		 map__rip_2objdump(map, sym->start),
 		 map__rip_2objdump(map, sym->end),
 		 symbol_conf.annotate_asm_raw ? "" : "--no-show-raw",
tools/perf/util/annotate.h +2 -0
index c2c2868..6ede128 100644
@@ -100,4 +100,6 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map, int evidx,
 			 int refresh);
 #endif
 
+extern const char	*disassembler_style;
+
 #endif	/* __PERF_ANNOTATE_H */
Signature · 1 line
1.6.2.5
#21 lore raw

PATCH 14/16 perf report: Fix stdio event name header printing

In reply to Arnaldo Carvalho de Melo

From: Arnaldo Carvalho de Melo <[email protected]>

In the past we tried to avoid printing the name of the event when just one event was found in the perf.data file, after some refactorings it ended up not printing the event name if just one hist_entry was found in one of the events.

Fix it by always printing the name of the event, even if just one is found.

---
 tools/perf/builtin-report.c |    5 +----
 1 files changed, 1 insertions(+), 4 deletions(-)
tools/perf/builtin-report.c +1 -4
index a0673ee..3d58334 100644
@@ -229,10 +229,7 @@ static int perf_evlist__tty_browse_hists(struct perf_evlist *evlist,
 
 	list_for_each_entry(pos, &evlist->entries, node) {
 		struct hists *hists = &pos->hists;
-		const char *evname = NULL;
-
-		if (rb_first(&hists->entries) != rb_last(&hists->entries))
-			evname = event_name(pos);
+		const char *evname = event_name(pos);
 
 		hists__fprintf_nr_sample_events(hists, evname, stdout);
 		hists__fprintf(hists, NULL, false, stdout);
Signature · 1 line
1.6.2.5
#22 lore raw

PATCH 15/16 perf sched: Fix script command documentation

In reply to Arnaldo Carvalho de Melo

From: Jiri Olsa <[email protected]>

Fixed leftover from trace -> script rename.

---
 tools/perf/Documentation/perf-sched.txt |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)
tools/perf/Documentation/perf-sched.txt +3 -3
index 46822d5..5b212b5 100644
@@ -8,7 +8,7 @@ perf-sched - Tool to trace/measure scheduler properties (latencies)
 SYNOPSIS
 --------
 [verse]
-'perf sched' {record|latency|map|replay|trace}
+'perf sched' {record|latency|map|replay|script}
 
 DESCRIPTION
 -----------
@@ -20,8 +20,8 @@ There are five variants of perf sched:
   'perf sched latency' to report the per task scheduling latencies
   and other scheduling properties of the workload.
 
-  'perf sched trace' to see a detailed trace of the workload that
-  was recorded.
+  'perf sched script' to see a detailed trace of the workload that
+   was recorded (aliased to 'perf script' for now).
 
   'perf sched replay' to simulate the workload that was recorded
   via perf sched record. (this is done by starting up mockup threads
Signature · 1 line
1.6.2.5
#23 lore raw

PATCH 16/16 perf symbols: Treat all memory maps without dso file as loaded

In reply to Arnaldo Carvalho de Melo

From: Jiri Olsa <[email protected]>

The stack/vdso/heap memory maps dont have any dso file. Setting the perf dso objects as 'loaded' for these maps, we avoid unnecessary warnings like:

"Failed to open [stack], continuing without symbols"

All map__find_* functions still return NULL when searching for symbols in these maps.

---
 tools/perf/util/map.c |   24 ++++++++++++++++++------
 1 files changed, 18 insertions(+), 6 deletions(-)
tools/perf/util/map.c +18 -6
index aa2f9fd..9cf0d43 100644
@@ -18,6 +18,13 @@ static inline int is_anon_memory(const char *filename)
 	return strcmp(filename, "//anon") == 0;
 }
 
+static inline int is_no_dso_memory(const char *filename)
+{
+	return !strcmp(filename, "[stack]") ||
+	       !strcmp(filename, "[vdso]")  ||
+	       !strcmp(filename, "[heap]");
+}
+
 void map__init(struct map *self, enum map_type type,
 	       u64 start, u64 end, u64 pgoff, struct dso *dso)
 {
@@ -42,9 +49,10 @@ struct map *map__new(struct list_head *dsos__list, u64 start, u64 len,
 	if (self != NULL) {
 		char newfilename[PATH_MAX];
 		struct dso *dso;
-		int anon;
+		int anon, no_dso;
 
 		anon = is_anon_memory(filename);
+		no_dso = is_no_dso_memory(filename);
 
 		if (anon) {
 			snprintf(newfilename, sizeof(newfilename), "/tmp/perf-%d.map", pid);
@@ -57,12 +65,16 @@ struct map *map__new(struct list_head *dsos__list, u64 start, u64 len,
 
 		map__init(self, type, start, start + len, pgoff, dso);
 
-		if (anon) {
-set_identity:
+		if (anon || no_dso) {
 			self->map_ip = self->unmap_ip = identity__map_ip;
-		} else if (strcmp(filename, "[vdso]") == 0) {
-			dso__set_loaded(dso, self->type);
-			goto set_identity;
+
+			/*
+			 * Set memory without DSO as loaded. All map__find_*
+			 * functions still return NULL, and we avoid the
+			 * unnecessary map__load warning.
+			 */
+			if (no_dso)
+				dso__set_loaded(dso, self->type);
 		}
 	}
 	return self;
Signature · 1 line
1.6.2.5
#24 lore raw
In reply to Arnaldo Carvalho de Melo
Quoted 54 lines · Arnaldo Carvalho de Melo

Hi Ingo,

Please consider pulling from:

git://github.com/acmel/linux.git perf/core

This was rebased against your perf/core on tesla.

Regards,

- Arnaldo

Andi Kleen (2):
perf tools: Make stat/record print fatal signals of the target program
perf: Support setting the disassembler style

Arnaldo Carvalho de Melo (6):
perf symbols: Stop using 'self' in map_groups__ methods perf buildid-list: Add option to show the running kernel build id perf buildid-list: Support showing the build id in an ELF file perf top browser: Fix up line width calculation
perf top: Improve lost events warning
perf report: Fix stdio event name header printing

Jim Cromie (5):
perf stat: Add --log-fd <N> option to redirect stderr elsewhere perf stat: Fix +- nan% in --no-aggr runs
perf stat: Suppress printing std-dev when its 0
perf stat: Allow tab as cvs delimiter
perf stat: Fix spelling in comment

Jiri Olsa (2):
perf sched: Fix script command documentation
perf symbols: Treat all memory maps without dso file as loaded

Neil Horman (1):
perf script: Add drop monitor script

 tools/perf/Documentation/perf-annotate.txt         |    3 +
 tools/perf/Documentation/perf-buildid-list.txt     |    6 +
 tools/perf/Documentation/perf-report.txt           |    3 +
 tools/perf/Documentation/perf-sched.txt            |    6 +-
 tools/perf/Documentation/perf-stat.txt             |   11 ++-
 tools/perf/builtin-annotate.c                      |    2 +
 tools/perf/builtin-buildid-list.c                  |   52 ++++++++++-
 tools/perf/builtin-record.c                        |   19 ++++-
 tools/perf/builtin-report.c                        |    7 +-
 tools/perf/builtin-stat.c                          |   35 ++++++-
 tools/perf/builtin-top.c                           |   34 ++++----
 .../perf/scripts/python/bin/net_dropmonitor-record |    2 +
 .../perf/scripts/python/bin/net_dropmonitor-report |    4 +
 tools/perf/scripts/python/net_dropmonitor.py       |   72 ++++++++++++++
 tools/perf/util/annotate.c                         |    6 +-
 tools/perf/util/annotate.h                         |    2 +
Quoted 8 lines
 tools/perf/util/map.c                              |   98 +++++++++++---------
 tools/perf/util/map.h                              |   42 ++++----
 tools/perf/util/top.h                              |    3 +
 tools/perf/util/ui/browsers/top.c                  |   28 +++++-
 20 files changed, 333 insertions(+), 102 deletions(-)
 create mode 100755 tools/perf/scripts/python/bin/net_dropmonitor-record
 create mode 100755 tools/perf/scripts/python/bin/net_dropmonitor-report
 create mode 100755 tools/perf/scripts/python/net_dropmonitor.py

Pulled, thanks a lot Arnaldo!

Ingo