Skip to contentSkip to conversation

perf/cor improvements and fixes

GIT PULL In review Arnaldo Carvalho de Melo 3 participants 20 messages Jul 8, 2014 – Jul 16, 2014 perf events

lore
Share & tools
lore

Arnaldo Carvalho de Melo

author maintainer
#0 lore raw

Hi Ingo,

Please consider pulling,

- Arnaldo

The following changes since commit 8b5b584daf3b92fc5cdc83919e64231817d2f5a7:

Merge tag 'perf-core-for-mingo' of git://git.kernel.org/pub/scm/linux/kernel/git/jolsa/perf into perf/core (2014-07-05 11:29:32 +0200)

are available in the git repository at:

git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux.git tags/perf-core-for-mingo

for you to fetch changes up to 4414a3c51028aea2ae2fe06c0377490eaa6abbfd:

perf trace: Fix build on 32-bit systems (2014-07-08 15:39:21 -0300)

----------------------------------------------------------------
perf/core improvements and fixes

User visible:

o Prep patches to support 'perf kvm stat' on s390 (Alexander Yarygin)

o Add pagefault statistics in 'trace' (Stanislav Fomichev)

o Add header for columns in 'top' and 'report' TUI browsers (Jiri Olsa)

o Add pagefault statistics in 'trace' (Stanislav Fomichev)

Build fixes:

Fix build on 32-bit systems (Arnaldo Carvalho de Melo)

Cleanups:

o Convert open coded equivalents to asprintf() (Andy Shevchenko)

Plumbing:

o Allow reserving a row for header purposes in the hists browser (Arnaldo Carvalho de Melo)

----------------------------------------------------------------
Alexander Yarygin (4):
perf kvm: Introduce HAVE_KVM_STAT_SUPPORT flag perf kvm: Simplify exit reasons tables definitions perf kvm: Refactoring of cpu_isa_config() perf tools: Allow to use cpuinfo on s390

Andy Shevchenko (1):
perf tools: Convert open coded equivalents to asprintf()

Arnaldo Carvalho de Melo (8):
perf ui browser: Add ->rows to disambiguate from ->height perf ui browser: Allow overriding refresh_dimensions method perf hists browser: Introduce gotorc method
perf hists browser: Override ui_browser refresh_dimensions method perf hists browser: Add support for showing columns header perf hists browser: Left justify column headers
perf tools: Suggest using -f to override perf.data file ownership message perf trace: Fix build on 32-bit systems

Jiri Olsa (2):
perf hists browser: Display columns header text on 'H' press perf hists browser: Add ui.show-headers config file option

Stanislav Fomichev (1):
perf trace: Add pagefault statistics

 tools/perf/arch/s390/Makefile      |   1 +
 tools/perf/arch/s390/util/header.c |  28 ++++++++
 tools/perf/arch/x86/Makefile       |   1 +
 tools/perf/builtin-kvm.c           |  72 +++++++++++----------
 tools/perf/builtin-trace.c         |  23 ++++++-
 tools/perf/config/Makefile         |   4 ++
 tools/perf/perf-sys.h              |   1 +
 tools/perf/ui/browser.c            |  37 ++++++-----
 tools/perf/ui/browser.h            |   3 +-
 tools/perf/ui/browsers/hists.c     | 128 ++++++++++++++++++++++++++++++++-----
 tools/perf/util/config.c           |  13 ++++
 tools/perf/util/data.c             |   2 +-
 tools/perf/util/sort.c             |   2 +-
 tools/perf/util/symbol.c           |   1 +
 tools/perf/util/symbol.h           |   3 +-
 tools/perf/util/trace-event-info.c |  12 +---
 tools/perf/util/util.c             |   9 +--
 17 files changed, 249 insertions(+), 91 deletions(-)
 create mode 100644 tools/perf/arch/s390/util/header.c
author maintainer
#1 lore raw

PATCH 1/16 perf ui browser: Add ->rows to disambiguate from ->height

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

The ui_browser->height is about the whole browser "window", including any header, status lines or any other space needed for some "Yes", "No", etc buttons a descendent browser, like hist_browser, may have.

Since the navigation is done mostly on the ui_browser methods, it needs to know how many rows are on the screen, while details about what other components are, say, if a header (that may be composed of multiple lines, etc) is present.

Besides this we'll need to add a ui_browser->refresh_dimensions() hook so that browsers like hist_browser can update ->rows in response to screen resizes, this will come in a follow up patch.

This patch just adds ->rows and updates it when updating ->height, keeps using ->height for the only other widget that can come with ui_browser, the scrollbar, that goes on using all the height on the rightmost column in the screen, using ->rows for the keyboard navigation needs.

Cc Adrian Hunter <[email protected]>
Cc David Ahern <[email protected]>
Cc Don Zickus <[email protected]>
Cc Frederic Weisbecker <[email protected]>
Cc Jiri Olsa <[email protected]>
Cc Mike Galbraith <[email protected]>
Cc Namhyung Kim <[email protected]>
Cc Paul Mackerras <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Stephane Eranian <[email protected]>
---
 tools/perf/ui/browser.c        | 30 +++++++++++++++---------------
 tools/perf/ui/browser.h        |  2 +-
 tools/perf/ui/browsers/hists.c | 16 ++++++++--------
 3 files changed, 24 insertions(+), 24 deletions(-)
tools/perf/ui/browser.c +15 -15
index 9d2294efc00c..adb294a3ec08 100644
@@ -150,7 +150,7 @@ unsigned int ui_browser__rb_tree_refresh(struct ui_browser *browser)
 	while (nd != NULL) {
 		ui_browser__gotorc(browser, row, 0);
 		browser->write(browser, nd, row);
-		if (++row == browser->height)
+		if (++row == browser->rows)
 			break;
 		nd = rb_next(nd);
 	}
@@ -166,7 +166,7 @@ bool ui_browser__is_current_entry(struct ui_browser *browser, unsigned row)
 void ui_browser__refresh_dimensions(struct ui_browser *browser)
 {
 	browser->width = SLtt_Screen_Cols - 1;
-	browser->height = SLtt_Screen_Rows - 2;
+	browser->height = browser->rows = SLtt_Screen_Rows - 2;
 	browser->y = 1;
 	browser->x = 0;
 }
@@ -389,7 +389,7 @@ int ui_browser__run(struct ui_browser *browser, int delay_secs)
 			if (browser->index == browser->nr_entries - 1)
 				break;
 			++browser->index;
-			if (browser->index == browser->top_idx + browser->height) {
+			if (browser->index == browser->top_idx + browser->rows) {
 				++browser->top_idx;
 				browser->seek(browser, +1, SEEK_CUR);
 			}
@@ -405,10 +405,10 @@ int ui_browser__run(struct ui_browser *browser, int delay_secs)
 			break;
 		case K_PGDN:
 		case ' ':
-			if (browser->top_idx + browser->height > browser->nr_entries - 1)
+			if (browser->top_idx + browser->rows > browser->nr_entries - 1)
 				break;
 
-			offset = browser->height;
+			offset = browser->rows;
 			if (browser->index + offset > browser->nr_entries - 1)
 				offset = browser->nr_entries - 1 - browser->index;
 			browser->index += offset;
@@ -419,10 +419,10 @@ int ui_browser__run(struct ui_browser *browser, int delay_secs)
 			if (browser->top_idx == 0)
 				break;
 
-			if (browser->top_idx < browser->height)
+			if (browser->top_idx < browser->rows)
 				offset = browser->top_idx;
 			else
-				offset = browser->height;
+				offset = browser->rows;
 
 			browser->index -= offset;
 			browser->top_idx -= offset;
@@ -432,7 +432,7 @@ int ui_browser__run(struct ui_browser *browser, int delay_secs)
 			ui_browser__reset_index(browser);
 			break;
 		case K_END:
-			offset = browser->height - 1;
+			offset = browser->rows - 1;
 			if (offset >= browser->nr_entries)
 				offset = browser->nr_entries - 1;
 
@@ -462,7 +462,7 @@ unsigned int ui_browser__list_head_refresh(struct ui_browser *browser)
 		if (!browser->filter || !browser->filter(browser, pos)) {
 			ui_browser__gotorc(browser, row, 0);
 			browser->write(browser, pos, row);
-			if (++row == browser->height)
+			if (++row == browser->rows)
 				break;
 		}
 	}
@@ -587,7 +587,7 @@ unsigned int ui_browser__argv_refresh(struct ui_browser *browser)
 		if (!browser->filter || !browser->filter(browser, *pos)) {
 			ui_browser__gotorc(browser, row, 0);
 			browser->write(browser, pos, row);
-			if (++row == browser->height)
+			if (++row == browser->rows)
 				break;
 		}
 
@@ -623,7 +623,7 @@ static void __ui_browser__line_arrow_up(struct ui_browser *browser,
 
 	SLsmg_set_char_set(1);
 
-	if (start < browser->top_idx + browser->height) {
+	if (start < browser->top_idx + browser->rows) {
 		row = start - browser->top_idx;
 		ui_browser__gotorc(browser, row, column);
 		SLsmg_write_char(SLSMG_LLCORN_CHAR);
@@ -633,7 +633,7 @@ static void __ui_browser__line_arrow_up(struct ui_browser *browser,
 		if (row-- == 0)
 			goto out;
 	} else
-		row = browser->height - 1;
+		row = browser->rows - 1;
 
 	if (end > browser->top_idx)
 		end_row = end - browser->top_idx;
@@ -675,8 +675,8 @@ static void __ui_browser__line_arrow_down(struct ui_browser *browser,
 	} else
 		row = 0;
 
-	if (end >= browser->top_idx + browser->height)
-		end_row = browser->height - 1;
+	if (end >= browser->top_idx + browser->rows)
+		end_row = browser->rows - 1;
 	else
 		end_row = end - browser->top_idx;
 
@@ -684,7 +684,7 @@ static void __ui_browser__line_arrow_down(struct ui_browser *browser,
 	SLsmg_draw_vline(end_row - row + 1);
 
 	ui_browser__gotorc(browser, end_row, column);
-	if (end < browser->top_idx + browser->height) {
+	if (end < browser->top_idx + browser->rows) {
 		SLsmg_write_char(SLSMG_LLCORN_CHAR);
 		ui_browser__gotorc(browser, end_row, column + 1);
 		SLsmg_write_char(SLSMG_HLINE_CHAR);
tools/perf/ui/browser.h +1 -1
index 03d4d6295f10..cb8f39a1646f 100644
@@ -14,7 +14,7 @@
 struct ui_browser {
 	u64	      index, top_idx;
 	void	      *top, *entries;
-	u16	      y, x, width, height;
+	u16	      y, x, width, height, rows;
 	int	      current_color;
 	void	      *priv;
 	const char    *title;
tools/perf/ui/browsers/hists.c +8 -8
index 2185091c5227..e16aff45b564 100644
@@ -392,10 +392,10 @@ static int hist_browser__run(struct hist_browser *browser,
 			struct hist_entry *h = rb_entry(browser->b.top,
 							struct hist_entry, rb_node);
 			ui_helpline__pop();
-			ui_helpline__fpush("%d: nr_ent=(%d,%d), height=%d, idx=%d, fve: idx=%d, row_off=%d, nrows=%d",
+			ui_helpline__fpush("%d: nr_ent=(%d,%d), rows=%d, idx=%d, fve: idx=%d, row_off=%d, nrows=%d",
 					   seq++, browser->b.nr_entries,
 					   browser->hists->nr_entries,
-					   browser->b.height,
+					   browser->b.rows,
 					   browser->b.index,
 					   browser->b.top_idx,
 					   h->row_offset, h->nr_rows);
@@ -514,7 +514,7 @@ static int hist_browser__show_callchain_node_rb_tree(struct hist_browser *browse
 			slsmg_write_nstring(str, width);
 			free(alloc_str);
 
-			if (++row == browser->b.height)
+			if (++row == browser->b.rows)
 				goto out;
 do_next:
 			if (folded_sign == '+')
@@ -527,7 +527,7 @@ do_next:
 									 new_level, row, row_offset,
 									 is_current_entry);
 		}
-		if (row == browser->b.height)
+		if (row == browser->b.rows)
 			goto out;
 		node = next;
 	}
@@ -573,7 +573,7 @@ static int hist_browser__show_callchain_node(struct hist_browser *browser,
 		slsmg_printf("%c ", folded_sign);
 		slsmg_write_nstring(s, width - 2);
 
-		if (++row == browser->b.height)
+		if (++row == browser->b.rows)
 			goto out;
 	}
 
@@ -602,7 +602,7 @@ static int hist_browser__show_callchain(struct hist_browser *browser,
 		row += hist_browser__show_callchain_node(browser, node, level,
 							 row, row_offset,
 							 is_current_entry);
-		if (row == browser->b.height)
+		if (row == browser->b.rows)
 			break;
 	}
 
@@ -776,7 +776,7 @@ static int hist_browser__show_entry(struct hist_browser *browser,
 	} else
 		--row_offset;
 
-	if (folded_sign == '-' && row != browser->b.height) {
+	if (folded_sign == '-' && row != browser->b.rows) {
 		printed += hist_browser__show_callchain(browser, &entry->sorted_chain,
 							1, row, &row_offset,
 							&current_entry);
@@ -817,7 +817,7 @@ static unsigned int hist_browser__refresh(struct ui_browser *browser)
 			continue;
 
 		row += hist_browser__show_entry(hb, h, row);
-		if (row == browser->height)
+		if (row == browser->rows)
 			break;
 	}
 
Signature · 1 line
1.9.3
author maintainer
#2 lore raw

PATCH 2/16 perf ui browser: Allow overriding refresh_dimensions method

In reply to Arnaldo Carvalho de Melo

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

Some browsers, like the hist_browser, may want to be notified everytime a refresh_dimensions is needed, so that it can reset ui_browser->rows, for instance, or do some other related reaction to screen resizings.

Cc Adrian Hunter <[email protected]>
Cc David Ahern <[email protected]>
Cc Don Zickus <[email protected]>
Cc Frederic Weisbecker <[email protected]>
Cc Jiri Olsa <[email protected]>
Cc Mike Galbraith <[email protected]>
Cc Namhyung Kim <[email protected]>
Cc Paul Mackerras <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Stephane Eranian <[email protected]>
---
 tools/perf/ui/browser.c | 7 +++++--
 tools/perf/ui/browser.h | 1 +
 2 files changed, 6 insertions(+), 2 deletions(-)
tools/perf/ui/browser.c +5 -2
index adb294a3ec08..6680fa5cb9dd 100644
@@ -250,7 +250,10 @@ int ui_browser__show(struct ui_browser *browser, const char *title,
 	int err;
 	va_list ap;
 
-	ui_browser__refresh_dimensions(browser);
+	if (browser->refresh_dimensions == NULL)
+		browser->refresh_dimensions = ui_browser__refresh_dimensions;
+
+	browser->refresh_dimensions(browser);
 
 	pthread_mutex_lock(&ui__lock);
 	__ui_browser__show_title(browser, title);
@@ -367,7 +370,7 @@ int ui_browser__run(struct ui_browser *browser, int delay_secs)
 
 		if (key == K_RESIZE) {
 			ui__refresh_dimensions(false);
-			ui_browser__refresh_dimensions(browser);
+			browser->refresh_dimensions(browser);
 			__ui_browser__show_title(browser, browser->title);
 			ui_helpline__puts(browser->helpline);
 			continue;
tools/perf/ui/browser.h +1 -0
index cb8f39a1646f..92ae72113965 100644
@@ -19,6 +19,7 @@ struct ui_browser {
 	void	      *priv;
 	const char    *title;
 	char	      *helpline;
+	void 	      (*refresh_dimensions)(struct ui_browser *browser);
 	unsigned int  (*refresh)(struct ui_browser *browser);
 	void	      (*write)(struct ui_browser *browser, void *entry, int row);
 	void	      (*seek)(struct ui_browser *browser, off_t offset, int whence);
Signature · 1 line
1.9.3
author maintainer
#3 lore raw

PATCH 3/16 perf hists browser: Introduce gotorc method

In reply to Arnaldo Carvalho de Melo

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

That will allow us to add a row offset to open up space for the column headers.

Cc Adrian Hunter <[email protected]>
Cc David Ahern <[email protected]>
Cc Don Zickus <[email protected]>
Cc Frederic Weisbecker <[email protected]>
Cc Jiri Olsa <[email protected]>
Cc Mike Galbraith <[email protected]>
Cc Namhyung Kim <[email protected]>
Cc Paul Mackerras <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Stephane Eranian <[email protected]>
---
 tools/perf/ui/browsers/hists.c | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)
tools/perf/ui/browsers/hists.c +8 -3
index e16aff45b564..ca63564d203a 100644
@@ -63,6 +63,11 @@ static void hist_browser__refresh_dimensions(struct hist_browser *browser)
 			     sizeof("[k]"));
 }
 
+static void hist_browser__gotorc(struct hist_browser *browser, int row, int column)
+{
+	ui_browser__gotorc(&browser->b, row, column);
+}
+
 static void hist_browser__reset(struct hist_browser *browser)
 {
 	/*
@@ -508,7 +513,7 @@ static int hist_browser__show_callchain_node_rb_tree(struct hist_browser *browse
 			}
 
 			ui_browser__set_color(&browser->b, color);
-			ui_browser__gotorc(&browser->b, row, 0);
+			hist_browser__gotorc(browser, row, 0);
 			slsmg_write_nstring(" ", offset + extra_offset);
 			slsmg_printf("%c ", folded_sign);
 			slsmg_write_nstring(str, width);
@@ -567,7 +572,7 @@ static int hist_browser__show_callchain_node(struct hist_browser *browser,
 
 		s = callchain_list__sym_name(chain, bf, sizeof(bf),
 					     browser->show_dso);
-		ui_browser__gotorc(&browser->b, row, 0);
+		hist_browser__gotorc(browser, row, 0);
 		ui_browser__set_color(&browser->b, color);
 		slsmg_write_nstring(" ", offset);
 		slsmg_printf("%c ", folded_sign);
@@ -732,7 +737,7 @@ static int hist_browser__show_entry(struct hist_browser *browser,
 			.ptr		= &arg,
 		};
 
-		ui_browser__gotorc(&browser->b, row, 0);
+		hist_browser__gotorc(browser, row, 0);
 
 		perf_hpp__for_each_format(fmt) {
 			if (perf_hpp__should_skip(fmt))
Signature · 1 line
1.9.3
author maintainer
#4 lore raw

PATCH 4/16 perf hists browser: Override ui_browser refresh_dimensions method

In reply to Arnaldo Carvalho de Melo

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

This requires some more work so that we can really just use the width of current entries when we want to partition the screen.

Right now its just a prep patch so that we can have where to update ui_browser->rows when introducing the column headers line, that will be togglable, so we need to update it everytime we refresh the dimensions of the browser.

Cc Adrian Hunter <[email protected]>
Cc David Ahern <[email protected]>
Cc Don Zickus <[email protected]>
Cc Frederic Weisbecker <[email protected]>
Cc Jiri Olsa <[email protected]>
Cc Mike Galbraith <[email protected]>
Cc Namhyung Kim <[email protected]>
Cc Paul Mackerras <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Stephane Eranian <[email protected]>
---
 tools/perf/ui/browsers/hists.c | 18 +++++++++++++-----
 1 file changed, 13 insertions(+), 5 deletions(-)
tools/perf/ui/browsers/hists.c +13 -5
index ca63564d203a..ef7abf896f5a 100644
@@ -56,11 +56,19 @@ static u32 hist_browser__nr_entries(struct hist_browser *hb)
 	return nr_entries + hb->nr_callchain_rows;
 }
 
-static void hist_browser__refresh_dimensions(struct hist_browser *browser)
+static void hist_browser__refresh_dimensions(struct ui_browser *browser)
 {
+	struct hist_browser *hb = container_of(browser, struct hist_browser, b);
+
 	/* 3 == +/- toggle symbol before actual hist_entry rendering */
-	browser->b.width = 3 + (hists__sort_list_width(browser->hists) +
-			     sizeof("[k]"));
+	browser->width = 3 + (hists__sort_list_width(hb->hists) + sizeof("[k]"));
+	/*
+ 	 * FIXME: Just keeping existing behaviour, but this really should be
+ 	 *	  before updating browser->width, as it will invalidate the
+ 	 *	  calculation above. Fix this and the fallout in another
+ 	 *	  changeset.
+ 	 */
+	ui_browser__refresh_dimensions(browser);
 }
 
 static void hist_browser__gotorc(struct hist_browser *browser, int row, int column)
@@ -78,7 +86,7 @@ static void hist_browser__reset(struct hist_browser *browser)
 
 	hist_browser__update_nr_entries(browser);
 	browser->b.nr_entries = hist_browser__nr_entries(browser);
-	hist_browser__refresh_dimensions(browser);
+	hist_browser__refresh_dimensions(&browser->b);
 	ui_browser__reset_index(&browser->b);
 }
 
@@ -360,7 +368,6 @@ static int hist_browser__run(struct hist_browser *browser,
 	browser->b.entries = &browser->hists->entries;
 	browser->b.nr_entries = hist_browser__nr_entries(browser);
 
-	hist_browser__refresh_dimensions(browser);
 	hists__browser_title(browser->hists, title, sizeof(title));
 
 	if (ui_browser__show(&browser->b, title,
@@ -1195,6 +1202,7 @@ static struct hist_browser *hist_browser__new(struct hists *hists)
 	if (browser) {
 		browser->hists = hists;
 		browser->b.refresh = hist_browser__refresh;
+		browser->b.refresh_dimensions = hist_browser__refresh_dimensions;
 		browser->b.seek = ui_browser__hists_seek;
 		browser->b.use_navkeypressed = true;
 	}
Signature · 1 line
1.9.3
#5 lore raw

Re: [PATCH 04/16] perf hists browser: Override ui_browser refresh_dimensions method

Quoted 2 lines · Arnaldo Carvalho de Melo

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

SNIP

Quoted 6 lines

index ca63564d203a..ef7abf896f5a 100644

tools/perf/ui/browsers/hists.c +0 -0
@@ -56,11 +56,19 @@ static u32 hist_browser__nr_entries(struct hist_browser *hb)
 	return nr_entries + hb->nr_callchain_rows;
 }

tools/perf/ui/browsers/hists.c static u32 hist_browser__nr_entries(struct hist_browser *hb) · line 64

Quoted 10 lines
tools/perf/ui/browsers/hists.c +4 -3
 
-static void hist_browser__refresh_dimensions(struct hist_browser *browser)
+static void hist_browser__refresh_dimensions(struct ui_browser *browser)
 {
+	struct hist_browser *hb = container_of(browser, struct hist_browser, b);
+
 	/* 3 == +/- toggle symbol before actual hist_entry rendering */
-	browser->b.width = 3 + (hists__sort_list_width(browser->hists) +
-			     sizeof("[k]"));
+	browser->width = 3 + (hists__sort_list_width(hb->hists) + sizeof("[k]"));

why not remove this completely? it'll get overwritten in the following ui_browser__refresh_dimensions call anyway..

tools/perf/ui/browsers/hists.c static u32 hist_browser__nr_entries(struct hist_browser *hb) · line 70

Quoted 6 lines
tools/perf/ui/browsers/hists.c +6 -0
+	/*
+ 	 * FIXME: Just keeping existing behaviour, but this really should be
+ 	 *	  before updating browser->width, as it will invalidate the
+ 	 *	  calculation above. Fix this and the fallout in another
+ 	 *	  changeset.
+ 	 */

extra whitespace above

jirka

author maintainer
#6 lore raw

Re: [PATCH 04/16] perf hists browser: Override ui_browser refresh_dimensions method

Em Thu, Jul 10, 2014 at 12:48:49AM +0200, Jiri Olsa escreveu:

Quoted 13 lines · Arnaldo Carvalho de Melo
Quoted 2 lines

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

SNIP

Quoted 7 lines

index ca63564d203a..ef7abf896f5a 100644

tools/perf/ui/browsers/hists.c +0 -0
@@ -56,11 +56,19 @@ static u32 hist_browser__nr_entries(struct hist_browser *hb)
 	return nr_entries + hb->nr_callchain_rows;
 }
 
Quoted 12 lines

tools/perf/ui/browsers/hists.c static u32 hist_browser__nr_entries(struct hist_browser *hb) · line 64

Quoted 9 lines
tools/perf/ui/browsers/hists.c +4 -3
-static void hist_browser__refresh_dimensions(struct hist_browser *browser)
+static void hist_browser__refresh_dimensions(struct ui_browser *browser)
 {
+	struct hist_browser *hb = container_of(browser, struct hist_browser, b);
+
 	/* 3 == +/- toggle symbol before actual hist_entry rendering */
-	browser->b.width = 3 + (hists__sort_list_width(browser->hists) +
-			     sizeof("[k]"));
+	browser->width = 3 + (hists__sort_list_width(hb->hists) + sizeof("[k]"));

why not remove this completely? it'll get overwritten in the following ui_browser__refresh_dimensions call anyway..

I thought I left a comment below it explaining that this would get fixed at a later patch, but yeah, we can comment it out, leaving it just as a hint at what needs to be done if we ever want to partition the screen horizontally.

Quoted 8 lines

tools/perf/ui/browsers/hists.c static u32 hist_browser__nr_entries(struct hist_browser *hb) · line 70

Quoted 6 lines
tools/perf/ui/browsers/hists.c +6 -0
+	/*
+ 	 * FIXME: Just keeping existing behaviour, but this really should be
+ 	 *	  before updating browser->width, as it will invalidate the
+ 	 *	  calculation above. Fix this and the fallout in another
+ 	 *	  changeset.
+ 	 */

extra whitespace above

Gack, thought I had that fixed, will check my pre-commit hooks... now:

[acme@zoo linux]$ ls -la .git/hooks/pre-commit.sample -rwxrwxr-x. 1 acme acme 1704 Abr 16 2013 .git/hooks/pre-commit.sample [acme@zoo linux]$ mv .git/hooks/pre-commit.sample .git/hooks/pre-commit [acme@zoo linux]$ vim .git/hooks/pre-commit
[acme@zoo linux]$ tail -3 .git/hooks/pre-commit

  # If there are whitespace errors, print the offending file names and
  # fail.
  exec git diff-index --check --cached $against --
  [acme@zoo linux]

I guess I should catch those on this machine from now on.

- Arnaldo

author maintainer
#7 lore raw

PATCH 5/16 perf hists browser: Add support for showing columns header

In reply to Arnaldo Carvalho de Melo

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

Open up space to show a one-line header text whenever 'H' is pressed, hide it on another key press.

Follow up patch will format this line from the set of headers used.

Cc Corey Ashford <[email protected]>
Cc David Ahern <[email protected]>
Cc Frederic Weisbecker <[email protected]>
Cc Ingo Molnar <[email protected]>
Cc Jiri Olsa <[email protected]>
Cc Namhyung Kim <[email protected]>
Cc Paul Mackerras <[email protected]>
Cc Peter Zijlstra <[email protected]>
---
 tools/perf/ui/browsers/hists.c | 42 ++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 40 insertions(+), 2 deletions(-)
tools/perf/ui/browsers/hists.c +40 -2
index ef7abf896f5a..2be71bf17b71 100644
@@ -26,6 +26,7 @@ struct hist_browser {
 	struct map_symbol   *selection;
 	int		     print_seq;
 	bool		     show_dso;
+	bool		     show_headers;
 	float		     min_pcnt;
 	u64		     nr_non_filtered_entries;
 	u64		     nr_callchain_rows;
@@ -56,6 +57,21 @@ static u32 hist_browser__nr_entries(struct hist_browser *hb)
 	return nr_entries + hb->nr_callchain_rows;
 }
 
+static void hist_browser__update_rows(struct hist_browser *hb)
+{
+	struct ui_browser *browser = &hb->b;
+	u16 header_offset = hb->show_headers ? 1 : 0, index_row;
+
+	browser->rows = browser->height - header_offset;
+	/*
+	 * Verify if we were at the last line and that line isn't
+	 * visibe because we now show the header line(s).
+	 */
+	index_row = browser->index - browser->top_idx;
+	if (index_row >= browser->rows)
+		browser->index -= index_row - browser->rows + 1;
+}
+
 static void hist_browser__refresh_dimensions(struct ui_browser *browser)
 {
 	struct hist_browser *hb = container_of(browser, struct hist_browser, b);
@@ -69,11 +85,14 @@ static void hist_browser__refresh_dimensions(struct ui_browser *browser)
  	 *	  changeset.
  	 */
 	ui_browser__refresh_dimensions(browser);
+	hist_browser__update_rows(hb);
 }
 
 static void hist_browser__gotorc(struct hist_browser *browser, int row, int column)
 {
-	ui_browser__gotorc(&browser->b, row, column);
+	u16 header_offset = browser->show_headers ? 1 : 0;
+
+	ui_browser__gotorc(&browser->b, row + header_offset, column);
 }
 
 static void hist_browser__reset(struct hist_browser *browser)
@@ -421,6 +440,10 @@ static int hist_browser__run(struct hist_browser *browser,
 			/* Expand the whole world. */
 			hist_browser__set_folding(browser, true);
 			break;
+		case 'H':
+			browser->show_headers = !browser->show_headers;
+			hist_browser__update_rows(browser);
+			break;
 		case K_ENTER:
 			if (hist_browser__toggle_fold(browser))
 				break;
@@ -799,6 +822,13 @@ static int hist_browser__show_entry(struct hist_browser *browser,
 	return printed;
 }
 
+static void hist_browser__show_headers(struct hist_browser *browser)
+{
+	ui_browser__gotorc(&browser->b, 0, 0);
+	ui_browser__set_color(&browser->b, HE_COLORSET_ROOT);
+	slsmg_write_nstring(" ", browser->b.width + 1);
+}
+
 static void ui_browser__hists_init_top(struct ui_browser *browser)
 {
 	if (browser->top == NULL) {
@@ -812,9 +842,15 @@ static void ui_browser__hists_init_top(struct ui_browser *browser)
 static unsigned int hist_browser__refresh(struct ui_browser *browser)
 {
 	unsigned row = 0;
+	u16 header_offset = 0;
 	struct rb_node *nd;
 	struct hist_browser *hb = container_of(browser, struct hist_browser, b);
 
+	if (hb->show_headers) {
+		hist_browser__show_headers(hb);
+		header_offset = 1;
+	}
+
 	ui_browser__hists_init_top(browser);
 
 	for (nd = browser->top; nd; nd = rb_next(nd)) {
@@ -833,7 +869,7 @@ static unsigned int hist_browser__refresh(struct ui_browser *browser)
 			break;
 	}
 
-	return row;
+	return row + header_offset;
 }
 
 static struct rb_node *hists__filter_entries(struct rb_node *nd,
@@ -1205,6 +1241,7 @@ static struct hist_browser *hist_browser__new(struct hists *hists)
 		browser->b.refresh_dimensions = hist_browser__refresh_dimensions;
 		browser->b.seek = ui_browser__hists_seek;
 		browser->b.use_navkeypressed = true;
+		browser->show_headers = false;
 	}
 
 	return browser;
@@ -1434,6 +1471,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
 	"d             Zoom into current DSO\n"				\
 	"E             Expand all callchains\n"				\
 	"F             Toggle percentage of filtered entries\n"		\
+	"H             Display column headers\n"			\
 
 	/* help messages are sorted by lexical order of the hotkey */
 	const char report_help[] = HIST_BROWSER_HELP_COMMON
Signature · 1 line
1.9.3
author maintainer
#8 lore raw

PATCH 6/16 perf hists browser: Display columns header text on 'H' press

In reply to Arnaldo Carvalho de Melo

From: Jiri Olsa <[email protected]>

Displaying columns header text whenever 'H' is pressed, and hiding it on on another press.

Cc Arnaldo Carvalho de Melo <[email protected]>
Cc Corey Ashford <[email protected]>
Cc David Ahern <[email protected]>
Cc Frederic Weisbecker <[email protected]>
Cc Ingo Molnar <[email protected]>
Cc Namhyung Kim <[email protected]>
Cc Paul Mackerras <[email protected]>
Cc Peter Zijlstra <[email protected]>
---
 tools/perf/ui/browsers/hists.c | 47 ++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 45 insertions(+), 2 deletions(-)
tools/perf/ui/browsers/hists.c +45 -2
index 2be71bf17b71..5fa2e181ef0c 100644
@@ -822,11 +822,54 @@ static int hist_browser__show_entry(struct hist_browser *browser,
 	return printed;
 }
 
+static int advance_hpp_check(struct perf_hpp *hpp, int inc)
+{
+	advance_hpp(hpp, inc);
+	return hpp->size <= 0;
+}
+
+static int hists__scnprintf_headers(char *buf, size_t size, struct hists *hists)
+{
+	struct perf_hpp dummy_hpp = {
+		.buf    = buf,
+		.size   = size,
+	};
+	struct perf_hpp_fmt *fmt;
+	size_t ret = 0;
+
+	if (symbol_conf.use_callchain) {
+		ret = scnprintf(buf, size, "  ");
+		if (advance_hpp_check(&dummy_hpp, ret))
+			return ret;
+	}
+
+	perf_hpp__for_each_format(fmt) {
+		if (perf_hpp__should_skip(fmt))
+			continue;
+
+		/* We need to add the length of the columns header. */
+		perf_hpp__reset_width(fmt, hists);
+
+		ret = fmt->header(fmt, &dummy_hpp, hists_to_evsel(hists));
+		if (advance_hpp_check(&dummy_hpp, ret))
+			break;
+
+		ret = scnprintf(dummy_hpp.buf, dummy_hpp.size, "  ");
+		if (advance_hpp_check(&dummy_hpp, ret))
+			break;
+	}
+
+	return ret;
+}
+
 static void hist_browser__show_headers(struct hist_browser *browser)
 {
+	char headers[1024];
+
+	hists__scnprintf_headers(headers, sizeof(headers), browser->hists);
 	ui_browser__gotorc(&browser->b, 0, 0);
 	ui_browser__set_color(&browser->b, HE_COLORSET_ROOT);
-	slsmg_write_nstring(" ", browser->b.width + 1);
+	slsmg_write_nstring(headers, browser->b.width + 1);
 }
 
 static void ui_browser__hists_init_top(struct ui_browser *browser)
@@ -1241,7 +1284,7 @@ static struct hist_browser *hist_browser__new(struct hists *hists)
 		browser->b.refresh_dimensions = hist_browser__refresh_dimensions;
 		browser->b.seek = ui_browser__hists_seek;
 		browser->b.use_navkeypressed = true;
-		browser->show_headers = false;
+		browser->show_headers = true;
 	}
 
 	return browser;
Signature · 1 line
1.9.3
author maintainer
#9 lore raw

PATCH 7/16 perf hists browser: Add ui.show-headers config file option

In reply to Arnaldo Carvalho de Melo

From: Jiri Olsa <[email protected]>

Adding ui.show-headers config file option to define if the histogram entries headers will start visible or not.

Currently columns headers are displayed by default, following lines in ~/.perfconfig file will disable that:

[ui]
show-headers = false

Cc Corey Ashford <[email protected]>
Cc David Ahern <[email protected]>
Cc Frederic Weisbecker <[email protected]>
Cc Ingo Molnar <[email protected]>
Cc Namhyung Kim <[email protected]>
Cc Paul Mackerras <[email protected]>
Cc Peter Zijlstra <[email protected]>
[ renamed symbol_conf.show_headers to .show_hist_headers ]
---
 tools/perf/ui/browsers/hists.c |  2 +-
 tools/perf/util/config.c       | 13 +++++++++++++
 tools/perf/util/symbol.c       |  1 +
 tools/perf/util/symbol.h       |  3 ++-
 4 files changed, 17 insertions(+), 2 deletions(-)
tools/perf/ui/browsers/hists.c +1 -1
index 5fa2e181ef0c..a94b11fc5e00 100644
@@ -1284,7 +1284,7 @@ static struct hist_browser *hist_browser__new(struct hists *hists)
 		browser->b.refresh_dimensions = hist_browser__refresh_dimensions;
 		browser->b.seek = ui_browser__hists_seek;
 		browser->b.use_navkeypressed = true;
-		browser->show_headers = true;
+		browser->show_headers = symbol_conf.show_hist_headers;
 	}
 
 	return browser;
tools/perf/util/config.c +13 -0
index 24519e14ac56..1e5e2e5af6b1 100644
@@ -350,6 +350,16 @@ static int perf_default_core_config(const char *var __maybe_unused,
 	return 0;
 }
 
+static int perf_ui_config(const char *var, const char *value)
+{
+	/* Add other config variables here. */
+	if (!strcmp(var, "ui.show-headers")) {
+		symbol_conf.show_hist_headers = perf_config_bool(var, value);
+		return 0;
+	}
+	return 0;
+}
+
 int perf_default_config(const char *var, const char *value,
 			void *dummy __maybe_unused)
 {
@@ -359,6 +369,9 @@ int perf_default_config(const char *var, const char *value,
 	if (!prefixcmp(var, "hist."))
 		return perf_hist_config(var, value);
 
+	if (!prefixcmp(var, "ui."))
+		return perf_ui_config(var, value);
+
 	/* Add other config variables here. */
 	return 0;
 }
tools/perf/util/symbol.c +1 -0
index 7b9096f29cdb..2e6a2e219eb9 100644
@@ -34,6 +34,7 @@ struct symbol_conf symbol_conf = {
 	.annotate_src		= true,
 	.demangle		= true,
 	.cumulate_callchain	= true,
+	.show_hist_headers	= true,
 	.symfs			= "",
 };
 
tools/perf/util/symbol.h +2 -1
index 615c752dd767..a81877b1dee0 100644
@@ -118,7 +118,8 @@ struct symbol_conf {
 			annotate_src,
 			event_group,
 			demangle,
-			filter_relative;
+			filter_relative,
+			show_hist_headers;
 	const char	*vmlinux_name,
 			*kallsyms_name,
 			*source_prefix,
Signature · 1 line
1.9.3
author maintainer
#10 lore raw

PATCH 8/16 perf hists browser: Left justify column headers

In reply to Arnaldo Carvalho de Melo

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

Looks better and avoids it moving to the end of the screen as the column width changes over time in 'perf top'.

Cc Adrian Hunter <[email protected]>
Cc David Ahern <[email protected]>
Cc Don Zickus <[email protected]>
Cc Frederic Weisbecker <[email protected]>
Cc Jiri Olsa <[email protected]>
Cc Mike Galbraith <[email protected]>
Cc Namhyung Kim <[email protected]>
Cc Paul Mackerras <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Stephane Eranian <[email protected]>
---
 tools/perf/util/sort.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/util/sort.c +1 -1
index 1ec57dd82284..14e5a039bc45 100644
@@ -1215,7 +1215,7 @@ static int __sort__hpp_header(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp,
 	hse = container_of(fmt, struct hpp_sort_entry, hpp);
 	len = hists__col_len(&evsel->hists, hse->se->se_width_idx);
 
-	return scnprintf(hpp->buf, hpp->size, "%*s", len, hse->se->se_header);
+	return scnprintf(hpp->buf, hpp->size, "%-*s", len, hse->se->se_header);
 }
 
 static int __sort__hpp_width(struct perf_hpp_fmt *fmt,
Signature · 1 line
1.9.3
author maintainer
#11 lore raw

PATCH 9/16 perf kvm: Introduce HAVE_KVM_STAT_SUPPORT flag

In reply to Arnaldo Carvalho de Melo

From: Alexander Yarygin <[email protected]>

kvm stat support is currently conditional on i386/x86_64. Let's abstract this into a HAVE_KVM_STAT_SUPPORT flag, so that other architectures can support kvm stat as well.

---
 tools/perf/arch/x86/Makefile | 1 +
 tools/perf/builtin-kvm.c     | 6 +++---
 tools/perf/config/Makefile   | 4 ++++
 3 files changed, 8 insertions(+), 3 deletions(-)
tools/perf/arch/x86/Makefile +1 -0
index 1641542e3636..d3939014a877 100644
@@ -15,3 +15,4 @@ endif
 LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/header.o
 LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/tsc.o
 LIB_H += arch/$(ARCH)/util/tsc.h
+HAVE_KVM_STAT_SUPPORT := 1
tools/perf/builtin-kvm.c +3 -3
index 0f1e5a2f6ad7..214ec0e7492b 100644
@@ -29,7 +29,7 @@
 #include <pthread.h>
 #include <math.h>
 
-#if defined(__i386__) || defined(__x86_64__)
+#ifdef HAVE_KVM_STAT_SUPPORT
 #include <asm/svm.h>
 #include <asm/vmx.h>
 #include <asm/kvm.h>
@@ -1609,7 +1609,7 @@ static int kvm_cmd_stat(const char *file_name, int argc, const char **argv)
 perf_stat:
 	return cmd_stat(argc, argv, NULL);
 }
-#endif
+#endif /* HAVE_KVM_STAT_SUPPORT */
 
 static int __cmd_record(const char *file_name, int argc, const char **argv)
 {
@@ -1726,7 +1726,7 @@ int cmd_kvm(int argc, const char **argv, const char *prefix __maybe_unused)
 		return cmd_top(argc, argv, NULL);
 	else if (!strncmp(argv[0], "buildid-list", 12))
 		return __cmd_buildid_list(file_name, argc, argv);
-#if defined(__i386__) || defined(__x86_64__)
+#ifdef HAVE_KVM_STAT_SUPPORT
 	else if (!strncmp(argv[0], "stat", 4))
 		return kvm_cmd_stat(file_name, argc, argv);
 #endif
tools/perf/config/Makefile +4 -0
index 346bdb617544..b7f42d577c4e 100644
@@ -594,6 +594,10 @@ ifndef NO_LIBNUMA
   endif
 endif
 
+ifdef HAVE_KVM_STAT_SUPPORT
+    CFLAGS += -DHAVE_KVM_STAT_SUPPORT
+endif
+
 # Among the variables below, these:
 #   perfexecdir
 #   template_dir
Signature · 1 line
1.9.3
author maintainer
#12 lore raw

PATCH 10/16 perf kvm: Simplify exit reasons tables definitions

In reply to Arnaldo Carvalho de Melo

From: Alexander Yarygin <[email protected]>

The perf_kvm_stat struct keeps the size of a table of exit reasons in the field 'exit_reasons_size'.

The field is initialized and then used by get_exit_reason() for serial access to the table, so that the calling function does not actually need to know table size.

Usage of tables with 'end of sequence' marker simplifies the get_exit_reason() function.

Also the patch introduces a define_exit_reasons_table, which makes it easier to define new tables.

---
 tools/perf/builtin-kvm.c | 27 ++++++++++++---------------
 1 file changed, 12 insertions(+), 15 deletions(-)
tools/perf/builtin-kvm.c +12 -15
index 214ec0e7492b..75f354459005 100644
@@ -99,7 +99,6 @@ struct perf_kvm_stat {
 	int trace_vcpu;
 
 	struct exit_reasons_table *exit_reasons;
-	int exit_reasons_size;
 	const char *exit_reasons_isa;
 
 	struct kvm_events_ops *events_ops;
@@ -158,20 +157,19 @@ static bool exit_event_end(struct perf_evsel *evsel,
 	return kvm_entry_event(evsel);
 }
 
-static struct exit_reasons_table vmx_exit_reasons[] = {
-	VMX_EXIT_REASONS
-};
+#define define_exit_reasons_table(name, symbols)	\
+	static struct exit_reasons_table name[] = {	\
+		symbols, { -1, NULL }			\
+	}
 
-static struct exit_reasons_table svm_exit_reasons[] = {
-	SVM_EXIT_REASONS
-};
+define_exit_reasons_table(vmx_exit_reasons, VMX_EXIT_REASONS);
+define_exit_reasons_table(svm_exit_reasons, SVM_EXIT_REASONS);
 
-static const char *get_exit_reason(struct perf_kvm_stat *kvm, u64 exit_code)
+static const char *get_exit_reason(struct perf_kvm_stat *kvm,
+				   struct exit_reasons_table *tbl,
+				   u64 exit_code)
 {
-	int i = kvm->exit_reasons_size;
-	struct exit_reasons_table *tbl = kvm->exit_reasons;
-
-	while (i--) {
+	while (tbl->reason != NULL) {
 		if (tbl->exit_code == exit_code)
 			return tbl->reason;
 		tbl++;
@@ -186,7 +184,8 @@ static void exit_event_decode_key(struct perf_kvm_stat *kvm,
 				  struct event_key *key,
 				  char decode[20])
 {
-	const char *exit_reason = get_exit_reason(kvm, key->key);
+	const char *exit_reason = get_exit_reason(kvm, kvm->exit_reasons,
+						  key->key);
 
 	scnprintf(decode, 20, "%s", exit_reason);
 }
@@ -862,7 +861,6 @@ static int cpu_isa_config(struct perf_kvm_stat *kvm)
 
 	if (isa == 1) {
 		kvm->exit_reasons = vmx_exit_reasons;
-		kvm->exit_reasons_size = ARRAY_SIZE(vmx_exit_reasons);
 		kvm->exit_reasons_isa = "VMX";
 	}
 
@@ -1586,7 +1584,6 @@ static int kvm_cmd_stat(const char *file_name, int argc, const char **argv)
 		.sort_key	= "sample",
 
 		.exit_reasons = svm_exit_reasons,
-		.exit_reasons_size = ARRAY_SIZE(svm_exit_reasons),
 		.exit_reasons_isa = "SVM",
 	};
 
Signature · 1 line
1.9.3
author maintainer
#13 lore raw

PATCH 11/16 perf kvm: Refactoring of cpu_isa_config()

In reply to Arnaldo Carvalho de Melo

From: Alexander Yarygin <[email protected]>

cpu_isa_config() does two different things: searching for cpuid and initializing perf_kvm_stat struct with proper parameters.

Let's move initialization to a separate function cpu_isa_init(), which is used to initialize all possible ISAs and can be used to init arch-depended things.

---
 tools/perf/builtin-kvm.c | 39 +++++++++++++++++++++++----------------
 1 file changed, 23 insertions(+), 16 deletions(-)
tools/perf/builtin-kvm.c +23 -16
index 75f354459005..41dbeaf8cc11 100644
@@ -835,36 +835,45 @@ static int process_sample_event(struct perf_tool *tool,
 	return 0;
 }
 
+static int cpu_isa_init(struct perf_kvm_stat *kvm, const char *cpuid)
+{
+	if (strstr(cpuid, "Intel")) {
+		kvm->exit_reasons = vmx_exit_reasons;
+		kvm->exit_reasons_isa = "VMX";
+	} else if (strstr(cpuid, "AMD")) {
+		kvm->exit_reasons = svm_exit_reasons;
+		kvm->exit_reasons_isa = "SVM";
+	} else
+		return -ENOTSUP;
+
+	return 0;
+}
+
 static int cpu_isa_config(struct perf_kvm_stat *kvm)
 {
 	char buf[64], *cpuid;
-	int err, isa;
+	int err;
 
 	if (kvm->live) {
 		err = get_cpuid(buf, sizeof(buf));
 		if (err != 0) {
-			pr_err("Failed to look up CPU type (Intel or AMD)\n");
+			pr_err("Failed to look up CPU type\n");
 			return err;
 		}
 		cpuid = buf;
 	} else
 		cpuid = kvm->session->header.env.cpuid;
 
-	if (strstr(cpuid, "Intel"))
-		isa = 1;
-	else if (strstr(cpuid, "AMD"))
-		isa = 0;
-	else {
-		pr_err("CPU %s is not supported.\n", cpuid);
-		return -ENOTSUP;
+	if (!cpuid) {
+		pr_err("Failed to look up CPU type\n");
+		return -EINVAL;
 	}
 
-	if (isa == 1) {
-		kvm->exit_reasons = vmx_exit_reasons;
-		kvm->exit_reasons_isa = "VMX";
-	}
+	err = cpu_isa_init(kvm, cpuid);
+	if (err == -ENOTSUP)
+		pr_err("CPU %s is not supported.\n", cpuid);
 
-	return 0;
+	return err;
 }
 
 static bool verify_vcpu(int vcpu)
@@ -1583,8 +1592,6 @@ static int kvm_cmd_stat(const char *file_name, int argc, const char **argv)
 		.report_event	= "vmexit",
 		.sort_key	= "sample",
 
-		.exit_reasons = svm_exit_reasons,
-		.exit_reasons_isa = "SVM",
 	};
 
 	if (argc == 1) {
Signature · 1 line
1.9.3
author maintainer
#14 lore raw

PATCH 12/16 perf tools: Allow to use cpuinfo on s390

In reply to Arnaldo Carvalho de Melo

From: Alexander Yarygin <[email protected]>

This patch defines CPUINFO_PROC for s390 and implements get_cpuid().

---
 tools/perf/arch/s390/Makefile      |  1 +
 tools/perf/arch/s390/util/header.c | 28 ++++++++++++++++++++++++++++
 tools/perf/perf-sys.h              |  1 +
 3 files changed, 30 insertions(+)
 create mode 100644 tools/perf/arch/s390/util/header.c
tools/perf/arch/s390/Makefile +1 -0
index 15130b50dfe3..744e629797be 100644
@@ -2,3 +2,4 @@ ifndef NO_DWARF
 PERF_HAVE_DWARF_REGS := 1
 LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/dwarf-regs.o
 endif
+LIB_OBJS += $(OUTPUT)arch/$(ARCH)/util/header.o
tools/perf/arch/s390/util/header.c new file +28 -0
new file mode 100644
index 000000000000..9fa6c3e5782c
@@ -0,0 +1,28 @@
+/*
+ * Implementation of get_cpuid().
+ *
+ * Copyright 2014 IBM Corp.
+ * Author(s): Alexander Yarygin <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License (version 2 only)
+ * as published by the Free Software Foundation.
+ */
+
+#include <sys/types.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "../../util/header.h"
+
+int get_cpuid(char *buffer, size_t sz)
+{
+	const char *cpuid = "IBM/S390";
+
+	if (strlen(cpuid) + 1 > sz)
+		return -1;
+
+	strcpy(buffer, cpuid);
+	return 0;
+}
tools/perf/perf-sys.h +1 -0
index 5268a1481d23..937e4324ad94 100644
@@ -54,6 +54,7 @@
 #define mb()		asm volatile("bcr 15,0" ::: "memory")
 #define wmb()		asm volatile("bcr 15,0" ::: "memory")
 #define rmb()		asm volatile("bcr 15,0" ::: "memory")
+#define CPUINFO_PROC	"vendor_id"
 #endif
 
 #ifdef __sh__
Signature · 1 line
1.9.3
author maintainer
#15 lore raw

PATCH 13/16 perf tools: Convert open coded equivalents to asprintf()

In reply to Arnaldo Carvalho de Melo

From: Andy Shevchenko <[email protected]>

The following snippet

	V = malloc(S);
	if (!V) { }
	sprintf(V, ...)

Can be easily changed to a one line:

	if (asprintf(&V, ...) < 0) { }
---
 tools/perf/util/trace-event-info.c | 12 +++---------
 tools/perf/util/util.c             |  9 ++-------
 2 files changed, 5 insertions(+), 16 deletions(-)
tools/perf/util/trace-event-info.c +3 -9
index 7e6fcfe8b438..c3bba883f5c3 100644
@@ -191,12 +191,10 @@ static int copy_event_system(const char *sys, struct tracepoint_path *tps)
 		    strcmp(dent->d_name, "..") == 0 ||
 		    !name_in_tp_list(dent->d_name, tps))
 			continue;
-		format = malloc(strlen(sys) + strlen(dent->d_name) + 10);
-		if (!format) {
+		if (asprintf(&format, "%s/%s/format", sys, dent->d_name) < 0) {
 			err = -ENOMEM;
 			goto out;
 		}
-		sprintf(format, "%s/%s/format", sys, dent->d_name);
 		ret = stat(format, &st);
 		free(format);
 		if (ret < 0)
@@ -217,12 +215,10 @@ static int copy_event_system(const char *sys, struct tracepoint_path *tps)
 		    strcmp(dent->d_name, "..") == 0 ||
 		    !name_in_tp_list(dent->d_name, tps))
 			continue;
-		format = malloc(strlen(sys) + strlen(dent->d_name) + 10);
-		if (!format) {
+		if (asprintf(&format, "%s/%s/format", sys, dent->d_name) < 0) {
 			err = -ENOMEM;
 			goto out;
 		}
-		sprintf(format, "%s/%s/format", sys, dent->d_name);
 		ret = stat(format, &st);
 
 		if (ret >= 0) {
@@ -317,12 +313,10 @@ static int record_event_files(struct tracepoint_path *tps)
 		    strcmp(dent->d_name, "ftrace") == 0 ||
 		    !system_in_tp_list(dent->d_name, tps))
 			continue;
-		sys = malloc(strlen(path) + strlen(dent->d_name) + 2);
-		if (!sys) {
+		if (asprintf(&sys, "%s/%s", path, dent->d_name) < 0) {
 			err = -ENOMEM;
 			goto out;
 		}
-		sprintf(sys, "%s/%s", path, dent->d_name);
 		ret = stat(sys, &st);
 		if (ret >= 0) {
 			ssize_t size = strlen(dent->d_name) + 1;
tools/perf/util/util.c +2 -7
index 95aefa78bb07..e4132aeeb780 100644
@@ -333,12 +333,9 @@ const char *find_tracing_dir(void)
 	if (!debugfs)
 		return NULL;
 
-	tracing = malloc(strlen(debugfs) + 9);
-	if (!tracing)
+	if (asprintf(&tracing, "%s/tracing", debugfs) < 0)
 		return NULL;
 
-	sprintf(tracing, "%s/tracing", debugfs);
-
 	tracing_found = 1;
 	return tracing;
 }
@@ -352,11 +349,9 @@ char *get_tracing_file(const char *name)
 	if (!tracing)
 		return NULL;
 
-	file = malloc(strlen(tracing) + strlen(name) + 2);
-	if (!file)
+	if (asprintf(&file, "%s/%s", tracing, name) < 0)
 		return NULL;
 
-	sprintf(file, "%s/%s", tracing, name);
 	return file;
 }
 
Signature · 1 line
1.9.3
author maintainer
#16 lore raw

PATCH 14/16 perf tools: Suggest using -f to override perf.data file ownership message

In reply to Arnaldo Carvalho de Melo

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

  # id
  uid=0(root) gid=0(root) groups=0(root)
  # ls -la perf.data
  -rw-------. 1 acme acme 20720 Jul  8 11:35 perf.data

Previously:

  # perf report
  file perf.data not owned by current user or root

Now:

  # perf report
  File perf.data not owned by current user or root (use -f to override)
Cc Adrian Hunter <[email protected]>
Cc David Ahern <[email protected]>
Cc Don Zickus <[email protected]>
Cc Frederic Weisbecker <[email protected]>
Cc Jiri Olsa <[email protected]>
Cc Mike Galbraith <[email protected]>
Cc Namhyung Kim <[email protected]>
Cc Paul Mackerras <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Stephane Eranian <[email protected]>
---
 tools/perf/util/data.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/util/data.c +1 -1
index 55de44ecebef..ee370a7f2444 100644
@@ -65,7 +65,7 @@ static int open_file_read(struct perf_data_file *file)
 		goto out_close;
 
 	if (!file->force && st.st_uid && (st.st_uid != geteuid())) {
-		pr_err("file %s not owned by current user or root\n",
+		pr_err("File %s not owned by current user or root (use -f to override)\n",
 		       file->path);
 		goto out_close;
 	}
Signature · 1 line
1.9.3
author maintainer
#17 lore raw

PATCH 15/16 perf trace: Add pagefault statistics

In reply to Arnaldo Carvalho de Melo

From: Stanislav Fomichev <[email protected]>

'perf trace' can show summary of events using -S option. This commit also reports number of major/minor pagefault events in this summary.

$ perf trace -s --pf all -- sleep 1

Summary of events:

sleep (18604), 275 events, 99.6%, 197 minfaults, 0.000 msec

syscall calls min avg max stddev
(msec) (msec) (msec) (%)
--------------- -------- --------- --------- --------- ------

   read                   2     0.000     0.001     0.002    100.00%
   open                   3     0.004     0.005     0.007     21.13%
   close                  3     0.001     0.001     0.001      1.37%
   fstat                  3     0.001     0.002     0.002     10.66%
   mmap                   8     0.002     0.004     0.006     10.69%
   mprotect               4     0.003     0.005     0.008     24.68%
   munmap                 1     0.005     0.005     0.005      0.00%
   brk                    3     0.001     0.002     0.003     28.08%
   access                 3     0.002     0.003     0.005     24.48%
   nanosleep              1  1000.747  1000.747  1000.747      0.00%
   execve                 8     0.000     0.033     0.246     91.00%
   arch_prctl             1     0.001     0.001     0.001      0.00%
---
 tools/perf/builtin-trace.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)
tools/perf/builtin-trace.c +17 -0
index dc7a694b61fe..b94dffc5fa85 100644
@@ -1133,6 +1133,7 @@ struct thread_trace {
 	u64		  exit_time;
 	bool		  entry_pending;
 	unsigned long	  nr_events;
+	unsigned long	  pfmaj, pfmin;
 	char		  *entry_str;
 	double		  runtime_ms;
 	struct {
@@ -1804,8 +1805,20 @@ static int trace__pgfault(struct trace *trace,
 	u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
 	struct addr_location al;
 	char map_type = 'd';
+	struct thread_trace *ttrace;
 
 	thread = machine__findnew_thread(trace->host, sample->pid, sample->tid);
+	ttrace = thread__trace(thread, trace->output);
+	if (ttrace == NULL)
+		return -1;
+
+	if (evsel->attr.config == PERF_COUNT_SW_PAGE_FAULTS_MAJ)
+		ttrace->pfmaj++;
+	else
+		ttrace->pfmin++;
+
+	if (trace->summary_only)
+		return 0;
 
 	thread__find_addr_location(thread, trace->host, cpumode, MAP__FUNCTION,
 			      sample->ip, &al);
@@ -2346,6 +2359,10 @@ static int trace__fprintf_one_thread(struct thread *thread, void *priv)
 	printed += fprintf(fp, " %s (%d), ", thread__comm_str(thread), thread->tid);
 	printed += fprintf(fp, "%lu events, ", ttrace->nr_events);
 	printed += fprintf(fp, "%.1f%%", ratio);
+	if (ttrace->pfmaj)
+		printed += fprintf(fp, ", %lu majfaults", ttrace->pfmaj);
+	if (ttrace->pfmin)
+		printed += fprintf(fp, ", %lu minfaults", ttrace->pfmin);
 	printed += fprintf(fp, ", %.3f msec\n", ttrace->runtime_ms);
 	printed += thread__dump_stats(ttrace, trace, fp);
 
Signature · 1 line
1.9.3
author maintainer
#18 lore raw

PATCH 16/16 perf trace: Fix build on 32-bit systems

In reply to Arnaldo Carvalho de Melo

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

CC /tmp/build/perf/builtin-trace.o
builtin-trace.c: In function 'print_location':
builtin-trace.c:1792:4: error: format '%lx' expects argument of type 'long unsigned int', but argument 4 has type 'u64' [-Werror=format] builtin-trace.c:1794:3: error: format '%lx' expects argument of type 'long unsigned int', but argument 3 has type 'u64' [-Werror=format] builtin-trace.c:1796:3: error: format '%lx' expects argument of type 'long unsigned int', but argument 3 has type 'u64' [-Werror=format]
cc1: all warnings being treated as errors
make[1]: *** [/tmp/build/perf/builtin-trace.o] Error 1
make[1]: *** Waiting for unfinished jobs....
make: *** [install-bin] Error 2
make: Leaving directory `/home/acme/git/linux/tools/perf'

acme@linux-goap:~/git/linux> uname -a
Linux linux-goap 3.7.10-1.16-desktop #1 SMP PREEMPT Fri May 31 20:21:23 UTC 2013 (97c14ba) i686 i686 i386 GNU/Linux

Cc Adrian Hunter <[email protected]>
Cc David Ahern <[email protected]>
Cc Don Zickus <[email protected]>
Cc Frederic Weisbecker <[email protected]>
Cc Jiri Olsa <[email protected]>
Cc Mike Galbraith <[email protected]>
Cc Namhyung Kim <[email protected]>
Cc Paul Mackerras <[email protected]>
Cc Peter Zijlstra <[email protected]>
Cc Stanislav Fomichev <[email protected]>
Cc Stephane Eranian <[email protected]>
---
 tools/perf/builtin-trace.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)
tools/perf/builtin-trace.c +3 -3
index b94dffc5fa85..c4a5a7d7b2cf 100644
@@ -1788,12 +1788,12 @@ static void print_location(FILE *f, struct perf_sample *sample,
 		fprintf(f, "%s@", al->map->dso->long_name);
 
 	if ((verbose || print_sym) && al->sym)
-		fprintf(f, "%s+0x%lx", al->sym->name,
+		fprintf(f, "%s+0x%" PRIx64, al->sym->name,
 			al->addr - al->sym->start);
 	else if (al->map)
-		fprintf(f, "0x%lx", al->addr);
+		fprintf(f, "0x%" PRIx64, al->addr);
 	else
-		fprintf(f, "0x%lx", sample->addr);
+		fprintf(f, "0x%" PRIx64, sample->addr);
 }
 
 static int trace__pgfault(struct trace *trace,
Signature · 1 line
1.9.3
#19 lore raw
In reply to Arnaldo Carvalho de Melo
Quoted 84 lines · Arnaldo Carvalho de Melo

Hi Ingo,

Please consider pulling,

- Arnaldo

The following changes since commit 8b5b584daf3b92fc5cdc83919e64231817d2f5a7:

Merge tag 'perf-core-for-mingo' of git://git.kernel.org/pub/scm/linux/kernel/git/jolsa/perf into perf/core (2014-07-05 11:29:32 +0200)

are available in the git repository at:

git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux.git tags/perf-core-for-mingo

for you to fetch changes up to 4414a3c51028aea2ae2fe06c0377490eaa6abbfd:

perf trace: Fix build on 32-bit systems (2014-07-08 15:39:21 -0300)

----------------------------------------------------------------
perf/core improvements and fixes

User visible:

o Prep patches to support 'perf kvm stat' on s390 (Alexander Yarygin)

o Add pagefault statistics in 'trace' (Stanislav Fomichev)

o Add header for columns in 'top' and 'report' TUI browsers (Jiri Olsa)

o Add pagefault statistics in 'trace' (Stanislav Fomichev)

Build fixes:

Fix build on 32-bit systems (Arnaldo Carvalho de Melo)

Cleanups:

o Convert open coded equivalents to asprintf() (Andy Shevchenko)

Plumbing:

o Allow reserving a row for header purposes in the hists browser (Arnaldo Carvalho de Melo)

----------------------------------------------------------------
Alexander Yarygin (4):
perf kvm: Introduce HAVE_KVM_STAT_SUPPORT flag perf kvm: Simplify exit reasons tables definitions perf kvm: Refactoring of cpu_isa_config() perf tools: Allow to use cpuinfo on s390

Andy Shevchenko (1):
perf tools: Convert open coded equivalents to asprintf()

Arnaldo Carvalho de Melo (8):
perf ui browser: Add ->rows to disambiguate from ->height perf ui browser: Allow overriding refresh_dimensions method perf hists browser: Introduce gotorc method
perf hists browser: Override ui_browser refresh_dimensions method perf hists browser: Add support for showing columns header perf hists browser: Left justify column headers
perf tools: Suggest using -f to override perf.data file ownership message perf trace: Fix build on 32-bit systems

Jiri Olsa (2):
perf hists browser: Display columns header text on 'H' press perf hists browser: Add ui.show-headers config file option

Stanislav Fomichev (1):
perf trace: Add pagefault statistics

 tools/perf/arch/s390/Makefile      |   1 +
 tools/perf/arch/s390/util/header.c |  28 ++++++++
 tools/perf/arch/x86/Makefile       |   1 +
 tools/perf/builtin-kvm.c           |  72 +++++++++++----------
 tools/perf/builtin-trace.c         |  23 ++++++-
 tools/perf/config/Makefile         |   4 ++
 tools/perf/perf-sys.h              |   1 +
 tools/perf/ui/browser.c            |  37 ++++++-----
 tools/perf/ui/browser.h            |   3 +-
 tools/perf/ui/browsers/hists.c     | 128 ++++++++++++++++++++++++++++++++-----
 tools/perf/util/config.c           |  13 ++++
Quoted 8 lines
 tools/perf/util/data.c             |   2 +-
 tools/perf/util/sort.c             |   2 +-
 tools/perf/util/symbol.c           |   1 +
 tools/perf/util/symbol.h           |   3 +-
 tools/perf/util/trace-event-info.c |  12 +---
 tools/perf/util/util.c             |   9 +--
 17 files changed, 249 insertions(+), 91 deletions(-)
 create mode 100644 tools/perf/arch/s390/util/header.c

Pulled, thanks a lot Arnaldo!

Ingo