linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC 00/22] perf tools: Display tracepoint enahncements
@ 2014-02-02 21:38 Jiri Olsa
  2014-02-02 21:38 ` [PATCH 01/22] perf tools: Fix memory leak in event_format__print function Jiri Olsa
                   ` (23 more replies)
  0 siblings, 24 replies; 31+ messages in thread
From: Jiri Olsa @ 2014-02-02 21:38 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Corey Ashford, Frederic Weisbecker, Ingo Molnar,
	Namhyung Kim, Paul Mackerras, Peter Zijlstra,
	Arnaldo Carvalho de Melo, Steven Rostedt, David Ahern

hi,
sending out tracepoint (mostly) events display enahncements.

* adding the '--tp' option for report command to show
  tracepoint related info. Use can specify following switches:
    fields: shows separated tracepoint fields
    format: shows tracepoints 'print fmt' in single column
             (This is default if no switch is given.)

  $ perf report --tp --no-children
  Samples: 4K of event 'sched:sched_switch', Event count (approx.): 4788
   Overhead          Command      Shared Object          Symbol  Print fmt
  +  26.27%          swapper  [kernel.kallsyms]  [k] __schedule  swapper/2:0 [120] R ==> offlineimap:22134 [120]
  +  26.27%      offlineimap  [kernel.kallsyms]  [k] __schedule  offlineimap:22134 [120] S ==> swapper/2:0 [120]
  -   8.15%          swapper  [kernel.kallsyms]  [k] __schedule  swapper/3:0 [120] R ==> offlineimap:22134 [120]
       __schedule
       schedule_preempt_disabled
       cpu_startup_entry
       start_secondary
  +   8.15%      offlineimap  [kernel.kallsyms]  [k] __schedule  offlineimap:22134 [120] S ==> swapper/3:0 [120]

  $ perf report --tp=fields --no-children
  Samples: 4K of event 'sched:sched_switch', Event count (approx.): 4788
    Overhead          Command      Shared Object          Symbol                       prev_comm    prev_pid   prev_prio          prev_state                       next_comm    next_pid   next_prio
  +   26.27%          swapper  [kernel.kallsyms]  [k] __schedule                       swapper/2           0         120                   0                     offlineimap       22134         120
  +   26.27%      offlineimap  [kernel.kallsyms]  [k] __schedule                     offlineimap       22134         120                   1                       swapper/2           0         120
  -    8.15%          swapper  [kernel.kallsyms]  [k] __schedule                       swapper/3           0         120                   0                     offlineimap       22134         120
       __schedule
       schedule_preempt_disabled
       cpu_startup_entry
       start_secondary
  +    8.15%      offlineimap  [kernel.kallsyms]  [k] __schedule                     offlineimap       22134         120                   1                       swapper/3           0         120


* adding '--list' report option to display entries sequentialy:

  Samples: 2K of event 'sched:sched_switch', Event count (approx.): 2450
        Self  Children                              Time          Command                Shared Object                                                       Symbol  Print fmt
  +    0.04%     0.04%        9582.431783 +000000.000000          swapper  [kernel.kallsyms]            [k] __schedule                                               swapper/1:0 [120] R ==> perf:11168 [120]
  -    0.00%     0.04%        9582.431783 +000000.000000          swapper  [kernel.kallsyms]            [k] __schedule                                               swapper/1:0 [120] R ==> perf:11168 [120]
       __schedule
       schedule
       cpu_idle
       start_secondary
  +    0.00%     0.04%        9582.431783 +000000.000000          swapper  [kernel.kallsyms]            [k] schedule                                                 swapper/1:0 [120] R ==> perf:11168 [120]
  +    0.00%     0.04%        9582.431783 +000000.000000          swapper  [kernel.kallsyms]            [k] cpu_idle                                                 swapper/1:0 [120] R ==> perf:11168 [120]

* adding 'H' key handler to togle header columns


thanks for comments,
jirka


Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: David Ahern <dsahern@gmail.com>
---
Jiri Olsa (22):
      perf tools: Fix memory leak in event_format__print function
      perf tools: Add time sort entry
      perf tools: Add idx sort entry
      perf tools: Add --list report option
      perf tools: Add sort_entry struct into sort entries callbacks
      perf tools: Add selected bool into se_snprintf sort entries callback
      perf tools: Implement selected bool se_snprintf callback logic
      perf tools: Implement selected logic for time sort entry
      perf tools: Factor ui_browser ops out of ui_browser struct
      perf tools: Add header callback into ui_browser_ops struct
      perf tools: Remove ev_name argument from perf_evsel__hists_browse
      perf tools: Add header callback to hist browser
      perf tools: Factor hpp_arg struct to carry hist_browser
      perf tools tui: Display columns header text on 'H' press
      tools lib traceevent: Factor print_event_fields function
      tools lib traceevent: Make the name output optional in pevent_field_info
      tools lib traceevent: Add pevent_field_cmp function
      perf tools: Factor sort entries loops
      perf tools: Add local hists sort entry list
      perf tools: Make hists col_len dynamicaly alocated
      perf tools: Add raw info into hist entry
      perf tools: Add support for tracepoint fields

 tools/lib/traceevent/event-parse.c       | 181 +++++++++++++++++++++----------
 tools/lib/traceevent/event-parse.h       |  10 ++
 tools/perf/Documentation/perf-report.txt |   6 ++
 tools/perf/Makefile.perf                 |   1 +
 tools/perf/builtin-annotate.c            |   4 +-
 tools/perf/builtin-diff.c                |   4 +-
 tools/perf/builtin-report.c              |  52 ++++++++-
 tools/perf/tests/hists_link.c            |   6 +-
 tools/perf/ui/browser.c                  | 101 ++++++++++++-----
 tools/perf/ui/browser.h                  |  31 ++++--
 tools/perf/ui/browsers/annotate.c        |  19 ++--
 tools/perf/ui/browsers/header.c          |   8 +-
 tools/perf/ui/browsers/hists.c           | 168 ++++++++++++++++++++++-------
 tools/perf/ui/browsers/map.c             |   8 +-
 tools/perf/ui/browsers/scripts.c         |   2 +-
 tools/perf/ui/gtk/hists.c                |   8 +-
 tools/perf/ui/hist.c                     |  10 +-
 tools/perf/ui/stdio/hist.c               |   6 +-
 tools/perf/ui/tui/util.c                 |   8 +-
 tools/perf/util/evsel.c                  |  24 +++--
 tools/perf/util/evsel.h                  |   6 +-
 tools/perf/util/hist.c                   |  65 ++++++++---
 tools/perf/util/hist.h                   |  20 +++-
 tools/perf/util/python.c                 |   3 +-
 tools/perf/util/report-tp.c              | 244 +++++++++++++++++++++++++++++++++++++++++
 tools/perf/util/report-tp.h              |  18 ++++
 tools/perf/util/sort.c                   | 370 +++++++++++++++++++++++++++++++++++++++++++++++++--------------
 tools/perf/util/sort.h                   |  29 ++++-
 tools/perf/util/symbol.h                 |   3 +-
 tools/perf/util/trace-event-parse.c      |   1 +
 tools/perf/util/util.h                   |  17 +++
 31 files changed, 1144 insertions(+), 289 deletions(-)
 create mode 100644 tools/perf/util/report-tp.c
 create mode 100644 tools/perf/util/report-tp.h

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH 01/22] perf tools: Fix memory leak in event_format__print function
  2014-02-02 21:38 [RFC 00/22] perf tools: Display tracepoint enahncements Jiri Olsa
@ 2014-02-02 21:38 ` Jiri Olsa
  2014-02-05  1:41   ` Namhyung Kim
  2014-02-22 17:57   ` [tip:perf/core] " tip-bot for Jiri Olsa
  2014-02-02 21:38 ` [PATCH 02/22] perf tools: Add time sort entry Jiri Olsa
                   ` (22 subsequent siblings)
  23 siblings, 2 replies; 31+ messages in thread
From: Jiri Olsa @ 2014-02-02 21:38 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Corey Ashford, Frederic Weisbecker, Ingo Molnar,
	Namhyung Kim, Paul Mackerras, Peter Zijlstra,
	Arnaldo Carvalho de Melo, Steven Rostedt, David Ahern

Properly destroying trace_seq object.

Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: David Ahern <dsahern@gmail.com>
---
 tools/perf/util/trace-event-parse.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/tools/perf/util/trace-event-parse.c b/tools/perf/util/trace-event-parse.c
index e0d6d07f..c36636f 100644
--- a/tools/perf/util/trace-event-parse.c
+++ b/tools/perf/util/trace-event-parse.c
@@ -126,6 +126,7 @@ void event_format__print(struct event_format *event,
 	trace_seq_init(&s);
 	pevent_event_info(&s, event, &record);
 	trace_seq_do_printf(&s);
+	trace_seq_destroy(&s);
 }
 
 void parse_proc_kallsyms(struct pevent *pevent,
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 02/22] perf tools: Add time sort entry
  2014-02-02 21:38 [RFC 00/22] perf tools: Display tracepoint enahncements Jiri Olsa
  2014-02-02 21:38 ` [PATCH 01/22] perf tools: Fix memory leak in event_format__print function Jiri Olsa
@ 2014-02-02 21:38 ` Jiri Olsa
  2014-02-02 21:38 ` [PATCH 03/22] perf tools: Add idx " Jiri Olsa
                   ` (21 subsequent siblings)
  23 siblings, 0 replies; 31+ messages in thread
From: Jiri Olsa @ 2014-02-02 21:38 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Corey Ashford, Frederic Weisbecker, Ingo Molnar,
	Namhyung Kim, Paul Mackerras, Peter Zijlstra,
	Arnaldo Carvalho de Melo, David Ahern

Adding time sort entry. It's mainly for displaying the
time for entries for --list display in following patch.

Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: David Ahern <dsahern@gmail.com>
---
 tools/perf/builtin-annotate.c |  2 +-
 tools/perf/builtin-diff.c     |  2 +-
 tools/perf/tests/hists_link.c |  4 ++--
 tools/perf/util/hist.c        | 15 ++++++++-----
 tools/perf/util/hist.h        |  4 +++-
 tools/perf/util/sort.c        | 52 +++++++++++++++++++++++++++++++++++++++++++
 tools/perf/util/sort.h        |  2 ++
 tools/perf/util/util.h        | 17 ++++++++++++++
 8 files changed, 87 insertions(+), 11 deletions(-)

diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index 70b2d52..875c117 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -65,7 +65,7 @@ static int perf_evsel__add_sample(struct perf_evsel *evsel,
 		return 0;
 	}
 
-	he = __hists__add_entry(&evsel->hists, al, NULL, NULL, NULL, 1, 1, 0,
+	he = __hists__add_entry(&evsel->hists, al, NULL, NULL, NULL, 1, 1, 0, 0,
 				true);
 	if (he == NULL)
 		return -ENOMEM;
diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c
index 93912ad..92faed5 100644
--- a/tools/perf/builtin-diff.c
+++ b/tools/perf/builtin-diff.c
@@ -308,7 +308,7 @@ static int hists__add_entry(struct hists *hists,
 			    u64 weight, u64 transaction)
 {
 	if (__hists__add_entry(hists, al, NULL, NULL, NULL, period, weight,
-			       transaction, true) != NULL)
+			       transaction, 0, true) != NULL)
 		return 0;
 	return -ENOMEM;
 }
diff --git a/tools/perf/tests/hists_link.c b/tools/perf/tests/hists_link.c
index e4e931e..e3bc8a8 100644
--- a/tools/perf/tests/hists_link.c
+++ b/tools/perf/tests/hists_link.c
@@ -223,7 +223,7 @@ static int add_hist_entries(struct perf_evlist *evlist, struct machine *machine)
 				goto out;
 
 			he = __hists__add_entry(&evsel->hists, &al, NULL,
-						NULL, NULL, 1, 1, 0, true);
+						NULL, NULL, 1, 1, 0, 0, true);
 			if (he == NULL)
 				goto out;
 
@@ -246,7 +246,7 @@ static int add_hist_entries(struct perf_evlist *evlist, struct machine *machine)
 				goto out;
 
 			he = __hists__add_entry(&evsel->hists, &al, NULL,
-						NULL, NULL, 1, 1, 0, true);
+						NULL, NULL, 1, 1, 0, 0, true);
 			if (he == NULL)
 				goto out;
 
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index b14fa14..cf7d7e0 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -157,6 +157,8 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h)
 	if (h->transaction)
 		hists__new_col_len(hists, HISTC_TRANSACTION,
 				   hist_entry__transaction_len());
+
+	hists__new_col_len(hists, HISTC_TIME, 32);
 }
 
 void hists__output_recalc_col_len(struct hists *hists, int max_rows)
@@ -434,7 +436,7 @@ struct hist_entry *__hists__add_entry(struct hists *hists,
 				      struct branch_info *bi,
 				      struct mem_info *mi,
 				      u64 period, u64 weight, u64 transaction,
-				      bool sample_self)
+				      u64 t, bool sample_self)
 {
 	struct hist_entry entry = {
 		.thread	= al->thread,
@@ -457,6 +459,7 @@ struct hist_entry *__hists__add_entry(struct hists *hists,
 		.branch_info = bi,
 		.mem_info = mi,
 		.transaction = transaction,
+		.time = t,
 	};
 
 	return add_hist_entry(hists, &entry, al, sample_self);
@@ -516,7 +519,7 @@ iter_add_single_mem_entry(struct hist_entry_iter *iter, struct addr_location *al
 	 * and the he_stat__add_period() function.
 	 */
 	he = __hists__add_entry(&iter->evsel->hists, al, iter->parent, NULL, mi,
-				cost, cost, 0, true);
+				cost, cost, 0, 0, true);
 	if (!he)
 		return -ENOMEM;
 
@@ -628,7 +631,7 @@ iter_add_next_branch_entry(struct hist_entry_iter *iter, struct addr_location *a
 	 * and not events sampled. Thus we use a pseudo period of 1.
 	 */
 	he = __hists__add_entry(&evsel->hists, al, iter->parent, &bi[i], NULL,
-				1, 1, 0, true);
+				1, 1, 0, 0, true);
 	if (he == NULL)
 		return -ENOMEM;
 
@@ -674,7 +677,7 @@ iter_add_single_normal_entry(struct hist_entry_iter *iter, struct addr_location
 
 	he = __hists__add_entry(&evsel->hists, al, iter->parent, NULL, NULL,
 				sample->period, sample->weight,
-				sample->transaction, true);
+				sample->transaction, sample->time, true);
 	if (he == NULL)
 		return -ENOMEM;
 
@@ -730,7 +733,7 @@ iter_add_single_cumulative_entry(struct hist_entry_iter *iter,
 
 	he = __hists__add_entry(&evsel->hists, al, iter->parent, NULL, NULL,
 				sample->period, sample->weight,
-				sample->transaction, true);
+				sample->transaction, sample->time, true);
 	if (he == NULL)
 		return -ENOMEM;
 
@@ -801,7 +804,7 @@ iter_add_next_cumulative_entry(struct hist_entry_iter *iter,
 
 	he = __hists__add_entry(&evsel->hists, al, iter->parent, NULL, NULL,
 				sample->period, sample->weight,
-				sample->transaction, false);
+				sample->transaction, sample->time, false);
 	if (he == NULL)
 		return -ENOMEM;
 
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h
index 2f52c4d..851beef 100644
--- a/tools/perf/util/hist.h
+++ b/tools/perf/util/hist.h
@@ -69,6 +69,7 @@ enum hist_column {
 	HISTC_MEM_LVL,
 	HISTC_MEM_SNOOP,
 	HISTC_TRANSACTION,
+	HISTC_TIME,
 	HISTC_NR_COLS, /* Last entry */
 };
 
@@ -87,6 +88,7 @@ struct hists {
 	const char		*symbol_filter_str;
 	pthread_mutex_t		lock;
 	struct events_stats	stats;
+	u64			time_base;
 	u64			event_stream;
 	u16			col_len[HISTC_NR_COLS];
 };
@@ -131,7 +133,7 @@ struct hist_entry *__hists__add_entry(struct hists *hists,
 				      struct branch_info *bi,
 				      struct mem_info *mi, u64 period,
 				      u64 weight, u64 transaction,
-				      bool sample_self);
+				      u64 time, bool sample_self);
 int hist_entry_iter__add(struct hist_entry_iter *iter, struct addr_location *al,
 			 struct perf_evsel *evsel, const union perf_event *event,
 			 struct perf_sample *sample, int max_stack_depth,
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
index 635cd8f..9438617 100644
--- a/tools/perf/util/sort.c
+++ b/tools/perf/util/sort.c
@@ -2,6 +2,7 @@
 #include "hist.h"
 #include "comm.h"
 #include "symbol.h"
+#include "util.h"
 
 regex_t		parent_regex;
 const char	default_parent_pattern[] = "^sys_|^do_page_fault";
@@ -54,6 +55,56 @@ static int64_t cmp_null(const void *l, const void *r)
 		return 1;
 }
 
+/* --sort time */
+
+static int64_t
+sort__time_cmp(struct hist_entry *left, struct hist_entry *right)
+{
+	return right->time - left->time;
+}
+
+static u64 get_time_base(struct hist_entry *he)
+{
+	struct hists *hists = he->hists;
+
+	if (!hists->time_base)
+		hists->time_base = he->time;
+
+	return hists->time_base;
+}
+
+static int hist_entry__time_snprintf(struct hist_entry *he, char *bf,
+				       size_t size, unsigned int width)
+{
+	char buf[100];
+	u64 time_base = get_time_base(he);
+	unsigned long time_sec, time_usec;
+	unsigned long base_sec, base_usec;
+	long delta_sec, delta_usec;
+	bool neg = (s64)(he->time - time_base) < 0;
+
+	time_sec  = nanotime_get_sec(he->time);
+	time_usec = nanotime_get_usec(he->time);
+	base_sec  = nanotime_get_sec(time_base);
+	base_usec = nanotime_get_usec(time_base);
+
+	delta_sec  = abs(time_sec - base_sec);
+	delta_usec = abs(time_usec - base_usec);
+
+	scnprintf(buf, 100, "%6lu.%06lu %s%06lu.%06lu",
+		  time_sec, time_usec,
+		  neg ? "-" : "+",
+		  delta_sec, delta_usec);
+	return repsep_snprintf(bf, size, "%*s", width, buf);
+}
+
+struct sort_entry sort_time = {
+	.se_header	= "Time",
+	.se_cmp		= sort__time_cmp,
+	.se_snprintf	= hist_entry__time_snprintf,
+	.se_width_idx	= HISTC_TIME,
+};
+
 /* --sort pid */
 
 static int64_t
@@ -996,6 +1047,7 @@ static struct sort_dimension common_sort_dimensions[] = {
 	DIM(SORT_LOCAL_WEIGHT, "local_weight", sort_local_weight),
 	DIM(SORT_GLOBAL_WEIGHT, "weight", sort_global_weight),
 	DIM(SORT_TRANSACTION, "transaction", sort_transaction),
+	DIM(SORT_TIME, "time", sort_time),
 };
 
 #undef DIM
diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h
index 103748b..4eb684e 100644
--- a/tools/perf/util/sort.h
+++ b/tools/perf/util/sort.h
@@ -88,6 +88,7 @@ struct hist_entry {
 	u64			ip;
 	u64			transaction;
 	s32			cpu;
+	u64			time;
 
 	struct hist_entry_diff	diff;
 
@@ -163,6 +164,7 @@ enum sort_type {
 	SORT_LOCAL_WEIGHT,
 	SORT_GLOBAL_WEIGHT,
 	SORT_TRANSACTION,
+	SORT_TIME,
 
 	/* branch stack specific sort keys */
 	__SORT_BRANCH_STACK,
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h
index 6995d66..881db9b 100644
--- a/tools/perf/util/util.h
+++ b/tools/perf/util/util.h
@@ -75,6 +75,9 @@
 #include <termios.h>
 #include <linux/bitops.h>
 
+#define NSECS_PER_SEC	1000000000ULL
+#define NSECS_PER_USEC	1000ULL
+
 extern const char *graph_line;
 extern const char *graph_dotted_line;
 extern char buildid_dir[];
@@ -295,6 +298,20 @@ static inline unsigned long next_pow2_l(unsigned long x)
 #endif
 }
 
+static inline unsigned long nanotime_get_sec(u64 t)
+{
+	return t / NSECS_PER_SEC;
+}
+
+static inline unsigned long nanotime_get_usec(u64 t)
+{
+	unsigned long long secs;
+
+	secs = t / NSECS_PER_SEC;
+	t -= secs * NSECS_PER_SEC;
+	return t / NSECS_PER_USEC;
+}
+
 size_t hex_width(u64 v);
 int hex2u64(const char *ptr, u64 *val);
 
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 03/22] perf tools: Add idx sort entry
  2014-02-02 21:38 [RFC 00/22] perf tools: Display tracepoint enahncements Jiri Olsa
  2014-02-02 21:38 ` [PATCH 01/22] perf tools: Fix memory leak in event_format__print function Jiri Olsa
  2014-02-02 21:38 ` [PATCH 02/22] perf tools: Add time sort entry Jiri Olsa
@ 2014-02-02 21:38 ` Jiri Olsa
  2014-02-02 21:38 ` [PATCH 04/22] perf tools: Add --list report option Jiri Olsa
                   ` (20 subsequent siblings)
  23 siblings, 0 replies; 31+ messages in thread
From: Jiri Olsa @ 2014-02-02 21:38 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Corey Ashford, Frederic Weisbecker, Ingo Molnar,
	Namhyung Kim, Paul Mackerras, Peter Zijlstra,
	Arnaldo Carvalho de Melo, David Ahern

Adding idx sort entry to have a way sort entries
the way they are stored in the data file.

Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: David Ahern <dsahern@gmail.com>
---
 tools/perf/util/hist.c |  2 ++
 tools/perf/util/hist.h |  1 +
 tools/perf/util/sort.c | 23 +++++++++++++++++++++++
 tools/perf/util/sort.h |  2 ++
 4 files changed, 28 insertions(+)

diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index cf7d7e0..2ecb976 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -438,6 +438,7 @@ struct hist_entry *__hists__add_entry(struct hists *hists,
 				      u64 period, u64 weight, u64 transaction,
 				      u64 t, bool sample_self)
 {
+	static u64 idx;
 	struct hist_entry entry = {
 		.thread	= al->thread,
 		.comm = thread__comm(al->thread),
@@ -460,6 +461,7 @@ struct hist_entry *__hists__add_entry(struct hists *hists,
 		.mem_info = mi,
 		.transaction = transaction,
 		.time = t,
+		.idx  = idx++,
 	};
 
 	return add_hist_entry(hists, &entry, al, sample_self);
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h
index 851beef..ae403a6 100644
--- a/tools/perf/util/hist.h
+++ b/tools/perf/util/hist.h
@@ -70,6 +70,7 @@ enum hist_column {
 	HISTC_MEM_SNOOP,
 	HISTC_TRANSACTION,
 	HISTC_TIME,
+	HISTC_IDX,
 	HISTC_NR_COLS, /* Last entry */
 };
 
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
index 9438617..5607edb 100644
--- a/tools/perf/util/sort.c
+++ b/tools/perf/util/sort.c
@@ -55,6 +55,28 @@ static int64_t cmp_null(const void *l, const void *r)
 		return 1;
 }
 
+/* --sort idx */
+
+static int64_t
+sort__idx_cmp(struct hist_entry *left, struct hist_entry *right)
+{
+	return right->idx - left->idx;
+}
+
+static int hist_entry__idx_snprintf(struct hist_entry *he, char *bf,
+				    size_t size, unsigned int width)
+{
+	return repsep_snprintf(bf, size, "%*lu", width, he->idx);
+}
+
+struct sort_entry sort_idx = {
+	.se_header	= "Idx",
+	.se_cmp		= sort__idx_cmp,
+	.se_snprintf	= hist_entry__idx_snprintf,
+	.se_width_idx	= HISTC_IDX,
+};
+
+
 /* --sort time */
 
 static int64_t
@@ -1048,6 +1070,7 @@ static struct sort_dimension common_sort_dimensions[] = {
 	DIM(SORT_GLOBAL_WEIGHT, "weight", sort_global_weight),
 	DIM(SORT_TRANSACTION, "transaction", sort_transaction),
 	DIM(SORT_TIME, "time", sort_time),
+	DIM(SORT_IDX, "idx", sort_idx),
 };
 
 #undef DIM
diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h
index 4eb684e..666bf0b 100644
--- a/tools/perf/util/sort.h
+++ b/tools/perf/util/sort.h
@@ -89,6 +89,7 @@ struct hist_entry {
 	u64			transaction;
 	s32			cpu;
 	u64			time;
+	u64			idx;
 
 	struct hist_entry_diff	diff;
 
@@ -165,6 +166,7 @@ enum sort_type {
 	SORT_GLOBAL_WEIGHT,
 	SORT_TRANSACTION,
 	SORT_TIME,
+	SORT_IDX,
 
 	/* branch stack specific sort keys */
 	__SORT_BRANCH_STACK,
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 04/22] perf tools: Add --list report option
  2014-02-02 21:38 [RFC 00/22] perf tools: Display tracepoint enahncements Jiri Olsa
                   ` (2 preceding siblings ...)
  2014-02-02 21:38 ` [PATCH 03/22] perf tools: Add idx " Jiri Olsa
@ 2014-02-02 21:38 ` Jiri Olsa
  2014-02-05  1:50   ` Namhyung Kim
  2014-02-02 21:38 ` [PATCH 05/22] perf tools: Add sort_entry struct into sort entries callbacks Jiri Olsa
                   ` (19 subsequent siblings)
  23 siblings, 1 reply; 31+ messages in thread
From: Jiri Olsa @ 2014-02-02 21:38 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Corey Ashford, Frederic Weisbecker, Ingo Molnar,
	Namhyung Kim, Paul Mackerras, Peter Zijlstra,
	Arnaldo Carvalho de Melo, David Ahern

Adding --list report option to display entries sequentialy:

  $ perf report --list --stdio
  ...
       0.00%       13151.543527 +000000.000000       ls  [kernel.kallsyms]  [k] native_write_msr_safe
       0.00%       13151.543530 +000000.000003       ls  [kernel.kallsyms]  [k] native_write_msr_safe
       0.00%       13151.543532 +000000.000005       ls  [kernel.kallsyms]  [k] native_write_msr_safe
       0.00%       13151.543534 +000000.000007       ls  [kernel.kallsyms]  [k] native_write_msr_safe
       0.05%       13151.543536 +000000.000009       ls  [kernel.kallsyms]  [k] native_write_msr_safe
       0.92%       13151.543538 +000000.000011       ls  [kernel.kallsyms]  [k] perf_event_comm
      14.52%       13151.543560 +000000.000033       ls  [kernel.kallsyms]  [k] uprobe_mmap
      30.10%       13151.543878 +000000.000351       ls  ld-2.17.so         [.] _dl_setup_hash
      29.30%       13151.544531 +000000.001004       ls  ls                 [.] gobble_file.constprop.49
      25.09%       13151.545613 +000000.002086       ls  [kernel.kallsyms]  [k] _cond_resched

Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: David Ahern <dsahern@gmail.com>
---
 tools/perf/builtin-report.c |  6 +++++-
 tools/perf/util/hist.c      |  3 +++
 tools/perf/util/sort.c      | 26 ++++++++++++++++++++++++++
 tools/perf/util/sort.h      |  1 +
 tools/perf/util/symbol.h    |  3 ++-
 5 files changed, 37 insertions(+), 2 deletions(-)

diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 3dbf2b8..a752687 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -731,7 +731,7 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
 	OPT_BOOLEAN(0, "source", &symbol_conf.annotate_src,
 		    "Interleave source code with assembly code (default)"),
 	OPT_BOOLEAN(0, "asm-raw", &symbol_conf.annotate_asm_raw,
-		    "Display raw encoding of assembly instructions (default)"),
+		    "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_BOOLEAN(0, "show-total-period", &symbol_conf.show_total_period,
@@ -749,6 +749,7 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
 		     "Don't show entries under that percent", parse_percent_limit),
 	OPT_CALLBACK(0, "percentage", NULL, "relative|absolute",
 		     "how to display percentage of filtered entries", parse_percentage),
+	OPT_BOOLEAN(0, "list", &symbol_conf.show_list, "Show events list"),
 	OPT_END()
 	};
 	struct perf_data_file file = {
@@ -891,6 +892,9 @@ repeat:
 
 	sort__setup_elide(stdout);
 
+	if (symbol_conf.show_list)
+		sort__setup_list();
+
 	ret = __cmd_report(&report);
 	if (ret == K_SWITCH_INPUT_DATA) {
 		perf_session__delete(session);
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index 2ecb976..43241ea 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -1073,6 +1073,9 @@ static int hist_entry__sort_on_period(struct hist_entry *a,
 	struct hist_entry *pair;
 	u64 *periods_a, *periods_b;
 
+	if (symbol_conf.show_list)
+		return b->idx - a->idx;
+
 	if (symbol_conf.cumulate_callchain) {
 		/*
 		 * Put caller above callee when they have equal period.
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
index 5607edb..4ddf934 100644
--- a/tools/perf/util/sort.c
+++ b/tools/perf/util/sort.c
@@ -1102,6 +1102,21 @@ static struct sort_dimension memory_sort_dimensions[] = {
 
 #undef DIM
 
+static void __sort_dimension__prep(struct sort_dimension *sd,
+				   enum sort_type idx)
+{
+	if (sd->taken)
+		return;
+
+	if (sd->entry->se_collapse)
+		sort__need_collapse = 1;
+
+	sort__first_dimension = idx;
+
+	list_add(&sd->entry->list, &hist_entry__sort_list);
+	sd->taken = 1;
+}
+
 static void __sort_dimension__add(struct sort_dimension *sd, enum sort_type idx)
 {
 	if (sd->taken)
@@ -1271,3 +1286,14 @@ void sort__setup_elide(FILE *output)
 	list_for_each_entry(se, &hist_entry__sort_list, list)
 		se->elide = false;
 }
+
+void sort__setup_list(void)
+{
+	struct sort_dimension *sd_idx  = &common_sort_dimensions[SORT_IDX];
+	struct sort_dimension *sd_time = &common_sort_dimensions[SORT_TIME];
+
+	__sort_dimension__prep(sd_time, SORT_TIME);
+	__sort_dimension__prep(sd_idx, SORT_IDX);
+
+	sd_idx->entry->elide = true;
+}
diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h
index 666bf0b..c2fa361 100644
--- a/tools/perf/util/sort.h
+++ b/tools/perf/util/sort.h
@@ -211,6 +211,7 @@ extern struct list_head hist_entry__sort_list;
 int setup_sorting(void);
 extern int sort_dimension__add(const char *);
 void sort__setup_elide(FILE *fp);
+void sort__setup_list(void);
 
 int report_parse_ignore_callees_opt(const struct option *opt, const char *arg, int unset);
 
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index 0657e72..423e55c 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -106,7 +106,8 @@ struct symbol_conf {
 			annotate_src,
 			event_group,
 			demangle,
-			filter_relative;
+			filter_relative,
+			show_list;
 	const char	*vmlinux_name,
 			*kallsyms_name,
 			*source_prefix,
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 05/22] perf tools: Add sort_entry struct into sort entries callbacks
  2014-02-02 21:38 [RFC 00/22] perf tools: Display tracepoint enahncements Jiri Olsa
                   ` (3 preceding siblings ...)
  2014-02-02 21:38 ` [PATCH 04/22] perf tools: Add --list report option Jiri Olsa
@ 2014-02-02 21:38 ` Jiri Olsa
  2014-02-02 21:38 ` [PATCH 06/22] perf tools: Add selected bool into se_snprintf sort entries callback Jiri Olsa
                   ` (18 subsequent siblings)
  23 siblings, 0 replies; 31+ messages in thread
From: Jiri Olsa @ 2014-02-02 21:38 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Corey Ashford, Frederic Weisbecker, Ingo Molnar,
	Namhyung Kim, Paul Mackerras, Peter Zijlstra,
	Arnaldo Carvalho de Melo, David Ahern

Adding 'struct sort_entry' to all its callback
as the first parameter. This will be usefull
for dynamic sort entries to get specific data.

Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: David Ahern <dsahern@gmail.com>
---
 tools/perf/ui/gtk/hists.c |   2 +-
 tools/perf/ui/hist.c      |   2 +-
 tools/perf/util/hist.c    |   7 +-
 tools/perf/util/sort.c    | 225 +++++++++++++++++++++++++++++-----------------
 tools/perf/util/sort.h    |  10 ++-
 5 files changed, 154 insertions(+), 92 deletions(-)

diff --git a/tools/perf/ui/gtk/hists.c b/tools/perf/ui/gtk/hists.c
index ded22b4..4a3a207 100644
--- a/tools/perf/ui/gtk/hists.c
+++ b/tools/perf/ui/gtk/hists.c
@@ -322,7 +322,7 @@ static void perf_gtk__show_hists(GtkWidget *window, struct hists *hists,
 			if (se->elide)
 				continue;
 
-			se->se_snprintf(h, s, ARRAY_SIZE(s),
+			se->se_snprintf(se, h, s, ARRAY_SIZE(s),
 					hists__col_len(hists, se->se_width_idx));
 
 			gtk_tree_store_set(store, &iter, col_idx++, s, -1);
diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c
index 1f9e252..470a1c6 100644
--- a/tools/perf/ui/hist.c
+++ b/tools/perf/ui/hist.c
@@ -310,7 +310,7 @@ int hist_entry__sort_snprintf(struct hist_entry *he, char *s, size_t size,
 			continue;
 
 		ret += scnprintf(s + ret, size - ret, "%s", sep ?: "  ");
-		ret += se->se_snprintf(he, s + ret, size - ret,
+		ret += se->se_snprintf(se, he, s + ret, size - ret,
 				       hists__col_len(hists, se->se_width_idx));
 	}
 
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index 43241ea..164d20d 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -916,7 +916,7 @@ hist_entry__cmp(struct hist_entry *left, struct hist_entry *right)
 	int64_t cmp = 0;
 
 	list_for_each_entry(se, &hist_entry__sort_list, list) {
-		cmp = se->se_cmp(left, right);
+		cmp = se->se_cmp(se, left, right);
 		if (cmp)
 			break;
 	}
@@ -931,11 +931,12 @@ hist_entry__collapse(struct hist_entry *left, struct hist_entry *right)
 	int64_t cmp = 0;
 
 	list_for_each_entry(se, &hist_entry__sort_list, list) {
-		int64_t (*f)(struct hist_entry *, struct hist_entry *);
+		int64_t (*f)(struct sort_entry *, struct hist_entry *,
+			     struct hist_entry *);
 
 		f = se->se_collapse ?: se->se_cmp;
 
-		cmp = f(left, right);
+		cmp = f(se, left, right);
 		if (cmp)
 			break;
 	}
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
index 4ddf934..823a958 100644
--- a/tools/perf/util/sort.c
+++ b/tools/perf/util/sort.c
@@ -58,12 +58,14 @@ static int64_t cmp_null(const void *l, const void *r)
 /* --sort idx */
 
 static int64_t
-sort__idx_cmp(struct hist_entry *left, struct hist_entry *right)
+sort__idx_cmp(struct sort_entry *se __maybe_unused,
+	      struct hist_entry *left, struct hist_entry *right)
 {
 	return right->idx - left->idx;
 }
 
-static int hist_entry__idx_snprintf(struct hist_entry *he, char *bf,
+static int hist_entry__idx_snprintf(struct sort_entry *se __maybe_unused,
+				    struct hist_entry *he, char *bf,
 				    size_t size, unsigned int width)
 {
 	return repsep_snprintf(bf, size, "%*lu", width, he->idx);
@@ -80,7 +82,9 @@ struct sort_entry sort_idx = {
 /* --sort time */
 
 static int64_t
-sort__time_cmp(struct hist_entry *left, struct hist_entry *right)
+sort__time_cmp(struct sort_entry *se __maybe_unused,
+	       struct hist_entry *left,
+	       struct hist_entry *right)
 {
 	return right->time - left->time;
 }
@@ -95,8 +99,9 @@ static u64 get_time_base(struct hist_entry *he)
 	return hists->time_base;
 }
 
-static int hist_entry__time_snprintf(struct hist_entry *he, char *bf,
-				       size_t size, unsigned int width)
+static int hist_entry__time_snprintf(struct sort_entry *se __maybe_unused,
+				     struct hist_entry *he, char *bf,
+				     size_t size, unsigned int width)
 {
 	char buf[100];
 	u64 time_base = get_time_base(he);
@@ -130,12 +135,14 @@ struct sort_entry sort_time = {
 /* --sort pid */
 
 static int64_t
-sort__thread_cmp(struct hist_entry *left, struct hist_entry *right)
+sort__thread_cmp(struct sort_entry *se __maybe_unused,
+		 struct hist_entry *left, struct hist_entry *right)
 {
 	return right->thread->tid - left->thread->tid;
 }
 
-static int hist_entry__thread_snprintf(struct hist_entry *he, char *bf,
+static int hist_entry__thread_snprintf(struct sort_entry *se __maybe_unused,
+				       struct hist_entry *he, char *bf,
 				       size_t size, unsigned int width)
 {
 	const char *comm = thread__comm_str(he->thread);
@@ -153,20 +160,23 @@ struct sort_entry sort_thread = {
 /* --sort comm */
 
 static int64_t
-sort__comm_cmp(struct hist_entry *left, struct hist_entry *right)
+sort__comm_cmp(struct sort_entry *se __maybe_unused,
+	       struct hist_entry *left, struct hist_entry *right)
 {
 	/* Compare the addr that should be unique among comm */
 	return comm__str(right->comm) - comm__str(left->comm);
 }
 
 static int64_t
-sort__comm_collapse(struct hist_entry *left, struct hist_entry *right)
+sort__comm_collapse(struct sort_entry *se __maybe_unused,
+		    struct hist_entry *left, struct hist_entry *right)
 {
 	/* Compare the addr that should be unique among comm */
 	return comm__str(right->comm) - comm__str(left->comm);
 }
 
-static int hist_entry__comm_snprintf(struct hist_entry *he, char *bf,
+static int hist_entry__comm_snprintf(struct sort_entry *se __maybe_unused,
+				     struct hist_entry *he, char *bf,
 				     size_t size, unsigned int width)
 {
 	return repsep_snprintf(bf, size, "%*s", width, comm__str(he->comm));
@@ -182,7 +192,8 @@ struct sort_entry sort_comm = {
 
 /* --sort dso */
 
-static int64_t _sort__dso_cmp(struct map *map_l, struct map *map_r)
+static int64_t _sort__dso_cmp(struct sort_entry *se __maybe_unused,
+			      struct map *map_l, struct map *map_r)
 {
 	struct dso *dso_l = map_l ? map_l->dso : NULL;
 	struct dso *dso_r = map_r ? map_r->dso : NULL;
@@ -203,12 +214,14 @@ static int64_t _sort__dso_cmp(struct map *map_l, struct map *map_r)
 }
 
 static int64_t
-sort__dso_cmp(struct hist_entry *left, struct hist_entry *right)
+sort__dso_cmp(struct sort_entry *se,
+	      struct hist_entry *left, struct hist_entry *right)
 {
-	return _sort__dso_cmp(left->ms.map, right->ms.map);
+	return _sort__dso_cmp(se, left->ms.map, right->ms.map);
 }
 
-static int _hist_entry__dso_snprintf(struct map *map, char *bf,
+static int _hist_entry__dso_snprintf(struct sort_entry *se __maybe_unused,
+				     struct map *map, char *bf,
 				     size_t size, unsigned int width)
 {
 	if (map && map->dso) {
@@ -220,10 +233,11 @@ static int _hist_entry__dso_snprintf(struct map *map, char *bf,
 	return repsep_snprintf(bf, size, "%-*s", width, "[unknown]");
 }
 
-static int hist_entry__dso_snprintf(struct hist_entry *he, char *bf,
+static int hist_entry__dso_snprintf(struct sort_entry *se,
+				    struct hist_entry *he, char *bf,
 				    size_t size, unsigned int width)
 {
-	return _hist_entry__dso_snprintf(he->ms.map, bf, size, width);
+	return _hist_entry__dso_snprintf(se, he->ms.map, bf, size, width);
 }
 
 struct sort_entry sort_dso = {
@@ -240,7 +254,8 @@ static int64_t _sort__addr_cmp(u64 left_ip, u64 right_ip)
 	return (int64_t)(right_ip - left_ip);
 }
 
-static int64_t _sort__sym_cmp(struct symbol *sym_l, struct symbol *sym_r)
+static int64_t _sort__sym_cmp(struct sort_entry *se __maybe_unused,
+			      struct symbol *sym_l, struct symbol *sym_r)
 {
 	u64 ip_l, ip_r;
 
@@ -257,7 +272,8 @@ static int64_t _sort__sym_cmp(struct symbol *sym_l, struct symbol *sym_r)
 }
 
 static int64_t
-sort__sym_cmp(struct hist_entry *left, struct hist_entry *right)
+sort__sym_cmp(struct sort_entry *se,
+	      struct hist_entry *left, struct hist_entry *right)
 {
 	int64_t ret;
 
@@ -269,15 +285,16 @@ sort__sym_cmp(struct hist_entry *left, struct hist_entry *right)
 	 * relative address within a dso.
 	 */
 	if (!sort__has_dso) {
-		ret = sort__dso_cmp(left, right);
+		ret = sort__dso_cmp(se, left, right);
 		if (ret != 0)
 			return ret;
 	}
 
-	return _sort__sym_cmp(left->ms.sym, right->ms.sym);
+	return _sort__sym_cmp(se, left->ms.sym, right->ms.sym);
 }
 
-static int _hist_entry__sym_snprintf(struct map *map, struct symbol *sym,
+static int _hist_entry__sym_snprintf(struct sort_entry *se __maybe_unused,
+				     struct map *map, struct symbol *sym,
 				     u64 ip, char level, char *bf, size_t size,
 				     unsigned int width)
 {
@@ -313,10 +330,11 @@ static int _hist_entry__sym_snprintf(struct map *map, struct symbol *sym,
 	return ret;
 }
 
-static int hist_entry__sym_snprintf(struct hist_entry *he, char *bf,
+static int hist_entry__sym_snprintf(struct sort_entry *se __maybe_unused,
+				    struct hist_entry *he, char *bf,
 				    size_t size, unsigned int width)
 {
-	return _hist_entry__sym_snprintf(he->ms.map, he->ms.sym, he->ip,
+	return _hist_entry__sym_snprintf(se, he->ms.map, he->ms.sym, he->ip,
 					 he->level, bf, size, width);
 }
 
@@ -330,7 +348,8 @@ struct sort_entry sort_sym = {
 /* --sort srcline */
 
 static int64_t
-sort__srcline_cmp(struct hist_entry *left, struct hist_entry *right)
+sort__srcline_cmp(struct sort_entry *se __maybe_unused,
+		  struct hist_entry *left, struct hist_entry *right)
 {
 	if (!left->srcline) {
 		if (!left->ms.map)
@@ -353,7 +372,8 @@ sort__srcline_cmp(struct hist_entry *left, struct hist_entry *right)
 	return strcmp(left->srcline, right->srcline);
 }
 
-static int hist_entry__srcline_snprintf(struct hist_entry *he, char *bf,
+static int hist_entry__srcline_snprintf(struct sort_entry *se __maybe_unused,
+					struct hist_entry *he, char *bf,
 					size_t size,
 					unsigned int width __maybe_unused)
 {
@@ -370,7 +390,8 @@ struct sort_entry sort_srcline = {
 /* --sort parent */
 
 static int64_t
-sort__parent_cmp(struct hist_entry *left, struct hist_entry *right)
+sort__parent_cmp(struct sort_entry *se __maybe_unused,
+		 struct hist_entry *left, struct hist_entry *right)
 {
 	struct symbol *sym_l = left->parent;
 	struct symbol *sym_r = right->parent;
@@ -381,7 +402,8 @@ sort__parent_cmp(struct hist_entry *left, struct hist_entry *right)
 	return strcmp(sym_l->name, sym_r->name);
 }
 
-static int hist_entry__parent_snprintf(struct hist_entry *he, char *bf,
+static int hist_entry__parent_snprintf(struct sort_entry *se __maybe_unused,
+				       struct hist_entry *he, char *bf,
 				       size_t size, unsigned int width)
 {
 	return repsep_snprintf(bf, size, "%-*s", width,
@@ -398,12 +420,14 @@ struct sort_entry sort_parent = {
 /* --sort cpu */
 
 static int64_t
-sort__cpu_cmp(struct hist_entry *left, struct hist_entry *right)
+sort__cpu_cmp(struct sort_entry *se __maybe_unused,
+	      struct hist_entry *left, struct hist_entry *right)
 {
 	return right->cpu - left->cpu;
 }
 
-static int hist_entry__cpu_snprintf(struct hist_entry *he, char *bf,
+static int hist_entry__cpu_snprintf(struct sort_entry *se __maybe_unused,
+				    struct hist_entry *he, char *bf,
 				    size_t size, unsigned int width)
 {
 	return repsep_snprintf(bf, size, "%*d", width, he->cpu);
@@ -419,35 +443,40 @@ struct sort_entry sort_cpu = {
 /* sort keys for branch stacks */
 
 static int64_t
-sort__dso_from_cmp(struct hist_entry *left, struct hist_entry *right)
+sort__dso_from_cmp(struct sort_entry *se,
+		   struct hist_entry *left, struct hist_entry *right)
 {
-	return _sort__dso_cmp(left->branch_info->from.map,
+	return _sort__dso_cmp(se, left->branch_info->from.map,
 			      right->branch_info->from.map);
 }
 
-static int hist_entry__dso_from_snprintf(struct hist_entry *he, char *bf,
+static int hist_entry__dso_from_snprintf(struct sort_entry *se,
+					 struct hist_entry *he, char *bf,
 				    size_t size, unsigned int width)
 {
-	return _hist_entry__dso_snprintf(he->branch_info->from.map,
+	return _hist_entry__dso_snprintf(se, he->branch_info->from.map,
 					 bf, size, width);
 }
 
 static int64_t
-sort__dso_to_cmp(struct hist_entry *left, struct hist_entry *right)
+sort__dso_to_cmp(struct sort_entry *se,
+		 struct hist_entry *left, struct hist_entry *right)
 {
-	return _sort__dso_cmp(left->branch_info->to.map,
+	return _sort__dso_cmp(se, left->branch_info->to.map,
 			      right->branch_info->to.map);
 }
 
-static int hist_entry__dso_to_snprintf(struct hist_entry *he, char *bf,
+static int hist_entry__dso_to_snprintf(struct sort_entry *se __maybe_unused,
+				       struct hist_entry *he, char *bf,
 				       size_t size, unsigned int width)
 {
-	return _hist_entry__dso_snprintf(he->branch_info->to.map,
+	return _hist_entry__dso_snprintf(se, he->branch_info->to.map,
 					 bf, size, width);
 }
 
 static int64_t
-sort__sym_from_cmp(struct hist_entry *left, struct hist_entry *right)
+sort__sym_from_cmp(struct sort_entry *se,
+		   struct hist_entry *left, struct hist_entry *right)
 {
 	struct addr_map_symbol *from_l = &left->branch_info->from;
 	struct addr_map_symbol *from_r = &right->branch_info->from;
@@ -455,11 +484,12 @@ sort__sym_from_cmp(struct hist_entry *left, struct hist_entry *right)
 	if (!from_l->sym && !from_r->sym)
 		return _sort__addr_cmp(from_l->addr, from_r->addr);
 
-	return _sort__sym_cmp(from_l->sym, from_r->sym);
+	return _sort__sym_cmp(se, from_l->sym, from_r->sym);
 }
 
 static int64_t
-sort__sym_to_cmp(struct hist_entry *left, struct hist_entry *right)
+sort__sym_to_cmp(struct sort_entry *se,
+		 struct hist_entry *left, struct hist_entry *right)
 {
 	struct addr_map_symbol *to_l = &left->branch_info->to;
 	struct addr_map_symbol *to_r = &right->branch_info->to;
@@ -467,23 +497,25 @@ sort__sym_to_cmp(struct hist_entry *left, struct hist_entry *right)
 	if (!to_l->sym && !to_r->sym)
 		return _sort__addr_cmp(to_l->addr, to_r->addr);
 
-	return _sort__sym_cmp(to_l->sym, to_r->sym);
+	return _sort__sym_cmp(se, to_l->sym, to_r->sym);
 }
 
-static int hist_entry__sym_from_snprintf(struct hist_entry *he, char *bf,
+static int hist_entry__sym_from_snprintf(struct sort_entry *se,
+					 struct hist_entry *he, char *bf,
 					 size_t size, unsigned int width)
 {
 	struct addr_map_symbol *from = &he->branch_info->from;
-	return _hist_entry__sym_snprintf(from->map, from->sym, from->addr,
+	return _hist_entry__sym_snprintf(se, from->map, from->sym, from->addr,
 					 he->level, bf, size, width);
 
 }
 
-static int hist_entry__sym_to_snprintf(struct hist_entry *he, char *bf,
+static int hist_entry__sym_to_snprintf(struct sort_entry *se __maybe_unused,
+				       struct hist_entry *he, char *bf,
 				       size_t size, unsigned int width)
 {
 	struct addr_map_symbol *to = &he->branch_info->to;
-	return _hist_entry__sym_snprintf(to->map, to->sym, to->addr,
+	return _hist_entry__sym_snprintf(se, to->map, to->sym, to->addr,
 					 he->level, bf, size, width);
 
 }
@@ -517,7 +549,8 @@ struct sort_entry sort_sym_to = {
 };
 
 static int64_t
-sort__mispredict_cmp(struct hist_entry *left, struct hist_entry *right)
+sort__mispredict_cmp(struct sort_entry *se __maybe_unused,
+		     struct hist_entry *left, struct hist_entry *right)
 {
 	const unsigned char mp = left->branch_info->flags.mispred !=
 					right->branch_info->flags.mispred;
@@ -527,8 +560,9 @@ sort__mispredict_cmp(struct hist_entry *left, struct hist_entry *right)
 	return mp || p;
 }
 
-static int hist_entry__mispredict_snprintf(struct hist_entry *he, char *bf,
-				    size_t size, unsigned int width){
+static int hist_entry__mispredict_snprintf(struct sort_entry *se __maybe_unused,
+					   struct hist_entry *he, char *bf,
+					   size_t size, unsigned int width){
 	static const char *out = "N/A";
 
 	if (he->branch_info->flags.predicted)
@@ -541,7 +575,8 @@ static int hist_entry__mispredict_snprintf(struct hist_entry *he, char *bf,
 
 /* --sort daddr_sym */
 static int64_t
-sort__daddr_cmp(struct hist_entry *left, struct hist_entry *right)
+sort__daddr_cmp(struct sort_entry *se __maybe_unused,
+		struct hist_entry *left, struct hist_entry *right)
 {
 	uint64_t l = 0, r = 0;
 
@@ -553,8 +588,9 @@ sort__daddr_cmp(struct hist_entry *left, struct hist_entry *right)
 	return (int64_t)(r - l);
 }
 
-static int hist_entry__daddr_snprintf(struct hist_entry *he, char *bf,
-				    size_t size, unsigned int width)
+static int hist_entry__daddr_snprintf(struct sort_entry *se,
+				      struct hist_entry *he, char *bf,
+				      size_t size, unsigned int width)
 {
 	uint64_t addr = 0;
 	struct map *map = NULL;
@@ -565,12 +601,13 @@ static int hist_entry__daddr_snprintf(struct hist_entry *he, char *bf,
 		map = he->mem_info->daddr.map;
 		sym = he->mem_info->daddr.sym;
 	}
-	return _hist_entry__sym_snprintf(map, sym, addr, he->level, bf, size,
-					 width);
+	return _hist_entry__sym_snprintf(se, map, sym, addr, he->level, bf,
+					 size, width);
 }
 
 static int64_t
-sort__dso_daddr_cmp(struct hist_entry *left, struct hist_entry *right)
+sort__dso_daddr_cmp(struct sort_entry *se __maybe_unused,
+		    struct hist_entry *left, struct hist_entry *right)
 {
 	struct map *map_l = NULL;
 	struct map *map_r = NULL;
@@ -580,22 +617,24 @@ sort__dso_daddr_cmp(struct hist_entry *left, struct hist_entry *right)
 	if (right->mem_info)
 		map_r = right->mem_info->daddr.map;
 
-	return _sort__dso_cmp(map_l, map_r);
+	return _sort__dso_cmp(se, map_l, map_r);
 }
 
-static int hist_entry__dso_daddr_snprintf(struct hist_entry *he, char *bf,
-				    size_t size, unsigned int width)
+static int hist_entry__dso_daddr_snprintf(struct sort_entry *se,
+					  struct hist_entry *he, char *bf,
+					  size_t size, unsigned int width)
 {
 	struct map *map = NULL;
 
 	if (he->mem_info)
 		map = he->mem_info->daddr.map;
 
-	return _hist_entry__dso_snprintf(map, bf, size, width);
+	return _hist_entry__dso_snprintf(se, map, bf, size, width);
 }
 
 static int64_t
-sort__locked_cmp(struct hist_entry *left, struct hist_entry *right)
+sort__locked_cmp(struct sort_entry *se __maybe_unused,
+		 struct hist_entry *left, struct hist_entry *right)
 {
 	union perf_mem_data_src data_src_l;
 	union perf_mem_data_src data_src_r;
@@ -613,8 +652,9 @@ sort__locked_cmp(struct hist_entry *left, struct hist_entry *right)
 	return (int64_t)(data_src_r.mem_lock - data_src_l.mem_lock);
 }
 
-static int hist_entry__locked_snprintf(struct hist_entry *he, char *bf,
-				    size_t size, unsigned int width)
+static int hist_entry__locked_snprintf(struct sort_entry *se __maybe_unused,
+				       struct hist_entry *he, char *bf,
+				       size_t size, unsigned int width)
 {
 	const char *out;
 	u64 mask = PERF_MEM_LOCK_NA;
@@ -633,7 +673,8 @@ static int hist_entry__locked_snprintf(struct hist_entry *he, char *bf,
 }
 
 static int64_t
-sort__tlb_cmp(struct hist_entry *left, struct hist_entry *right)
+sort__tlb_cmp(struct sort_entry *se __maybe_unused,
+	      struct hist_entry *left, struct hist_entry *right)
 {
 	union perf_mem_data_src data_src_l;
 	union perf_mem_data_src data_src_r;
@@ -662,7 +703,8 @@ static const char * const tlb_access[] = {
 };
 #define NUM_TLB_ACCESS (sizeof(tlb_access)/sizeof(const char *))
 
-static int hist_entry__tlb_snprintf(struct hist_entry *he, char *bf,
+static int hist_entry__tlb_snprintf(struct sort_entry *se __maybe_unused,
+				    struct hist_entry *he, char *bf,
 				    size_t size, unsigned int width)
 {
 	char out[64];
@@ -703,7 +745,8 @@ static int hist_entry__tlb_snprintf(struct hist_entry *he, char *bf,
 }
 
 static int64_t
-sort__lvl_cmp(struct hist_entry *left, struct hist_entry *right)
+sort__lvl_cmp(struct sort_entry *se __maybe_unused,
+	      struct hist_entry *left, struct hist_entry *right)
 {
 	union perf_mem_data_src data_src_l;
 	union perf_mem_data_src data_src_r;
@@ -739,7 +782,8 @@ static const char * const mem_lvl[] = {
 };
 #define NUM_MEM_LVL (sizeof(mem_lvl)/sizeof(const char *))
 
-static int hist_entry__lvl_snprintf(struct hist_entry *he, char *bf,
+static int hist_entry__lvl_snprintf(struct sort_entry *se __maybe_unused,
+				    struct hist_entry *he, char *bf,
 				    size_t size, unsigned int width)
 {
 	char out[64];
@@ -780,7 +824,8 @@ static int hist_entry__lvl_snprintf(struct hist_entry *he, char *bf,
 }
 
 static int64_t
-sort__snoop_cmp(struct hist_entry *left, struct hist_entry *right)
+sort__snoop_cmp(struct sort_entry *se __maybe_unused,
+		struct hist_entry *left, struct hist_entry *right)
 {
 	union perf_mem_data_src data_src_l;
 	union perf_mem_data_src data_src_r;
@@ -807,8 +852,9 @@ static const char * const snoop_access[] = {
 };
 #define NUM_SNOOP_ACCESS (sizeof(snoop_access)/sizeof(const char *))
 
-static int hist_entry__snoop_snprintf(struct hist_entry *he, char *bf,
-				    size_t size, unsigned int width)
+static int hist_entry__snoop_snprintf(struct sort_entry *se __maybe_unused,
+				      struct hist_entry *he, char *bf,
+				      size_t size, unsigned int width)
 {
 	char out[64];
 	size_t sz = sizeof(out) - 1; /* -1 for null termination */
@@ -850,13 +896,16 @@ static u64 he_weight(struct hist_entry *he)
 }
 
 static int64_t
-sort__local_weight_cmp(struct hist_entry *left, struct hist_entry *right)
+sort__local_weight_cmp(struct sort_entry *se __maybe_unused,
+		       struct hist_entry *left, struct hist_entry *right)
 {
 	return he_weight(left) - he_weight(right);
 }
 
-static int hist_entry__local_weight_snprintf(struct hist_entry *he, char *bf,
-				    size_t size, unsigned int width)
+static int
+hist_entry__local_weight_snprintf(struct sort_entry *se __maybe_unused,
+				  struct hist_entry *he, char *bf,
+				  size_t size, unsigned int width)
 {
 	return repsep_snprintf(bf, size, "%-*llu", width, he_weight(he));
 }
@@ -869,13 +918,16 @@ struct sort_entry sort_local_weight = {
 };
 
 static int64_t
-sort__global_weight_cmp(struct hist_entry *left, struct hist_entry *right)
+sort__global_weight_cmp(struct sort_entry *se __maybe_unused,
+			struct hist_entry *left, struct hist_entry *right)
 {
 	return left->stat.weight - right->stat.weight;
 }
 
-static int hist_entry__global_weight_snprintf(struct hist_entry *he, char *bf,
-					      size_t size, unsigned int width)
+static int
+hist_entry__global_weight_snprintf(struct sort_entry *se __maybe_unused,
+				   struct hist_entry *he, char *bf,
+				   size_t size, unsigned int width)
 {
 	return repsep_snprintf(bf, size, "%-*llu", width, he->stat.weight);
 }
@@ -930,14 +982,16 @@ struct sort_entry sort_mem_snoop = {
 };
 
 static int64_t
-sort__abort_cmp(struct hist_entry *left, struct hist_entry *right)
+sort__abort_cmp(struct sort_entry *se __maybe_unused,
+		struct hist_entry *left, struct hist_entry *right)
 {
 	return left->branch_info->flags.abort !=
 		right->branch_info->flags.abort;
 }
 
-static int hist_entry__abort_snprintf(struct hist_entry *he, char *bf,
-				    size_t size, unsigned int width)
+static int hist_entry__abort_snprintf(struct sort_entry *se __maybe_unused,
+				      struct hist_entry *he, char *bf,
+				      size_t size, unsigned int width)
 {
 	static const char *out = ".";
 
@@ -954,14 +1008,16 @@ struct sort_entry sort_abort = {
 };
 
 static int64_t
-sort__in_tx_cmp(struct hist_entry *left, struct hist_entry *right)
+sort__in_tx_cmp(struct sort_entry *se __maybe_unused,
+		struct hist_entry *left, struct hist_entry *right)
 {
 	return left->branch_info->flags.in_tx !=
 		right->branch_info->flags.in_tx;
 }
 
-static int hist_entry__in_tx_snprintf(struct hist_entry *he, char *bf,
-				    size_t size, unsigned int width)
+static int hist_entry__in_tx_snprintf(struct sort_entry *se __maybe_unused,
+				      struct hist_entry *he, char *bf,
+				      size_t size, unsigned int width)
 {
 	static const char *out = ".";
 
@@ -979,7 +1035,8 @@ struct sort_entry sort_in_tx = {
 };
 
 static int64_t
-sort__transaction_cmp(struct hist_entry *left, struct hist_entry *right)
+sort__transaction_cmp(struct sort_entry *se __maybe_unused,
+		      struct hist_entry *left, struct hist_entry *right)
 {
 	return left->transaction - right->transaction;
 }
@@ -1019,8 +1076,10 @@ int hist_entry__transaction_len(void)
 	return len;
 }
 
-static int hist_entry__transaction_snprintf(struct hist_entry *he, char *bf,
-					    size_t size, unsigned int width)
+static int
+hist_entry__transaction_snprintf(struct sort_entry *se __maybe_unused,
+				 struct hist_entry *he, char *bf,
+				 size_t size, unsigned int width)
 {
 	u64 t = he->transaction;
 	char buf[128];
diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h
index c2fa361..1dffebc 100644
--- a/tools/perf/util/sort.h
+++ b/tools/perf/util/sort.h
@@ -197,10 +197,12 @@ struct sort_entry {
 
 	const char *se_header;
 
-	int64_t (*se_cmp)(struct hist_entry *, struct hist_entry *);
-	int64_t (*se_collapse)(struct hist_entry *, struct hist_entry *);
-	int	(*se_snprintf)(struct hist_entry *he, char *bf, size_t size,
-			       unsigned int width);
+	int64_t (*se_cmp)(struct sort_entry *, struct hist_entry *,
+			  struct hist_entry *);
+	int64_t (*se_collapse)(struct sort_entry *, struct hist_entry *,
+			       struct hist_entry *);
+	int	(*se_snprintf)(struct sort_entry *, struct hist_entry *he,
+			       char *bf, size_t size, unsigned int width);
 	u8	se_width_idx;
 	bool	elide;
 };
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 06/22] perf tools: Add selected bool into se_snprintf sort entries callback
  2014-02-02 21:38 [RFC 00/22] perf tools: Display tracepoint enahncements Jiri Olsa
                   ` (4 preceding siblings ...)
  2014-02-02 21:38 ` [PATCH 05/22] perf tools: Add sort_entry struct into sort entries callbacks Jiri Olsa
@ 2014-02-02 21:38 ` Jiri Olsa
  2014-02-02 21:38 ` [PATCH 07/22] perf tools: Implement selected bool se_snprintf callback logic Jiri Olsa
                   ` (17 subsequent siblings)
  23 siblings, 0 replies; 31+ messages in thread
From: Jiri Olsa @ 2014-02-02 21:38 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Corey Ashford, Frederic Weisbecker, Ingo Molnar,
	Namhyung Kim, Paul Mackerras, Peter Zijlstra,
	Arnaldo Carvalho de Melo, David Ahern

Adding selected bool into se_snprintf sort entries callback,
so we could display selected field differently. This is
going to be used for 'Time' column in following patch.

Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: David Ahern <dsahern@gmail.com>
---
 tools/perf/ui/gtk/hists.c |  2 +-
 tools/perf/ui/hist.c      |  2 +-
 tools/perf/util/sort.c    | 27 ++++++++++++++++++++++++++-
 tools/perf/util/sort.h    |  3 ++-
 4 files changed, 30 insertions(+), 4 deletions(-)

diff --git a/tools/perf/ui/gtk/hists.c b/tools/perf/ui/gtk/hists.c
index 4a3a207..bd9a491 100644
--- a/tools/perf/ui/gtk/hists.c
+++ b/tools/perf/ui/gtk/hists.c
@@ -322,7 +322,7 @@ static void perf_gtk__show_hists(GtkWidget *window, struct hists *hists,
 			if (se->elide)
 				continue;
 
-			se->se_snprintf(se, h, s, ARRAY_SIZE(s),
+			se->se_snprintf(se, false, h, s, ARRAY_SIZE(s),
 					hists__col_len(hists, se->se_width_idx));
 
 			gtk_tree_store_set(store, &iter, col_idx++, s, -1);
diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c
index 470a1c6..75a8ea6 100644
--- a/tools/perf/ui/hist.c
+++ b/tools/perf/ui/hist.c
@@ -310,7 +310,7 @@ int hist_entry__sort_snprintf(struct hist_entry *he, char *s, size_t size,
 			continue;
 
 		ret += scnprintf(s + ret, size - ret, "%s", sep ?: "  ");
-		ret += se->se_snprintf(se, he, s + ret, size - ret,
+		ret += se->se_snprintf(se, false, he, s + ret, size - ret,
 				       hists__col_len(hists, se->se_width_idx));
 	}
 
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
index 823a958..b219eaf 100644
--- a/tools/perf/util/sort.c
+++ b/tools/perf/util/sort.c
@@ -65,6 +65,7 @@ sort__idx_cmp(struct sort_entry *se __maybe_unused,
 }
 
 static int hist_entry__idx_snprintf(struct sort_entry *se __maybe_unused,
+				    bool selected __maybe_unused,
 				    struct hist_entry *he, char *bf,
 				    size_t size, unsigned int width)
 {
@@ -100,6 +101,7 @@ static u64 get_time_base(struct hist_entry *he)
 }
 
 static int hist_entry__time_snprintf(struct sort_entry *se __maybe_unused,
+				     bool selected __maybe_unused,
 				     struct hist_entry *he, char *bf,
 				     size_t size, unsigned int width)
 {
@@ -142,6 +144,7 @@ sort__thread_cmp(struct sort_entry *se __maybe_unused,
 }
 
 static int hist_entry__thread_snprintf(struct sort_entry *se __maybe_unused,
+				       bool selected __maybe_unused,
 				       struct hist_entry *he, char *bf,
 				       size_t size, unsigned int width)
 {
@@ -176,6 +179,7 @@ sort__comm_collapse(struct sort_entry *se __maybe_unused,
 }
 
 static int hist_entry__comm_snprintf(struct sort_entry *se __maybe_unused,
+				     bool selected __maybe_unused,
 				     struct hist_entry *he, char *bf,
 				     size_t size, unsigned int width)
 {
@@ -234,6 +238,7 @@ static int _hist_entry__dso_snprintf(struct sort_entry *se __maybe_unused,
 }
 
 static int hist_entry__dso_snprintf(struct sort_entry *se,
+				    bool selected __maybe_unused,
 				    struct hist_entry *he, char *bf,
 				    size_t size, unsigned int width)
 {
@@ -331,6 +336,7 @@ static int _hist_entry__sym_snprintf(struct sort_entry *se __maybe_unused,
 }
 
 static int hist_entry__sym_snprintf(struct sort_entry *se __maybe_unused,
+				    bool selected __maybe_unused,
 				    struct hist_entry *he, char *bf,
 				    size_t size, unsigned int width)
 {
@@ -373,6 +379,7 @@ sort__srcline_cmp(struct sort_entry *se __maybe_unused,
 }
 
 static int hist_entry__srcline_snprintf(struct sort_entry *se __maybe_unused,
+					bool selected __maybe_unused,
 					struct hist_entry *he, char *bf,
 					size_t size,
 					unsigned int width __maybe_unused)
@@ -403,6 +410,7 @@ sort__parent_cmp(struct sort_entry *se __maybe_unused,
 }
 
 static int hist_entry__parent_snprintf(struct sort_entry *se __maybe_unused,
+				       bool selected __maybe_unused,
 				       struct hist_entry *he, char *bf,
 				       size_t size, unsigned int width)
 {
@@ -427,6 +435,7 @@ sort__cpu_cmp(struct sort_entry *se __maybe_unused,
 }
 
 static int hist_entry__cpu_snprintf(struct sort_entry *se __maybe_unused,
+				    bool selected __maybe_unused,
 				    struct hist_entry *he, char *bf,
 				    size_t size, unsigned int width)
 {
@@ -451,8 +460,9 @@ sort__dso_from_cmp(struct sort_entry *se,
 }
 
 static int hist_entry__dso_from_snprintf(struct sort_entry *se,
+					 bool selected __maybe_unused,
 					 struct hist_entry *he, char *bf,
-				    size_t size, unsigned int width)
+					 size_t size, unsigned int width)
 {
 	return _hist_entry__dso_snprintf(se, he->branch_info->from.map,
 					 bf, size, width);
@@ -467,6 +477,7 @@ sort__dso_to_cmp(struct sort_entry *se,
 }
 
 static int hist_entry__dso_to_snprintf(struct sort_entry *se __maybe_unused,
+				       bool selected __maybe_unused,
 				       struct hist_entry *he, char *bf,
 				       size_t size, unsigned int width)
 {
@@ -501,6 +512,7 @@ sort__sym_to_cmp(struct sort_entry *se,
 }
 
 static int hist_entry__sym_from_snprintf(struct sort_entry *se,
+					 bool selected __maybe_unused,
 					 struct hist_entry *he, char *bf,
 					 size_t size, unsigned int width)
 {
@@ -511,6 +523,7 @@ static int hist_entry__sym_from_snprintf(struct sort_entry *se,
 }
 
 static int hist_entry__sym_to_snprintf(struct sort_entry *se __maybe_unused,
+				       bool selected __maybe_unused,
 				       struct hist_entry *he, char *bf,
 				       size_t size, unsigned int width)
 {
@@ -561,6 +574,7 @@ sort__mispredict_cmp(struct sort_entry *se __maybe_unused,
 }
 
 static int hist_entry__mispredict_snprintf(struct sort_entry *se __maybe_unused,
+					   bool selected __maybe_unused,
 					   struct hist_entry *he, char *bf,
 					   size_t size, unsigned int width){
 	static const char *out = "N/A";
@@ -589,6 +603,7 @@ sort__daddr_cmp(struct sort_entry *se __maybe_unused,
 }
 
 static int hist_entry__daddr_snprintf(struct sort_entry *se,
+				      bool selected __maybe_unused,
 				      struct hist_entry *he, char *bf,
 				      size_t size, unsigned int width)
 {
@@ -621,6 +636,7 @@ sort__dso_daddr_cmp(struct sort_entry *se __maybe_unused,
 }
 
 static int hist_entry__dso_daddr_snprintf(struct sort_entry *se,
+					  bool selected __maybe_unused,
 					  struct hist_entry *he, char *bf,
 					  size_t size, unsigned int width)
 {
@@ -653,6 +669,7 @@ sort__locked_cmp(struct sort_entry *se __maybe_unused,
 }
 
 static int hist_entry__locked_snprintf(struct sort_entry *se __maybe_unused,
+				       bool selected __maybe_unused,
 				       struct hist_entry *he, char *bf,
 				       size_t size, unsigned int width)
 {
@@ -704,6 +721,7 @@ static const char * const tlb_access[] = {
 #define NUM_TLB_ACCESS (sizeof(tlb_access)/sizeof(const char *))
 
 static int hist_entry__tlb_snprintf(struct sort_entry *se __maybe_unused,
+				    bool selected __maybe_unused,
 				    struct hist_entry *he, char *bf,
 				    size_t size, unsigned int width)
 {
@@ -783,6 +801,7 @@ static const char * const mem_lvl[] = {
 #define NUM_MEM_LVL (sizeof(mem_lvl)/sizeof(const char *))
 
 static int hist_entry__lvl_snprintf(struct sort_entry *se __maybe_unused,
+				    bool selected __maybe_unused,
 				    struct hist_entry *he, char *bf,
 				    size_t size, unsigned int width)
 {
@@ -853,6 +872,7 @@ static const char * const snoop_access[] = {
 #define NUM_SNOOP_ACCESS (sizeof(snoop_access)/sizeof(const char *))
 
 static int hist_entry__snoop_snprintf(struct sort_entry *se __maybe_unused,
+				      bool selected __maybe_unused,
 				      struct hist_entry *he, char *bf,
 				      size_t size, unsigned int width)
 {
@@ -904,6 +924,7 @@ sort__local_weight_cmp(struct sort_entry *se __maybe_unused,
 
 static int
 hist_entry__local_weight_snprintf(struct sort_entry *se __maybe_unused,
+				  bool selected __maybe_unused,
 				  struct hist_entry *he, char *bf,
 				  size_t size, unsigned int width)
 {
@@ -926,6 +947,7 @@ sort__global_weight_cmp(struct sort_entry *se __maybe_unused,
 
 static int
 hist_entry__global_weight_snprintf(struct sort_entry *se __maybe_unused,
+				   bool selected __maybe_unused,
 				   struct hist_entry *he, char *bf,
 				   size_t size, unsigned int width)
 {
@@ -990,6 +1012,7 @@ sort__abort_cmp(struct sort_entry *se __maybe_unused,
 }
 
 static int hist_entry__abort_snprintf(struct sort_entry *se __maybe_unused,
+				      bool selected __maybe_unused,
 				      struct hist_entry *he, char *bf,
 				      size_t size, unsigned int width)
 {
@@ -1016,6 +1039,7 @@ sort__in_tx_cmp(struct sort_entry *se __maybe_unused,
 }
 
 static int hist_entry__in_tx_snprintf(struct sort_entry *se __maybe_unused,
+				      bool selected __maybe_unused,
 				      struct hist_entry *he, char *bf,
 				      size_t size, unsigned int width)
 {
@@ -1078,6 +1102,7 @@ int hist_entry__transaction_len(void)
 
 static int
 hist_entry__transaction_snprintf(struct sort_entry *se __maybe_unused,
+				 bool selected __maybe_unused,
 				 struct hist_entry *he, char *bf,
 				 size_t size, unsigned int width)
 {
diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h
index 1dffebc..0b992fd 100644
--- a/tools/perf/util/sort.h
+++ b/tools/perf/util/sort.h
@@ -201,7 +201,8 @@ struct sort_entry {
 			  struct hist_entry *);
 	int64_t (*se_collapse)(struct sort_entry *, struct hist_entry *,
 			       struct hist_entry *);
-	int	(*se_snprintf)(struct sort_entry *, struct hist_entry *he,
+	int	(*se_snprintf)(struct sort_entry *, bool selected,
+			       struct hist_entry *he,
 			       char *bf, size_t size, unsigned int width);
 	u8	se_width_idx;
 	bool	elide;
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 07/22] perf tools: Implement selected bool se_snprintf callback logic
  2014-02-02 21:38 [RFC 00/22] perf tools: Display tracepoint enahncements Jiri Olsa
                   ` (5 preceding siblings ...)
  2014-02-02 21:38 ` [PATCH 06/22] perf tools: Add selected bool into se_snprintf sort entries callback Jiri Olsa
@ 2014-02-02 21:38 ` Jiri Olsa
  2014-02-02 21:38 ` [PATCH 08/22] perf tools: Implement selected logic for time sort entry Jiri Olsa
                   ` (16 subsequent siblings)
  23 siblings, 0 replies; 31+ messages in thread
From: Jiri Olsa @ 2014-02-02 21:38 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Corey Ashford, Frederic Weisbecker, Ingo Molnar,
	Namhyung Kim, Paul Mackerras, Peter Zijlstra,
	Arnaldo Carvalho de Melo, David Ahern

Pass the selected info for TUI browser.

Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: David Ahern <dsahern@gmail.com>
---
 tools/perf/ui/browsers/hists.c | 5 +++--
 tools/perf/ui/hist.c           | 5 +++--
 tools/perf/ui/stdio/hist.c     | 2 +-
 tools/perf/util/hist.h         | 3 ++-
 4 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
index 0a08853..0f6d515 100644
--- a/tools/perf/ui/browsers/hists.c
+++ b/tools/perf/ui/browsers/hists.c
@@ -790,7 +790,8 @@ static int hist_browser__show_entry(struct hist_browser *browser,
 		if (!browser->b.navkeypressed)
 			width += 1;
 
-		hist_entry__sort_snprintf(entry, s, sizeof(s), browser->hists);
+		hist_entry__sort_snprintf(entry, current_entry, s, sizeof(s),
+					  browser->hists);
 		slsmg_write_nstring(s, width);
 		++row;
 		++printed;
@@ -1124,7 +1125,7 @@ static int hist_browser__fprintf_entry(struct hist_browser *browser,
 	if (symbol_conf.use_callchain)
 		folded_sign = hist_entry__folded(he);
 
-	hist_entry__sort_snprintf(he, s, sizeof(s), browser->hists);
+	hist_entry__sort_snprintf(he, false, s, sizeof(s), browser->hists);
 	percent = (he->stat.period * 100.0) / browser->hists->stats.total_period;
 
 	if (symbol_conf.use_callchain)
diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c
index 75a8ea6..430c4ea 100644
--- a/tools/perf/ui/hist.c
+++ b/tools/perf/ui/hist.c
@@ -298,7 +298,8 @@ void perf_hpp__cancel_cumulate(void)
 	perf_hpp__format[PERF_HPP__OVERHEAD].header = hpp__header_overhead;
 }
 
-int hist_entry__sort_snprintf(struct hist_entry *he, char *s, size_t size,
+int hist_entry__sort_snprintf(struct hist_entry *he, bool selected,
+			      char *s, size_t size,
 			      struct hists *hists)
 {
 	const char *sep = symbol_conf.field_sep;
@@ -310,7 +311,7 @@ int hist_entry__sort_snprintf(struct hist_entry *he, char *s, size_t size,
 			continue;
 
 		ret += scnprintf(s + ret, size - ret, "%s", sep ?: "  ");
-		ret += se->se_snprintf(se, false, he, s + ret, size - ret,
+		ret += se->se_snprintf(se, selected, he, s + ret, size - ret,
 				       hists__col_len(hists, se->se_width_idx));
 	}
 
diff --git a/tools/perf/ui/stdio/hist.c b/tools/perf/ui/stdio/hist.c
index b48c7ba..ab6f4d6 100644
--- a/tools/perf/ui/stdio/hist.c
+++ b/tools/perf/ui/stdio/hist.c
@@ -360,7 +360,7 @@ static int hist_entry__fprintf(struct hist_entry *he, size_t size,
 		size = hpp.size = bfsz;
 
 	ret = hist_entry__period_snprintf(&hpp, he);
-	hist_entry__sort_snprintf(he, bf + ret, size - ret, hists);
+	hist_entry__sort_snprintf(he, false, bf + ret, size - ret, hists);
 
 	ret = fprintf(fp, "%s\n", bf);
 
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h
index ae403a6..9c0bd20 100644
--- a/tools/perf/util/hist.h
+++ b/tools/perf/util/hist.h
@@ -143,7 +143,8 @@ int hist_entry_iter__add(struct hist_entry_iter *iter, struct addr_location *al,
 int64_t hist_entry__cmp(struct hist_entry *left, struct hist_entry *right);
 int64_t hist_entry__collapse(struct hist_entry *left, struct hist_entry *right);
 int hist_entry__transaction_len(void);
-int hist_entry__sort_snprintf(struct hist_entry *he, char *bf, size_t size,
+int hist_entry__sort_snprintf(struct hist_entry *he, bool selected,
+			      char *bf, size_t size,
 			      struct hists *hists);
 void hist_entry__free(struct hist_entry *);
 
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 08/22] perf tools: Implement selected logic for time sort entry
  2014-02-02 21:38 [RFC 00/22] perf tools: Display tracepoint enahncements Jiri Olsa
                   ` (6 preceding siblings ...)
  2014-02-02 21:38 ` [PATCH 07/22] perf tools: Implement selected bool se_snprintf callback logic Jiri Olsa
@ 2014-02-02 21:38 ` Jiri Olsa
  2014-02-02 21:38 ` [PATCH 09/22] perf tools: Factor ui_browser ops out of ui_browser struct Jiri Olsa
                   ` (15 subsequent siblings)
  23 siblings, 0 replies; 31+ messages in thread
From: Jiri Olsa @ 2014-02-02 21:38 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Corey Ashford, Frederic Weisbecker, Ingo Molnar,
	Namhyung Kim, Paul Mackerras, Peter Zijlstra,
	Arnaldo Carvalho de Melo, David Ahern

Display delta time from the selected entry. Implemented
only for the TUI browser.

Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: David Ahern <dsahern@gmail.com>
---
 tools/perf/ui/browsers/hists.c | 13 +++++++++++++
 tools/perf/util/sort.c         |  6 +++---
 2 files changed, 16 insertions(+), 3 deletions(-)

diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
index 0f6d515..e26afea 100644
--- a/tools/perf/ui/browsers/hists.c
+++ b/tools/perf/ui/browsers/hists.c
@@ -27,6 +27,7 @@ struct hist_browser {
 	bool		     show_dso;
 	float		     min_pcnt;
 	u64		     nr_pcnt_entries;
+	u64		     time_base;
 };
 
 extern void hist_browser__init_hpp(void);
@@ -819,12 +820,24 @@ static void ui_browser__hists_init_top(struct ui_browser *browser)
 	}
 }
 
+static void init_time_base(struct hist_browser *hb)
+{
+	struct hists *hists = hb->hists;
+
+	if (hb->time_base)
+		hists->time_base = hb->time_base;
+
+	if (hists->time_base && !hb->time_base)
+		hb->time_base = hists->time_base;
+}
+
 static unsigned int hist_browser__refresh(struct ui_browser *browser)
 {
 	unsigned row = 0;
 	struct rb_node *nd;
 	struct hist_browser *hb = container_of(browser, struct hist_browser, b);
 
+	init_time_base(hb);
 	ui_browser__hists_init_top(browser);
 
 	for (nd = browser->top; nd; nd = rb_next(nd)) {
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
index b219eaf..381139d 100644
--- a/tools/perf/util/sort.c
+++ b/tools/perf/util/sort.c
@@ -90,11 +90,11 @@ sort__time_cmp(struct sort_entry *se __maybe_unused,
 	return right->time - left->time;
 }
 
-static u64 get_time_base(struct hist_entry *he)
+static u64 get_time_base(struct hist_entry *he, bool selected)
 {
 	struct hists *hists = he->hists;
 
-	if (!hists->time_base)
+	if (!hists->time_base || selected)
 		hists->time_base = he->time;
 
 	return hists->time_base;
@@ -106,7 +106,7 @@ static int hist_entry__time_snprintf(struct sort_entry *se __maybe_unused,
 				     size_t size, unsigned int width)
 {
 	char buf[100];
-	u64 time_base = get_time_base(he);
+	u64 time_base = get_time_base(he, selected);
 	unsigned long time_sec, time_usec;
 	unsigned long base_sec, base_usec;
 	long delta_sec, delta_usec;
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 09/22] perf tools: Factor ui_browser ops out of ui_browser struct
  2014-02-02 21:38 [RFC 00/22] perf tools: Display tracepoint enahncements Jiri Olsa
                   ` (7 preceding siblings ...)
  2014-02-02 21:38 ` [PATCH 08/22] perf tools: Implement selected logic for time sort entry Jiri Olsa
@ 2014-02-02 21:38 ` Jiri Olsa
  2014-02-02 21:38 ` [PATCH 10/22] perf tools: Add header callback into ui_browser_ops struct Jiri Olsa
                   ` (14 subsequent siblings)
  23 siblings, 0 replies; 31+ messages in thread
From: Jiri Olsa @ 2014-02-02 21:38 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Corey Ashford, Frederic Weisbecker, Ingo Molnar,
	Namhyung Kim, Paul Mackerras, Peter Zijlstra,
	Arnaldo Carvalho de Melo, David Ahern

Separating ops out of 'struct ui_browser' into
'struct ui_browser_ops'.

Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: David Ahern <dsahern@gmail.com>
---
 tools/perf/ui/browser.c           | 37 ++++++++++++++++++++++---------------
 tools/perf/ui/browser.h           | 28 +++++++++++++++++-----------
 tools/perf/ui/browsers/annotate.c | 19 +++++++++++--------
 tools/perf/ui/browsers/header.c   |  8 +++++---
 tools/perf/ui/browsers/hists.c    | 14 ++++++++------
 tools/perf/ui/browsers/map.c      |  8 +++++---
 tools/perf/ui/browsers/scripts.c  |  2 +-
 tools/perf/ui/tui/util.c          |  8 +++++---
 8 files changed, 74 insertions(+), 50 deletions(-)

diff --git a/tools/perf/ui/browser.c b/tools/perf/ui/browser.c
index d11541d..b0b651d 100644
--- a/tools/perf/ui/browser.c
+++ b/tools/perf/ui/browser.c
@@ -46,12 +46,18 @@ void ui_browser__gotorc(struct ui_browser *browser, int y, int x)
 	SLsmg_gotorc(browser->y + y, browser->x + x);
 }
 
+static bool ui_browser__filter(struct ui_browser *browser, void *entry)
+{
+	return browser->ops.filter ? browser->ops.filter(browser, entry) :
+				     false;
+}
+
 static struct list_head *
 ui_browser__list_head_filter_entries(struct ui_browser *browser,
 				     struct list_head *pos)
 {
 	do {
-		if (!browser->filter || !browser->filter(browser, pos))
+		if (!ui_browser__filter(browser, pos))
 			return pos;
 		pos = pos->next;
 	} while (pos != browser->entries);
@@ -64,7 +70,7 @@ ui_browser__list_head_filter_prev_entries(struct ui_browser *browser,
 					  struct list_head *pos)
 {
 	do {
-		if (!browser->filter || !browser->filter(browser, pos))
+		if (!ui_browser__filter(browser, pos))
 			return pos;
 		pos = pos->prev;
 	} while (pos != browser->entries);
@@ -149,7 +155,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);
+		browser->ops.write(browser, nd, row);
 		if (++row == browser->height)
 			break;
 		nd = rb_next(nd);
@@ -227,7 +233,7 @@ bool ui_browser__dialog_yesno(struct ui_browser *browser, const char *text)
 void ui_browser__reset_index(struct ui_browser *browser)
 {
 	browser->index = browser->top_idx = 0;
-	browser->seek(browser, 0, SEEK_SET);
+	browser->ops.seek(browser, 0, SEEK_SET);
 }
 
 void __ui_browser__show_title(struct ui_browser *browser, const char *title)
@@ -302,7 +308,7 @@ static int __ui_browser__refresh(struct ui_browser *browser)
 	int row;
 	int width = browser->width;
 
-	row = browser->refresh(browser);
+	row = browser->ops.refresh(browser);
 	ui_browser__set_color(browser, HE_COLORSET_NORMAL);
 
 	if (!browser->use_navkeypressed || browser->navkeypressed)
@@ -346,11 +352,12 @@ void ui_browser__update_nr_entries(struct ui_browser *browser, u32 nr_entries)
 	}
 
 	browser->top = NULL;
-	browser->seek(browser, browser->top_idx, SEEK_SET);
+	browser->ops.seek(browser, browser->top_idx, SEEK_SET);
 }
 
 int ui_browser__run(struct ui_browser *browser, int delay_secs)
 {
+	struct ui_browser_ops *ops = &browser->ops;
 	int err, key;
 
 	while (1) {
@@ -391,7 +398,7 @@ int ui_browser__run(struct ui_browser *browser, int delay_secs)
 			++browser->index;
 			if (browser->index == browser->top_idx + browser->height) {
 				++browser->top_idx;
-				browser->seek(browser, +1, SEEK_CUR);
+				ops->seek(browser, +1, SEEK_CUR);
 			}
 			break;
 		case K_UP:
@@ -400,7 +407,7 @@ int ui_browser__run(struct ui_browser *browser, int delay_secs)
 			--browser->index;
 			if (browser->index < browser->top_idx) {
 				--browser->top_idx;
-				browser->seek(browser, -1, SEEK_CUR);
+				ops->seek(browser, -1, SEEK_CUR);
 			}
 			break;
 		case K_PGDN:
@@ -413,7 +420,7 @@ int ui_browser__run(struct ui_browser *browser, int delay_secs)
 				offset = browser->nr_entries - 1 - browser->index;
 			browser->index += offset;
 			browser->top_idx += offset;
-			browser->seek(browser, +offset, SEEK_CUR);
+			ops->seek(browser, +offset, SEEK_CUR);
 			break;
 		case K_PGUP:
 			if (browser->top_idx == 0)
@@ -426,7 +433,7 @@ int ui_browser__run(struct ui_browser *browser, int delay_secs)
 
 			browser->index -= offset;
 			browser->top_idx -= offset;
-			browser->seek(browser, -offset, SEEK_CUR);
+			ops->seek(browser, -offset, SEEK_CUR);
 			break;
 		case K_HOME:
 			ui_browser__reset_index(browser);
@@ -438,7 +445,7 @@ int ui_browser__run(struct ui_browser *browser, int delay_secs)
 
 			browser->index = browser->nr_entries - 1;
 			browser->top_idx = browser->index - offset;
-			browser->seek(browser, -offset, SEEK_END);
+			ops->seek(browser, -offset, SEEK_END);
 			break;
 		default:
 			return key;
@@ -459,9 +466,9 @@ unsigned int ui_browser__list_head_refresh(struct ui_browser *browser)
 	pos = browser->top;
 
 	list_for_each_from(pos, head) {
-		if (!browser->filter || !browser->filter(browser, pos)) {
+		if (!ui_browser__filter(browser, pos)) {
 			ui_browser__gotorc(browser, row, 0);
-			browser->write(browser, pos, row);
+			browser->ops.write(browser, pos, row);
 			if (++row == browser->height)
 				break;
 		}
@@ -584,9 +591,9 @@ unsigned int ui_browser__argv_refresh(struct ui_browser *browser)
 
 	pos = (char **)browser->top;
 	while (idx < browser->nr_entries) {
-		if (!browser->filter || !browser->filter(browser, *pos)) {
+		if (!ui_browser__filter(browser, *pos)) {
 			ui_browser__gotorc(browser, row, 0);
-			browser->write(browser, pos, row);
+			browser->ops.write(browser, pos, row);
 			if (++row == browser->height)
 				break;
 		}
diff --git a/tools/perf/ui/browser.h b/tools/perf/ui/browser.h
index 118cca2..5610176 100644
--- a/tools/perf/ui/browser.h
+++ b/tools/perf/ui/browser.h
@@ -13,21 +13,27 @@
 #define HE_COLORSET_ADDR	55
 #define HE_COLORSET_ROOT	56
 
-struct ui_browser {
-	u64	      index, top_idx;
-	void	      *top, *entries;
-	u16	      y, x, width, height;
-	int	      current_color;
-	void	      *priv;
-	const char    *title;
-	char	      *helpline;
+struct ui_browser;
+
+struct ui_browser_ops {
 	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);
 	bool	      (*filter)(struct ui_browser *browser, void *entry);
-	u32	      nr_entries;
-	bool	      navkeypressed;
-	bool	      use_navkeypressed;
+};
+
+struct ui_browser {
+	u64			index, top_idx;
+	void			*top, *entries;
+	u16			y, x, width, height;
+	int			current_color;
+	void			*priv;
+	const char		*title;
+	char			*helpline;
+	u32			nr_entries;
+	bool			navkeypressed;
+	bool			use_navkeypressed;
+	struct ui_browser_ops	ops;
 };
 
 int  ui_browser__set_color(struct ui_browser *browser, int color);
diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c
index f0697a3..bc4bcfa 100644
--- a/tools/perf/ui/browsers/annotate.c
+++ b/tools/perf/ui/browsers/annotate.c
@@ -388,8 +388,9 @@ static bool annotate_browser__toggle_source(struct annotate_browser *browser)
 	struct disasm_line *dl;
 	struct browser_disasm_line *bdl;
 	off_t offset = browser->b.index - browser->b.top_idx;
+	struct ui_browser_ops *ops = &browser->b.ops;
 
-	browser->b.seek(&browser->b, offset, SEEK_CUR);
+	ops->seek(&browser->b, offset, SEEK_CUR);
 	dl = list_entry(browser->b.top, struct disasm_line, node);
 	bdl = disasm_line__browser(dl);
 
@@ -399,13 +400,13 @@ static bool annotate_browser__toggle_source(struct annotate_browser *browser)
 
 		browser->b.nr_entries = browser->nr_entries;
 		annotate_browser__opts.hide_src_code = false;
-		browser->b.seek(&browser->b, -offset, SEEK_CUR);
+		ops->seek(&browser->b, -offset, SEEK_CUR);
 		browser->b.top_idx = bdl->idx - offset;
 		browser->b.index = bdl->idx;
 	} else {
 		if (bdl->idx_asm < 0) {
 			ui_helpline__puts("Only available for assembly lines.");
-			browser->b.seek(&browser->b, -offset, SEEK_CUR);
+			ops->seek(&browser->b, -offset, SEEK_CUR);
 			return false;
 		}
 
@@ -414,7 +415,7 @@ static bool annotate_browser__toggle_source(struct annotate_browser *browser)
 
 		browser->b.nr_entries = browser->nr_asm_entries;
 		annotate_browser__opts.hide_src_code = true;
-		browser->b.seek(&browser->b, -offset, SEEK_CUR);
+		ops->seek(&browser->b, -offset, SEEK_CUR);
 		browser->b.top_idx = bdl->idx_asm - offset;
 		browser->b.index = bdl->idx_asm;
 	}
@@ -882,10 +883,12 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map,
 	};
 	struct annotate_browser browser = {
 		.b = {
-			.refresh = annotate_browser__refresh,
-			.seek	 = ui_browser__list_head_seek,
-			.write	 = annotate_browser__write,
-			.filter  = disasm_line__filter,
+			.ops = {
+				.refresh = annotate_browser__refresh,
+				.seek	 = ui_browser__list_head_seek,
+				.write	 = annotate_browser__write,
+				.filter  = disasm_line__filter,
+			},
 			.priv	 = &ms,
 			.use_navkeypressed = true,
 		},
diff --git a/tools/perf/ui/browsers/header.c b/tools/perf/ui/browsers/header.c
index 89c16b9..69f1929 100644
--- a/tools/perf/ui/browsers/header.c
+++ b/tools/perf/ui/browsers/header.c
@@ -81,10 +81,12 @@ static int ui__list_menu(int argc, char * const argv[])
 {
 	struct ui_browser menu = {
 		.entries    = (void *)argv,
-		.refresh    = ui_browser__argv_refresh,
-		.seek	    = ui_browser__argv_seek,
-		.write	    = ui_browser__argv_write,
 		.nr_entries = argc,
+		.ops = {
+			.refresh    = ui_browser__argv_refresh,
+			.seek	    = ui_browser__argv_seek,
+			.write	    = ui_browser__argv_write,
+		},
 	};
 
 	return list_menu__run(&menu);
diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
index e26afea..b4e476c 100644
--- a/tools/perf/ui/browsers/hists.c
+++ b/tools/perf/ui/browsers/hists.c
@@ -1216,8 +1216,8 @@ static struct hist_browser *hist_browser__new(struct hists *hists)
 
 	if (browser) {
 		browser->hists = hists;
-		browser->b.refresh = hist_browser__refresh;
-		browser->b.seek = ui_browser__hists_seek;
+		browser->b.ops.refresh = hist_browser__refresh;
+		browser->b.ops.seek = ui_browser__hists_seek;
 		browser->b.use_navkeypressed = true;
 	}
 
@@ -1944,11 +1944,13 @@ static int __perf_evlist__tui_browse_hists(struct perf_evlist *evlist,
 	struct perf_evsel *pos;
 	struct perf_evsel_menu menu = {
 		.b = {
+			.ops = {
+				.refresh    = ui_browser__list_head_refresh,
+				.seek	    = ui_browser__list_head_seek,
+				.write	    = perf_evsel_menu__write,
+				.filter	    = filter_group_entries,
+			},
 			.entries    = &evlist->entries,
-			.refresh    = ui_browser__list_head_refresh,
-			.seek	    = ui_browser__list_head_seek,
-			.write	    = perf_evsel_menu__write,
-			.filter	    = filter_group_entries,
 			.nr_entries = nr_entries,
 			.priv	    = evlist,
 		},
diff --git a/tools/perf/ui/browsers/map.c b/tools/perf/ui/browsers/map.c
index b11639f..6b09cd6 100644
--- a/tools/perf/ui/browsers/map.c
+++ b/tools/perf/ui/browsers/map.c
@@ -103,9 +103,11 @@ int map__browse(struct map *map)
 	struct map_browser mb = {
 		.b = {
 			.entries = &map->dso->symbols[map->type],
-			.refresh = ui_browser__rb_tree_refresh,
-			.seek	 = ui_browser__rb_tree_seek,
-			.write	 = map_browser__write,
+			.ops = {
+				.refresh = ui_browser__rb_tree_refresh,
+				.seek	 = ui_browser__rb_tree_seek,
+				.write	 = map_browser__write,
+			},
 		},
 		.map = map,
 	};
diff --git a/tools/perf/ui/browsers/scripts.c b/tools/perf/ui/browsers/scripts.c
index 402d2bd..bbbc442 100644
--- a/tools/perf/ui/browsers/scripts.c
+++ b/tools/perf/ui/browsers/scripts.c
@@ -116,7 +116,7 @@ int script_browse(const char *script_opt)
 	struct script_line *sline;
 
 	struct perf_script_browser script = {
-		.b = {
+		.b.ops = {
 			.refresh    = ui_browser__list_head_refresh,
 			.seek	    = ui_browser__list_head_seek,
 			.write	    = script_browser__write,
diff --git a/tools/perf/ui/tui/util.c b/tools/perf/ui/tui/util.c
index bf890f7..8ac0465 100644
--- a/tools/perf/ui/tui/util.c
+++ b/tools/perf/ui/tui/util.c
@@ -60,10 +60,12 @@ int ui__popup_menu(int argc, char * const argv[])
 {
 	struct ui_browser menu = {
 		.entries    = (void *)argv,
-		.refresh    = ui_browser__argv_refresh,
-		.seek	    = ui_browser__argv_seek,
-		.write	    = ui_browser__argv_write,
 		.nr_entries = argc,
+		.ops        = {
+			.refresh    = ui_browser__argv_refresh,
+			.seek	    = ui_browser__argv_seek,
+			.write	    = ui_browser__argv_write,
+		},
 	};
 
 	return popup_menu__run(&menu);
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 10/22] perf tools: Add header callback into ui_browser_ops struct
  2014-02-02 21:38 [RFC 00/22] perf tools: Display tracepoint enahncements Jiri Olsa
                   ` (8 preceding siblings ...)
  2014-02-02 21:38 ` [PATCH 09/22] perf tools: Factor ui_browser ops out of ui_browser struct Jiri Olsa
@ 2014-02-02 21:38 ` Jiri Olsa
  2014-02-02 21:38 ` [PATCH 11/22] perf tools: Remove ev_name argument from perf_evsel__hists_browse Jiri Olsa
                   ` (13 subsequent siblings)
  23 siblings, 0 replies; 31+ messages in thread
From: Jiri Olsa @ 2014-02-02 21:38 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Corey Ashford, Frederic Weisbecker, Ingo Molnar,
	Namhyung Kim, Paul Mackerras, Peter Zijlstra,
	Arnaldo Carvalho de Melo, David Ahern

Adding header callback into 'struct ui_browser_ops',
the prototype is:
   unsigned int (*header)(struct ui_browser *browser);

It's called before the refresh callback under the
same lock.  It's going to be used for hist browser
to display column header.

Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: David Ahern <dsahern@gmail.com>
---
 tools/perf/ui/browser.c | 8 ++++++++
 tools/perf/ui/browser.h | 1 +
 2 files changed, 9 insertions(+)

diff --git a/tools/perf/ui/browser.c b/tools/perf/ui/browser.c
index b0b651d..31bd6e8 100644
--- a/tools/perf/ui/browser.c
+++ b/tools/perf/ui/browser.c
@@ -303,11 +303,19 @@ static void ui_browser__scrollbar_set(struct ui_browser *browser)
 	SLsmg_set_char_set(0);
 }
 
+static void __ui_browser__header(struct ui_browser *browser)
+{
+	if (browser->ops.header)
+		browser->ops.header(browser);
+}
+
 static int __ui_browser__refresh(struct ui_browser *browser)
 {
 	int row;
 	int width = browser->width;
 
+	__ui_browser__header(browser);
+
 	row = browser->ops.refresh(browser);
 	ui_browser__set_color(browser, HE_COLORSET_NORMAL);
 
diff --git a/tools/perf/ui/browser.h b/tools/perf/ui/browser.h
index 5610176..73b17b7 100644
--- a/tools/perf/ui/browser.h
+++ b/tools/perf/ui/browser.h
@@ -16,6 +16,7 @@
 struct ui_browser;
 
 struct ui_browser_ops {
+	unsigned int  (*header)(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);
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 11/22] perf tools: Remove ev_name argument from perf_evsel__hists_browse
  2014-02-02 21:38 [RFC 00/22] perf tools: Display tracepoint enahncements Jiri Olsa
                   ` (9 preceding siblings ...)
  2014-02-02 21:38 ` [PATCH 10/22] perf tools: Add header callback into ui_browser_ops struct Jiri Olsa
@ 2014-02-02 21:38 ` Jiri Olsa
  2014-02-02 21:39 ` [PATCH 12/22] perf tools: Add header callback to hist browser Jiri Olsa
                   ` (12 subsequent siblings)
  23 siblings, 0 replies; 31+ messages in thread
From: Jiri Olsa @ 2014-02-02 21:38 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Corey Ashford, Frederic Weisbecker, Ingo Molnar,
	Namhyung Kim, Paul Mackerras, Peter Zijlstra,
	Arnaldo Carvalho de Melo, David Ahern

Removing ev_name argument from perf_evsel__hists_browse
function, because it's not needed. We can get the name
out of the 'struct perf_evsel' which is passed as
argument as well.

Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: David Ahern <dsahern@gmail.com>
---
 tools/perf/ui/browsers/hists.c | 25 +++++++++++--------------
 1 file changed, 11 insertions(+), 14 deletions(-)

diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
index b4e476c..b4e789b 100644
--- a/tools/perf/ui/browsers/hists.c
+++ b/tools/perf/ui/browsers/hists.c
@@ -32,8 +32,7 @@ struct hist_browser {
 
 extern void hist_browser__init_hpp(void);
 
-static int hists__browser_title(struct hists *hists, char *bf, size_t size,
-				const char *ev_name);
+static int hists__browser_title(struct hists *hists, char *bf, size_t size);
 
 static void hist_browser__refresh_dimensions(struct hist_browser *browser)
 {
@@ -313,7 +312,7 @@ static void ui_browser__warn_lost_events(struct ui_browser *browser)
 
 static void hist_browser__update_pcnt_entries(struct hist_browser *hb);
 
-static int hist_browser__run(struct hist_browser *browser, const char *ev_name,
+static int hist_browser__run(struct hist_browser *browser,
 			     struct hist_browser_timer *hbt)
 {
 	int key;
@@ -326,7 +325,7 @@ static int hist_browser__run(struct hist_browser *browser, const char *ev_name,
 		browser->b.nr_entries = browser->nr_pcnt_entries;
 
 	hist_browser__refresh_dimensions(browser);
-	hists__browser_title(browser->hists, title, sizeof(title), ev_name);
+	hists__browser_title(browser->hists, title, sizeof(title));
 
 	if (ui_browser__show(&browser->b, title,
 			     "Press '?' for help on key bindings") < 0)
@@ -356,7 +355,7 @@ static int hist_browser__run(struct hist_browser *browser, const char *ev_name,
 				ui_browser__warn_lost_events(&browser->b);
 			}
 
-			hists__browser_title(browser->hists, title, sizeof(title), ev_name);
+			hists__browser_title(browser->hists, title, sizeof(title));
 			ui_browser__show_title(&browser->b, title);
 			continue;
 		}
@@ -1239,8 +1238,7 @@ static struct thread *hist_browser__selected_thread(struct hist_browser *browser
 	return browser->he_selection->thread;
 }
 
-static int hists__browser_title(struct hists *hists, char *bf, size_t size,
-				const char *ev_name)
+static int hists__browser_title(struct hists *hists, char *bf, size_t size)
 {
 	char unit;
 	int printed;
@@ -1249,6 +1247,7 @@ static int hists__browser_title(struct hists *hists, char *bf, size_t size,
 	unsigned long nr_samples = hists->stats.nr_events[PERF_RECORD_SAMPLE];
 	u64 nr_events = hists->stats.total_period;
 	struct perf_evsel *evsel = hists_to_evsel(hists);
+	const char *ev_name = perf_evsel__name(evsel);
 	char buf[512];
 	size_t buflen = sizeof(buf);
 
@@ -1401,7 +1400,7 @@ static void hist_browser__update_pcnt_entries(struct hist_browser *hb)
 }
 
 static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
-				    const char *helpline, const char *ev_name,
+				    const char *helpline,
 				    bool left_exits,
 				    struct hist_browser_timer *hbt,
 				    float min_pcnt,
@@ -1475,7 +1474,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
 
 		nr_options = 0;
 
-		key = hist_browser__run(browser, ev_name, hbt);
+		key = hist_browser__run(browser, hbt);
 
 		if (browser->he_selection != NULL) {
 			thread = hist_browser__selected_thread(browser);
@@ -1840,7 +1839,7 @@ static int perf_evsel_menu__run(struct perf_evsel_menu *menu,
 {
 	struct perf_evlist *evlist = menu->b.priv;
 	struct perf_evsel *pos;
-	const char *ev_name, *title = "Available samples";
+	const char *title = "Available samples";
 	int delay_secs = hbt ? hbt->refresh : 0;
 	int key;
 
@@ -1873,9 +1872,8 @@ browse_hists:
 			 */
 			if (hbt)
 				hbt->timer(hbt->arg);
-			ev_name = perf_evsel__name(pos);
 			key = perf_evsel__hists_browse(pos, nr_events, help,
-						       ev_name, true, hbt,
+						       true, hbt,
 						       menu->min_pcnt,
 						       menu->env);
 			ui_browser__show_title(&menu->b, title);
@@ -1981,10 +1979,9 @@ int perf_evlist__tui_browse_hists(struct perf_evlist *evlist, const char *help,
 single_entry:
 	if (nr_entries == 1) {
 		struct perf_evsel *first = perf_evlist__first(evlist);
-		const char *ev_name = perf_evsel__name(first);
 
 		return perf_evsel__hists_browse(first, nr_entries, help,
-						ev_name, false, hbt, min_pcnt,
+						false, hbt, min_pcnt,
 						env);
 	}
 
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 12/22] perf tools: Add header callback to hist browser
  2014-02-02 21:38 [RFC 00/22] perf tools: Display tracepoint enahncements Jiri Olsa
                   ` (10 preceding siblings ...)
  2014-02-02 21:38 ` [PATCH 11/22] perf tools: Remove ev_name argument from perf_evsel__hists_browse Jiri Olsa
@ 2014-02-02 21:39 ` Jiri Olsa
  2014-02-02 21:39 ` [PATCH 13/22] perf tools: Factor hpp_arg struct to carry hist_browser Jiri Olsa
                   ` (11 subsequent siblings)
  23 siblings, 0 replies; 31+ messages in thread
From: Jiri Olsa @ 2014-02-02 21:39 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Corey Ashford, Frederic Weisbecker, Ingo Molnar,
	Namhyung Kim, Paul Mackerras, Peter Zijlstra,
	Arnaldo Carvalho de Melo, David Ahern

Adding header callback for hist browser to display
the column headers.

Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: David Ahern <dsahern@gmail.com>
---
 tools/perf/ui/browser.c        | 46 ++++++++++++++++++++++++++++++++----------
 tools/perf/ui/browser.h        |  2 ++
 tools/perf/ui/browsers/hists.c | 25 +++++++++++++++--------
 3 files changed, 54 insertions(+), 19 deletions(-)

diff --git a/tools/perf/ui/browser.c b/tools/perf/ui/browser.c
index 31bd6e8..3f8a758 100644
--- a/tools/perf/ui/browser.c
+++ b/tools/perf/ui/browser.c
@@ -250,26 +250,49 @@ void ui_browser__show_title(struct ui_browser *browser, const char *title)
 	pthread_mutex_unlock(&ui__lock);
 }
 
-int ui_browser__show(struct ui_browser *browser, const char *title,
-		     const char *helpline, ...)
+static int ui_browser__show_va(struct ui_browser *browser, const char *title,
+			const char *helpline, va_list args)
 {
 	int err;
-	va_list ap;
-
-	ui_browser__refresh_dimensions(browser);
 
-	pthread_mutex_lock(&ui__lock);
 	__ui_browser__show_title(browser, title);
 
 	browser->title = title;
 	zfree(&browser->helpline);
 
-	va_start(ap, helpline);
-	err = vasprintf(&browser->helpline, helpline, ap);
-	va_end(ap);
+	err = vasprintf(&browser->helpline, helpline, args);
 	if (err > 0)
 		ui_helpline__push(browser->helpline);
+
+	return err;
+}
+
+int __ui_browser__show(struct ui_browser *browser, const char *title,
+		       const char *helpline, ...)
+{
+	va_list args;
+	int err;
+
+	va_start(args, helpline);
+	err = ui_browser__show_va(browser, title, helpline, args);
+	va_end(args);
+
+	return err ? 0 : -1;
+}
+
+int ui_browser__show(struct ui_browser *browser, const char *title,
+		     const char *helpline, ...)
+{
+	va_list args;
+	int err;
+
+	pthread_mutex_lock(&ui__lock);
+	ui_browser__refresh_dimensions(browser);
+	va_start(args, helpline);
+	err = ui_browser__show_va(browser, title, helpline, args);
+	va_end(args);
 	pthread_mutex_unlock(&ui__lock);
+
 	return err ? 0 : -1;
 }
 
@@ -311,14 +334,15 @@ static void __ui_browser__header(struct ui_browser *browser)
 
 static int __ui_browser__refresh(struct ui_browser *browser)
 {
-	int row;
-	int width = browser->width;
+	int row, width;
 
 	__ui_browser__header(browser);
 
 	row = browser->ops.refresh(browser);
 	ui_browser__set_color(browser, HE_COLORSET_NORMAL);
 
+	width = browser->width;
+
 	if (!browser->use_navkeypressed || browser->navkeypressed)
 		ui_browser__scrollbar_set(browser);
 	else
diff --git a/tools/perf/ui/browser.h b/tools/perf/ui/browser.h
index 73b17b7..7231f39 100644
--- a/tools/perf/ui/browser.h
+++ b/tools/perf/ui/browser.h
@@ -50,6 +50,8 @@ void __ui_browser__line_arrow(struct ui_browser *browser, unsigned int column,
 			      u64 start, u64 end);
 void __ui_browser__show_title(struct ui_browser *browser, const char *title);
 void ui_browser__show_title(struct ui_browser *browser, const char *title);
+int __ui_browser__show(struct ui_browser *browser, const char *title,
+		       const char *helpline, ...);
 int ui_browser__show(struct ui_browser *browser, const char *title,
 		     const char *helpline, ...);
 void ui_browser__hide(struct ui_browser *browser);
diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
index b4e789b..9a95fdc 100644
--- a/tools/perf/ui/browsers/hists.c
+++ b/tools/perf/ui/browsers/hists.c
@@ -316,7 +316,6 @@ static int hist_browser__run(struct hist_browser *browser,
 			     struct hist_browser_timer *hbt)
 {
 	int key;
-	char title[160];
 	int delay_secs = hbt ? hbt->refresh : 0;
 
 	browser->b.entries = &browser->hists->entries;
@@ -325,11 +324,6 @@ static int hist_browser__run(struct hist_browser *browser,
 		browser->b.nr_entries = browser->nr_pcnt_entries;
 
 	hist_browser__refresh_dimensions(browser);
-	hists__browser_title(browser->hists, title, sizeof(title));
-
-	if (ui_browser__show(&browser->b, title,
-			     "Press '?' for help on key bindings") < 0)
-		return -1;
 
 	while (1) {
 		key = ui_browser__run(&browser->b, delay_secs);
@@ -355,8 +349,6 @@ static int hist_browser__run(struct hist_browser *browser,
 				ui_browser__warn_lost_events(&browser->b);
 			}
 
-			hists__browser_title(browser->hists, title, sizeof(title));
-			ui_browser__show_title(&browser->b, title);
 			continue;
 		}
 		case 'D': { /* Debug */
@@ -1209,12 +1201,29 @@ static int hist_browser__dump(struct hist_browser *browser)
 	return 0;
 }
 
+static unsigned int hist_browser__header(struct ui_browser *b)
+{
+	struct hist_browser *browser;
+	char title[160];
+
+	browser = container_of(b, struct hist_browser, b);
+	ui_browser__refresh_dimensions(b);
+	hists__browser_title(browser->hists, title, sizeof(title));
+
+	if (__ui_browser__show(b, title,
+		"Press '?' for help on key bindings") < 0)
+		return -1;
+
+	return 0;
+}
+
 static struct hist_browser *hist_browser__new(struct hists *hists)
 {
 	struct hist_browser *browser = zalloc(sizeof(*browser));
 
 	if (browser) {
 		browser->hists = hists;
+		browser->b.ops.header = hist_browser__header;
 		browser->b.ops.refresh = hist_browser__refresh;
 		browser->b.ops.seek = ui_browser__hists_seek;
 		browser->b.use_navkeypressed = true;
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 13/22] perf tools: Factor hpp_arg struct to carry hist_browser
  2014-02-02 21:38 [RFC 00/22] perf tools: Display tracepoint enahncements Jiri Olsa
                   ` (11 preceding siblings ...)
  2014-02-02 21:39 ` [PATCH 12/22] perf tools: Add header callback to hist browser Jiri Olsa
@ 2014-02-02 21:39 ` Jiri Olsa
  2014-02-02 21:39 ` [PATCH 14/22] perf tools tui: Display columns header text on 'H' press Jiri Olsa
                   ` (10 subsequent siblings)
  23 siblings, 0 replies; 31+ messages in thread
From: Jiri Olsa @ 2014-02-02 21:39 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Corey Ashford, Frederic Weisbecker, Ingo Molnar,
	Namhyung Kim, Paul Mackerras, Peter Zijlstra,
	Arnaldo Carvalho de Melo, David Ahern

The hpp_arg struct is used within the hist browser
specific code, so it could pass the hist_browser
struct itself.

We'll need access to hist browser struct within
__hpp__color_fmt function in following patch.

Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: David Ahern <dsahern@gmail.com>
---
 tools/perf/ui/browsers/hists.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
index 9a95fdc..3dd71d6 100644
--- a/tools/perf/ui/browsers/hists.c
+++ b/tools/perf/ui/browsers/hists.c
@@ -574,7 +574,7 @@ static int hist_browser__show_callchain(struct hist_browser *browser,
 }
 
 struct hpp_arg {
-	struct ui_browser *b;
+	struct hist_browser *hb;
 	char folded_sign;
 	bool current_entry;
 };
@@ -600,7 +600,7 @@ static int __hpp__color_fmt(struct perf_hpp *hpp, struct hist_entry *he,
 	if (hists->stats.total_period)
 		percent = 100.0 * get_field(he) / hists->stats.total_period;
 
-	ui_browser__set_percent_color(arg->b, percent, arg->current_entry);
+	ui_browser__set_percent_color(&arg->hb->b, percent, arg->current_entry);
 
 	if (callchain_cb)
 		ret += callchain_cb(arg);
@@ -634,7 +634,7 @@ static int __hpp__color_fmt(struct perf_hpp *hpp, struct hist_entry *he,
 				 * zero-fill group members in the middle which
 				 * have no sample
 				 */
-				ui_browser__set_percent_color(arg->b, 0.0,
+				ui_browser__set_percent_color(&arg->hb->b, 0.0,
 							arg->current_entry);
 				ret += scnprintf(hpp->buf, hpp->size,
 						 " %6.2f%%", 0.0);
@@ -642,7 +642,7 @@ static int __hpp__color_fmt(struct perf_hpp *hpp, struct hist_entry *he,
 			}
 
 			percent = 100.0 * period / total;
-			ui_browser__set_percent_color(arg->b, percent,
+			ui_browser__set_percent_color(&arg->hb->b, percent,
 						      arg->current_entry);
 			ret += scnprintf(hpp->buf, hpp->size,
 					 " %6.2f%%", percent);
@@ -657,7 +657,7 @@ static int __hpp__color_fmt(struct perf_hpp *hpp, struct hist_entry *he,
 			/*
 			 * zero-fill group members at last which have no sample
 			 */
-			ui_browser__set_percent_color(arg->b, 0.0,
+			ui_browser__set_percent_color(&arg->hb->b, 0.0,
 						      arg->current_entry);
 			ret += scnprintf(hpp->buf, hpp->size,
 					 " %6.2f%%", 0.0);
@@ -665,8 +665,8 @@ static int __hpp__color_fmt(struct perf_hpp *hpp, struct hist_entry *he,
 		}
 	}
 out:
-	if (!arg->current_entry || !arg->b->navkeypressed)
-		ui_browser__set_color(arg->b, HE_COLORSET_NORMAL);
+	if (!arg->current_entry || !arg->hb->b.navkeypressed)
+		ui_browser__set_color(&arg->hb->b, HE_COLORSET_NORMAL);
 
 	return ret;
 }
@@ -751,7 +751,7 @@ static int hist_browser__show_entry(struct hist_browser *browser,
 
 	if (row_offset == 0) {
 		struct hpp_arg arg = {
-			.b 		= &browser->b,
+			.hb		= browser,
 			.folded_sign	= folded_sign,
 			.current_entry	= current_entry,
 		};
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 14/22] perf tools tui: Display columns header text on 'H' press
  2014-02-02 21:38 [RFC 00/22] perf tools: Display tracepoint enahncements Jiri Olsa
                   ` (12 preceding siblings ...)
  2014-02-02 21:39 ` [PATCH 13/22] perf tools: Factor hpp_arg struct to carry hist_browser Jiri Olsa
@ 2014-02-02 21:39 ` Jiri Olsa
  2014-02-02 21:39 ` [PATCH 15/22] tools lib traceevent: Factor print_event_fields function Jiri Olsa
                   ` (9 subsequent siblings)
  23 siblings, 0 replies; 31+ messages in thread
From: Jiri Olsa @ 2014-02-02 21:39 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Corey Ashford, Frederic Weisbecker, Ingo Molnar,
	Namhyung Kim, Paul Mackerras, Peter Zijlstra,
	Arnaldo Carvalho de Melo, David Ahern

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

Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: David Ahern <dsahern@gmail.com>
---
 tools/perf/ui/browser.c        | 12 ++++++-
 tools/perf/ui/browser.h        |  2 +-
 tools/perf/ui/browsers/hists.c | 78 ++++++++++++++++++++++++++++++++++++++----
 3 files changed, 84 insertions(+), 8 deletions(-)

diff --git a/tools/perf/ui/browser.c b/tools/perf/ui/browser.c
index 3f8a758..7a8cd15 100644
--- a/tools/perf/ui/browser.c
+++ b/tools/perf/ui/browser.c
@@ -243,6 +243,13 @@ void __ui_browser__show_title(struct ui_browser *browser, const char *title)
 	slsmg_write_nstring(title, browser->width + 1);
 }
 
+static void __ui_browser__show_header(struct ui_browser *browser, char *header)
+{
+	SLsmg_gotorc(1, 0);
+	ui_browser__set_color(browser, HE_COLORSET_ROOT);
+	slsmg_write_nstring(header, browser->width + 1);
+}
+
 void ui_browser__show_title(struct ui_browser *browser, const char *title)
 {
 	pthread_mutex_lock(&ui__lock);
@@ -268,7 +275,7 @@ static int ui_browser__show_va(struct ui_browser *browser, const char *title,
 }
 
 int __ui_browser__show(struct ui_browser *browser, const char *title,
-		       const char *helpline, ...)
+		       char *header, const char *helpline, ...)
 {
 	va_list args;
 	int err;
@@ -277,6 +284,9 @@ int __ui_browser__show(struct ui_browser *browser, const char *title,
 	err = ui_browser__show_va(browser, title, helpline, args);
 	va_end(args);
 
+	if (header)
+		__ui_browser__show_header(browser, header);
+
 	return err ? 0 : -1;
 }
 
diff --git a/tools/perf/ui/browser.h b/tools/perf/ui/browser.h
index 7231f39..348e761 100644
--- a/tools/perf/ui/browser.h
+++ b/tools/perf/ui/browser.h
@@ -51,7 +51,7 @@ void __ui_browser__line_arrow(struct ui_browser *browser, unsigned int column,
 void __ui_browser__show_title(struct ui_browser *browser, const char *title);
 void ui_browser__show_title(struct ui_browser *browser, const char *title);
 int __ui_browser__show(struct ui_browser *browser, const char *title,
-		       const char *helpline, ...);
+		       char *header, const char *helpline, ...);
 int ui_browser__show(struct ui_browser *browser, const char *title,
 		     const char *helpline, ...);
 void ui_browser__hide(struct ui_browser *browser);
diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
index 3dd71d6..1d519e9 100644
--- a/tools/perf/ui/browsers/hists.c
+++ b/tools/perf/ui/browsers/hists.c
@@ -25,6 +25,7 @@ struct hist_browser {
 	struct map_symbol   *selection;
 	int		     print_seq;
 	bool		     show_dso;
+	bool		     show_col_headers;
 	float		     min_pcnt;
 	u64		     nr_pcnt_entries;
 	u64		     time_base;
@@ -36,9 +37,12 @@ static int hists__browser_title(struct hists *hists, char *bf, size_t size);
 
 static void hist_browser__refresh_dimensions(struct hist_browser *browser)
 {
-	/* 3 == +/- toggle symbol before actual hist_entry rendering */
-	browser->b.width = 3 + (hists__sort_list_width(browser->hists) +
-			     sizeof("[k]"));
+	u16 header = browser->show_col_headers ? 1 : 0;
+
+	browser->b.width = SLtt_Screen_Cols - 1;
+	browser->b.height = SLtt_Screen_Rows - 2 - header;
+	browser->b.y = 1 + header;
+	browser->b.x = 0;
 }
 
 static void hist_browser__reset(struct hist_browser *browser)
@@ -310,6 +314,61 @@ static void ui_browser__warn_lost_events(struct ui_browser *browser)
 		"Or reduce the sampling frequency.");
 }
 
+static size_t scnprintf_header_fmt(char *buf, size_t size)
+{
+	struct perf_hpp_fmt *fmt;
+	bool first = true;
+	size_t ret = 0;
+
+	perf_hpp__for_each_format(fmt) {
+		struct perf_hpp hpp = { .ptr = NULL, };
+
+		if (!first)
+			ret += scnprintf(buf + ret, size, "  ");
+
+		hpp.buf	 = buf + ret,
+		hpp.size = size - ret,
+
+		first = false;
+
+		ret += fmt->header(fmt, &hpp);
+	}
+	return ret;
+}
+
+static size_t scnprintf_header_se(struct hists *hists, char *buf, size_t size)
+{
+	struct sort_entry *se;
+	unsigned int width;
+	int ret = 0;
+
+	list_for_each_entry(se, &hist_entry__sort_list, list) {
+		if (se->elide)
+			continue;
+
+		width = strlen(se->se_header);
+		if (!hists__new_col_len(hists, se->se_width_idx, width))
+			width = hists__col_len(hists, se->se_width_idx);
+
+		ret += scnprintf(buf + ret, size - ret, "  %*s", width,
+				 se->se_header);
+	}
+	return ret;
+}
+
+static int hists__scnprintf_header(char *buf, size_t size, struct hists *hists)
+{
+	size_t ret = 0;
+
+	if (symbol_conf.use_callchain)
+		ret += scnprintf(buf, size, "  ");
+
+	ret += scnprintf_header_fmt(buf + ret, size - ret);
+	ret += scnprintf_header_se(hists, buf + ret, size - ret);
+
+	return ret;
+}
+
 static void hist_browser__update_pcnt_entries(struct hist_browser *hb);
 
 static int hist_browser__run(struct hist_browser *browser,
@@ -373,6 +432,9 @@ static int hist_browser__run(struct hist_browser *browser,
 			/* Expand the whole world. */
 			hist_browser__set_folding(browser, true);
 			break;
+		case 'H':
+			browser->show_col_headers = !browser->show_col_headers;
+			continue;
 		case K_ENTER:
 			if (hist_browser__toggle_fold(browser))
 				break;
@@ -596,6 +658,7 @@ static int __hpp__color_fmt(struct perf_hpp *hpp, struct hist_entry *he,
 	double percent = 0.0;
 	struct hists *hists = he->hists;
 	struct hpp_arg *arg = hpp->ptr;
+	const char *fmt = arg->hb->show_col_headers ? " %6.2f%%" : "%6.2f%%";
 
 	if (hists->stats.total_period)
 		percent = 100.0 * get_field(he) / hists->stats.total_period;
@@ -605,7 +668,7 @@ static int __hpp__color_fmt(struct perf_hpp *hpp, struct hist_entry *he,
 	if (callchain_cb)
 		ret += callchain_cb(arg);
 
-	ret += scnprintf(hpp->buf, hpp->size, "%6.2f%%", percent);
+	ret += scnprintf(hpp->buf, hpp->size, fmt, percent);
 	slsmg_printf("%s", hpp->buf);
 
 	if (symbol_conf.event_group) {
@@ -1205,12 +1268,15 @@ static unsigned int hist_browser__header(struct ui_browser *b)
 {
 	struct hist_browser *browser;
 	char title[160];
+	char header[500];
+	size_t size = min(b->width, (u16) sizeof(header));
 
 	browser = container_of(b, struct hist_browser, b);
-	ui_browser__refresh_dimensions(b);
+	hist_browser__refresh_dimensions(browser);
 	hists__browser_title(browser->hists, title, sizeof(title));
+	hists__scnprintf_header(header, size, browser->hists);
 
-	if (__ui_browser__show(b, title,
+	if (__ui_browser__show(b, title, header,
 		"Press '?' for help on key bindings") < 0)
 		return -1;
 
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 15/22] tools lib traceevent: Factor print_event_fields function
  2014-02-02 21:38 [RFC 00/22] perf tools: Display tracepoint enahncements Jiri Olsa
                   ` (13 preceding siblings ...)
  2014-02-02 21:39 ` [PATCH 14/22] perf tools tui: Display columns header text on 'H' press Jiri Olsa
@ 2014-02-02 21:39 ` Jiri Olsa
  2014-02-02 21:39 ` [PATCH 16/22] tools lib traceevent: Make the name output optional in pevent_field_info Jiri Olsa
                   ` (8 subsequent siblings)
  23 siblings, 0 replies; 31+ messages in thread
From: Jiri Olsa @ 2014-02-02 21:39 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Corey Ashford, Frederic Weisbecker, Ingo Molnar,
	Namhyung Kim, Paul Mackerras, Peter Zijlstra,
	Arnaldo Carvalho de Melo, Steven Rostedt, David Ahern

Factoring print_event_fields function and adding pevent_field_info
function that is used later in comming patches.

Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: David Ahern <dsahern@gmail.com>
---
 tools/lib/traceevent/event-parse.c | 126 ++++++++++++++++++++-----------------
 tools/lib/traceevent/event-parse.h |   4 ++
 2 files changed, 71 insertions(+), 59 deletions(-)

diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c
index 1587ea39..a3370f2 100644
--- a/tools/lib/traceevent/event-parse.c
+++ b/tools/lib/traceevent/event-parse.c
@@ -4026,73 +4026,81 @@ static int is_printable_array(char *p, unsigned int len)
 	return 1;
 }
 
-static void print_event_fields(struct trace_seq *s, void *data,
-			       int size __maybe_unused,
-			       struct event_format *event)
+void pevent_field_info(struct trace_seq *s,
+		       struct format_field *field,
+		       void *data, int size __maybe_unused)
 {
-	struct format_field *field;
-	unsigned long long val;
+	struct event_format *event = field->event;
 	unsigned int offset, len, i;
+	unsigned long long val;
 
-	field = event->format.fields;
-	while (field) {
-		trace_seq_printf(s, " %s=", field->name);
-		if (field->flags & FIELD_IS_ARRAY) {
-			offset = field->offset;
-			len = field->size;
-			if (field->flags & FIELD_IS_DYNAMIC) {
-				val = pevent_read_number(event->pevent, data + offset, len);
-				offset = val;
-				len = offset >> 16;
-				offset &= 0xffff;
-			}
-			if (field->flags & FIELD_IS_STRING &&
-			    is_printable_array(data + offset, len)) {
-				trace_seq_printf(s, "%s", (char *)data + offset);
-			} else {
-				trace_seq_puts(s, "ARRAY[");
-				for (i = 0; i < len; i++) {
-					if (i)
-						trace_seq_puts(s, ", ");
-					trace_seq_printf(s, "%02x",
-							 *((unsigned char *)data + offset + i));
-				}
-				trace_seq_putc(s, ']');
-				field->flags &= ~FIELD_IS_STRING;
-			}
+	trace_seq_printf(s, " %s=", field->name);
+	if (field->flags & FIELD_IS_ARRAY) {
+		offset = field->offset;
+		len = field->size;
+		if (field->flags & FIELD_IS_DYNAMIC) {
+			val = pevent_read_number(event->pevent, data + offset, len);
+			offset = val;
+			len = offset >> 16;
+			offset &= 0xffff;
+		}
+		if (field->flags & FIELD_IS_STRING &&
+		    is_printable_array(data + offset, len)) {
+			trace_seq_printf(s, "%s", (char *)data + offset);
 		} else {
-			val = pevent_read_number(event->pevent, data + field->offset,
-						 field->size);
-			if (field->flags & FIELD_IS_POINTER) {
-				trace_seq_printf(s, "0x%llx", val);
-			} else if (field->flags & FIELD_IS_SIGNED) {
-				switch (field->size) {
-				case 4:
-					/*
-					 * If field is long then print it in hex.
-					 * A long usually stores pointers.
-					 */
-					if (field->flags & FIELD_IS_LONG)
-						trace_seq_printf(s, "0x%x", (int)val);
-					else
-						trace_seq_printf(s, "%d", (int)val);
-					break;
-				case 2:
-					trace_seq_printf(s, "%2d", (short)val);
-					break;
-				case 1:
-					trace_seq_printf(s, "%1d", (char)val);
-					break;
-				default:
-					trace_seq_printf(s, "%lld", val);
-				}
-			} else {
+			trace_seq_puts(s, "ARRAY[");
+			for (i = 0; i < len; i++) {
+				if (i)
+					trace_seq_puts(s, ", ");
+				trace_seq_printf(s, "%02x",
+						 *((unsigned char *)data + offset + i));
+			}
+			trace_seq_putc(s, ']');
+			field->flags &= ~FIELD_IS_STRING;
+		}
+	} else {
+		val = pevent_read_number(event->pevent, data + field->offset,
+					 field->size);
+		if (field->flags & FIELD_IS_POINTER) {
+			trace_seq_printf(s, "0x%llx", val);
+		} else if (field->flags & FIELD_IS_SIGNED) {
+			switch (field->size) {
+			case 4:
+				/*
+				 * If field is long then print it in hex.
+				 * A long usually stores pointers.
+				 */
 				if (field->flags & FIELD_IS_LONG)
-					trace_seq_printf(s, "0x%llx", val);
+					trace_seq_printf(s, "0x%x", (int)val);
 				else
-					trace_seq_printf(s, "%llu", val);
+					trace_seq_printf(s, "%d", (int)val);
+				break;
+			case 2:
+				trace_seq_printf(s, "%2d", (short)val);
+				break;
+			case 1:
+				trace_seq_printf(s, "%1d", (char)val);
+				break;
+			default:
+				trace_seq_printf(s, "%lld", val);
 			}
+		} else {
+			if (field->flags & FIELD_IS_LONG)
+				trace_seq_printf(s, "0x%llx", val);
+			else
+				trace_seq_printf(s, "%llu", val);
 		}
+	}
+}
+
+static void print_event_fields(struct trace_seq *s, void *data, int size,
+			       struct event_format *event)
+{
+	struct format_field *field;
+
+	field = event->format.fields;
+	while (field) {
+		pevent_field_info(s, field, data, size);
 		field = field->next;
 	}
 }
diff --git a/tools/lib/traceevent/event-parse.h b/tools/lib/traceevent/event-parse.h
index 791c539..73492a9 100644
--- a/tools/lib/traceevent/event-parse.h
+++ b/tools/lib/traceevent/event-parse.h
@@ -588,6 +588,10 @@ int pevent_pid_is_registered(struct pevent *pevent, int pid);
 void pevent_print_event(struct pevent *pevent, struct trace_seq *s,
 			struct pevent_record *record, bool use_trace_clock);
 
+void pevent_field_info(struct trace_seq *s,
+		       struct format_field *field,
+		       void *data, int size);
+
 int pevent_parse_header_page(struct pevent *pevent, char *buf, unsigned long size,
 			     int long_size);
 
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 16/22] tools lib traceevent: Make the name output optional in pevent_field_info
  2014-02-02 21:38 [RFC 00/22] perf tools: Display tracepoint enahncements Jiri Olsa
                   ` (14 preceding siblings ...)
  2014-02-02 21:39 ` [PATCH 15/22] tools lib traceevent: Factor print_event_fields function Jiri Olsa
@ 2014-02-02 21:39 ` Jiri Olsa
  2014-02-02 21:39 ` [PATCH 17/22] tools lib traceevent: Add pevent_field_cmp function Jiri Olsa
                   ` (7 subsequent siblings)
  23 siblings, 0 replies; 31+ messages in thread
From: Jiri Olsa @ 2014-02-02 21:39 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Corey Ashford, Frederic Weisbecker, Ingo Molnar,
	Namhyung Kim, Paul Mackerras, Peter Zijlstra,
	Arnaldo Carvalho de Melo, Steven Rostedt, David Ahern

Making the name output optional in pevent_field_info function.

Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: David Ahern <dsahern@gmail.com>
---
 tools/lib/traceevent/event-parse.c | 9 ++++++---
 tools/lib/traceevent/event-parse.h | 3 ++-
 2 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c
index a3370f2..7b5b2dc 100644
--- a/tools/lib/traceevent/event-parse.c
+++ b/tools/lib/traceevent/event-parse.c
@@ -4028,13 +4028,16 @@ static int is_printable_array(char *p, unsigned int len)
 
 void pevent_field_info(struct trace_seq *s,
 		       struct format_field *field,
-		       void *data, int size __maybe_unused)
+		       void *data, int size __maybe_unused,
+		       bool print_name)
 {
 	struct event_format *event = field->event;
 	unsigned int offset, len, i;
 	unsigned long long val;
 
-	trace_seq_printf(s, " %s=", field->name);
+	if (print_name)
+		trace_seq_printf(s, " %s=", field->name);
+
 	if (field->flags & FIELD_IS_ARRAY) {
 		offset = field->offset;
 		len = field->size;
@@ -4100,7 +4103,7 @@ static void print_event_fields(struct trace_seq *s, void *data, int size,
 
 	field = event->format.fields;
 	while (field) {
-		pevent_field_info(s, field, data, size);
+		pevent_field_info(s, field, data, size, true);
 		field = field->next;
 	}
 }
diff --git a/tools/lib/traceevent/event-parse.h b/tools/lib/traceevent/event-parse.h
index 73492a9..b49fad1 100644
--- a/tools/lib/traceevent/event-parse.h
+++ b/tools/lib/traceevent/event-parse.h
@@ -590,7 +590,8 @@ void pevent_print_event(struct pevent *pevent, struct trace_seq *s,
 
 void pevent_field_info(struct trace_seq *s,
 		       struct format_field *field,
-		       void *data, int size);
+		       void *data, int size __maybe_unused,
+		       bool print_name);
 
 int pevent_parse_header_page(struct pevent *pevent, char *buf, unsigned long size,
 			     int long_size);
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 17/22] tools lib traceevent: Add pevent_field_cmp function
  2014-02-02 21:38 [RFC 00/22] perf tools: Display tracepoint enahncements Jiri Olsa
                   ` (15 preceding siblings ...)
  2014-02-02 21:39 ` [PATCH 16/22] tools lib traceevent: Make the name output optional in pevent_field_info Jiri Olsa
@ 2014-02-02 21:39 ` Jiri Olsa
  2014-02-02 21:39 ` [PATCH 18/22] perf tools: Factor sort entries loops Jiri Olsa
                   ` (6 subsequent siblings)
  23 siblings, 0 replies; 31+ messages in thread
From: Jiri Olsa @ 2014-02-02 21:39 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Corey Ashford, Frederic Weisbecker, Ingo Molnar,
	Namhyung Kim, Paul Mackerras, Peter Zijlstra,
	Arnaldo Carvalho de Melo, Steven Rostedt, David Ahern

Adding pevent_field_cmp function to compare 2 fields data,
the interface is:

int pevent_field_cmp(struct format_field *a_field,
		     struct format_field *b_field,
		     void *a_data, int a_size,
		     void *b_data, int b_size);

Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: David Ahern <dsahern@gmail.com>
---
 tools/lib/traceevent/event-parse.c | 54 ++++++++++++++++++++++++++++++++++++++
 tools/lib/traceevent/event-parse.h |  5 ++++
 2 files changed, 59 insertions(+)

diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c
index 7b5b2dc..aa58c26 100644
--- a/tools/lib/traceevent/event-parse.c
+++ b/tools/lib/traceevent/event-parse.c
@@ -4026,6 +4026,60 @@ static int is_printable_array(char *p, unsigned int len)
 	return 1;
 }
 
+int pevent_field_cmp(struct format_field *a_field,
+		     struct format_field *b_field,
+		     void *a_data, int a_size,
+		     void *b_data, int b_size)
+{
+	struct event_format *a_event = a_field->event;
+	struct event_format *b_event = a_field->event;
+	unsigned int a_offset, b_offset, a_len, b_len, i;
+	unsigned long long a_val = 0, b_val = 0;
+
+	if (a_size != b_size)
+		return a_size - b_size;
+
+	if (a_field->flags & FIELD_IS_ARRAY) {
+		a_offset = a_field->offset;
+		b_offset = b_field->offset;
+		a_len = a_field->size;
+		b_len = b_field->size;
+
+		if (a_field->flags & FIELD_IS_DYNAMIC) {
+			a_offset = pevent_read_number(a_event->pevent,
+						      a_data + a_offset,
+						      a_len);
+			a_len = a_offset >> 16;
+			a_offset &= 0xffff;
+		}
+
+		if (b_field->flags & FIELD_IS_DYNAMIC) {
+			b_offset = pevent_read_number(b_event->pevent,
+						      b_data + b_offset,
+						      b_len);
+			b_len = b_offset >> 16;
+			b_offset &= 0xffff;
+		}
+
+		if (a_len != b_len)
+			return a_len - b_len;
+
+		for (i = 0; (i < a_len) && (a_val == b_val); i++) {
+			a_val = *((unsigned char *)a_data + a_offset + i);
+			b_val = *((unsigned char *)b_data + b_offset + i);
+		}
+	} else {
+		a_val = pevent_read_number(a_event->pevent,
+					   a_data + a_field->offset,
+					   a_field->size);
+		b_val = pevent_read_number(b_event->pevent,
+					   b_data + b_field->offset,
+					   b_field->size);
+	}
+
+	return a_val - b_val;
+}
+
 void pevent_field_info(struct trace_seq *s,
 		       struct format_field *field,
 		       void *data, int size __maybe_unused,
diff --git a/tools/lib/traceevent/event-parse.h b/tools/lib/traceevent/event-parse.h
index b49fad1..7158b55 100644
--- a/tools/lib/traceevent/event-parse.h
+++ b/tools/lib/traceevent/event-parse.h
@@ -588,6 +588,11 @@ int pevent_pid_is_registered(struct pevent *pevent, int pid);
 void pevent_print_event(struct pevent *pevent, struct trace_seq *s,
 			struct pevent_record *record, bool use_trace_clock);
 
+int pevent_field_cmp(struct format_field *a_field,
+		     struct format_field *b_field,
+		     void *a_data, int a_size,
+		     void *b_data, int b_size);
+
 void pevent_field_info(struct trace_seq *s,
 		       struct format_field *field,
 		       void *data, int size __maybe_unused,
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 18/22] perf tools: Factor sort entries loops
  2014-02-02 21:38 [RFC 00/22] perf tools: Display tracepoint enahncements Jiri Olsa
                   ` (16 preceding siblings ...)
  2014-02-02 21:39 ` [PATCH 17/22] tools lib traceevent: Add pevent_field_cmp function Jiri Olsa
@ 2014-02-02 21:39 ` Jiri Olsa
  2014-02-02 21:39 ` [PATCH 19/22] perf tools: Add local hists sort entry list Jiri Olsa
                   ` (5 subsequent siblings)
  23 siblings, 0 replies; 31+ messages in thread
From: Jiri Olsa @ 2014-02-02 21:39 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Corey Ashford, Frederic Weisbecker, Ingo Molnar,
	Namhyung Kim, Paul Mackerras, Peter Zijlstra,
	Arnaldo Carvalho de Melo, David Ahern

Factoring sort entries loops so we could transparently
iterate over hists' specific list of sort entries.

Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: David Ahern <dsahern@gmail.com>
---
 tools/perf/ui/browsers/hists.c |  2 +-
 tools/perf/ui/gtk/hists.c      |  6 +++---
 tools/perf/ui/hist.c           |  5 +++--
 tools/perf/ui/stdio/hist.c     |  4 ++--
 tools/perf/util/hist.c         |  4 ++--
 tools/perf/util/sort.c         | 17 +++++++++++++++++
 tools/perf/util/sort.h         |  5 +++++
 7 files changed, 33 insertions(+), 10 deletions(-)

diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
index 1d519e9..852aee7 100644
--- a/tools/perf/ui/browsers/hists.c
+++ b/tools/perf/ui/browsers/hists.c
@@ -342,7 +342,7 @@ static size_t scnprintf_header_se(struct hists *hists, char *buf, size_t size)
 	unsigned int width;
 	int ret = 0;
 
-	list_for_each_entry(se, &hist_entry__sort_list, list) {
+	hists__for_each_se(hists, se) {
 		if (se->elide)
 			continue;
 
diff --git a/tools/perf/ui/gtk/hists.c b/tools/perf/ui/gtk/hists.c
index bd9a491..cafc4b0 100644
--- a/tools/perf/ui/gtk/hists.c
+++ b/tools/perf/ui/gtk/hists.c
@@ -240,7 +240,7 @@ static void perf_gtk__show_hists(GtkWidget *window, struct hists *hists,
 	perf_hpp__for_each_format(fmt)
 		col_types[nr_cols++] = G_TYPE_STRING;
 
-	list_for_each_entry(se, &hist_entry__sort_list, list) {
+	hists__for_each_se(hists, se) {
 		if (se->elide)
 			continue;
 
@@ -267,7 +267,7 @@ static void perf_gtk__show_hists(GtkWidget *window, struct hists *hists,
 							    col_idx++, NULL);
 	}
 
-	list_for_each_entry(se, &hist_entry__sort_list, list) {
+	hists__for_each_se(hists, se) {
 		if (se->elide)
 			continue;
 
@@ -318,7 +318,7 @@ static void perf_gtk__show_hists(GtkWidget *window, struct hists *hists,
 			gtk_tree_store_set(store, &iter, col_idx++, s, -1);
 		}
 
-		list_for_each_entry(se, &hist_entry__sort_list, list) {
+		hists__for_each_se(hists, se) {
 			if (se->elide)
 				continue;
 
diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c
index 430c4ea..6bd2136 100644
--- a/tools/perf/ui/hist.c
+++ b/tools/perf/ui/hist.c
@@ -306,7 +306,7 @@ int hist_entry__sort_snprintf(struct hist_entry *he, bool selected,
 	struct sort_entry *se;
 	int ret = 0;
 
-	list_for_each_entry(se, &hist_entry__sort_list, list) {
+	hists__for_each_se(he->hists, se) {
 		if (se->elide)
 			continue;
 
@@ -337,9 +337,10 @@ unsigned int hists__sort_list_width(struct hists *hists)
 		ret += fmt->width(fmt, &dummy_hpp);
 	}
 
-	list_for_each_entry(se, &hist_entry__sort_list, list)
+	hists__for_each_se(hists, se) {
 		if (!se->elide)
 			ret += 2 + hists__col_len(hists, se->se_width_idx);
+	}
 
 	if (verbose) /* Addr + origin */
 		ret += 3 + BITS_PER_LONG / 4;
diff --git a/tools/perf/ui/stdio/hist.c b/tools/perf/ui/stdio/hist.c
index ab6f4d6..d13fc99 100644
--- a/tools/perf/ui/stdio/hist.c
+++ b/tools/perf/ui/stdio/hist.c
@@ -408,7 +408,7 @@ size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows,
 		fprintf(fp, "%s", bf);
 	}
 
-	list_for_each_entry(se, &hist_entry__sort_list, list) {
+	hists__for_each_se(hists, se) {
 		if (se->elide)
 			continue;
 		if (sep) {
@@ -454,7 +454,7 @@ size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows,
 			fprintf(fp, ".");
 	}
 
-	list_for_each_entry(se, &hist_entry__sort_list, list) {
+	hists__for_each_se(hists, se) {
 		unsigned int i;
 
 		if (se->elide)
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index 164d20d..92c3d76 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -915,7 +915,7 @@ hist_entry__cmp(struct hist_entry *left, struct hist_entry *right)
 	struct sort_entry *se;
 	int64_t cmp = 0;
 
-	list_for_each_entry(se, &hist_entry__sort_list, list) {
+	hists__for_each_se(left->hists, se) {
 		cmp = se->se_cmp(se, left, right);
 		if (cmp)
 			break;
@@ -930,7 +930,7 @@ hist_entry__collapse(struct hist_entry *left, struct hist_entry *right)
 	struct sort_entry *se;
 	int64_t cmp = 0;
 
-	list_for_each_entry(se, &hist_entry__sort_list, list) {
+	hists__for_each_se(left->hists, se) {
 		int64_t (*f)(struct sort_entry *, struct hist_entry *,
 			     struct hist_entry *);
 
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
index 381139d..42e6038 100644
--- a/tools/perf/util/sort.c
+++ b/tools/perf/util/sort.c
@@ -1381,3 +1381,20 @@ void sort__setup_list(void)
 
 	sd_idx->entry->elide = true;
 }
+
+bool hists__next_se(struct hists *hists __maybe_unused, struct sort_entry **sep)
+{
+	struct list_head *head_global = &hist_entry__sort_list;
+	struct sort_entry *se = *sep;
+
+	if (!se) {
+		se = list_first_entry(head_global, struct sort_entry, list);
+	} else {
+		if (list_is_last(&se->list, head_global))
+			se = NULL;
+		else
+			se = list_next_entry(se, list);
+	}
+
+	return se ? (*sep = se) : false;
+}
diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h
index 0b992fd..f0d501e 100644
--- a/tools/perf/util/sort.h
+++ b/tools/perf/util/sort.h
@@ -218,4 +218,9 @@ void sort__setup_list(void);
 
 int report_parse_ignore_callees_opt(const struct option *opt, const char *arg, int unset);
 
+bool hists__next_se(struct hists *hists, struct sort_entry **sep);
+
+#define hists__for_each_se(hists, se) \
+	for (se = NULL; hists__next_se(hists, &se);)
+
 #endif	/* __PERF_SORT_H */
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 19/22] perf tools: Add local hists sort entry list
  2014-02-02 21:38 [RFC 00/22] perf tools: Display tracepoint enahncements Jiri Olsa
                   ` (17 preceding siblings ...)
  2014-02-02 21:39 ` [PATCH 18/22] perf tools: Factor sort entries loops Jiri Olsa
@ 2014-02-02 21:39 ` Jiri Olsa
  2014-02-02 21:39 ` [PATCH 20/22] perf tools: Make hists col_len dynamicaly alocated Jiri Olsa
                   ` (4 subsequent siblings)
  23 siblings, 0 replies; 31+ messages in thread
From: Jiri Olsa @ 2014-02-02 21:39 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Corey Ashford, Frederic Weisbecker, Ingo Molnar,
	Namhyung Kim, Paul Mackerras, Peter Zijlstra,
	Arnaldo Carvalho de Melo, David Ahern

Adding sort_entry list local to 'struct hists'.
This way we could setup specific sort entries
for separate hists.

This is going to be used for tracepoints fields
view in following patch.

Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: David Ahern <dsahern@gmail.com>
---
 tools/perf/util/evsel.c |  1 +
 tools/perf/util/hist.h  |  1 +
 tools/perf/util/sort.c  | 14 ++++++++++++--
 tools/perf/util/sort.h  |  2 ++
 4 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 55407c5..5baf13b 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -122,6 +122,7 @@ void hists__init(struct hists *hists)
 	hists->entries_in = &hists->entries_in_array[0];
 	hists->entries_collapsed = RB_ROOT;
 	hists->entries = RB_ROOT;
+	INIT_LIST_HEAD(&hists->sort_list);
 	pthread_mutex_init(&hists->lock, NULL);
 }
 
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h
index 9c0bd20..ff52c3bf 100644
--- a/tools/perf/util/hist.h
+++ b/tools/perf/util/hist.h
@@ -92,6 +92,7 @@ struct hists {
 	u64			time_base;
 	u64			event_stream;
 	u16			col_len[HISTC_NR_COLS];
+	struct list_head	sort_list;
 };
 
 struct hist_entry_iter;
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
index 42e6038..d2c52a6 100644
--- a/tools/perf/util/sort.c
+++ b/tools/perf/util/sort.c
@@ -1382,15 +1382,20 @@ void sort__setup_list(void)
 	sd_idx->entry->elide = true;
 }
 
-bool hists__next_se(struct hists *hists __maybe_unused, struct sort_entry **sep)
+bool hists__next_se(struct hists *hists, struct sort_entry **sep)
 {
 	struct list_head *head_global = &hist_entry__sort_list;
+	struct list_head *head_local  = &hists->sort_list;
 	struct sort_entry *se = *sep;
 
 	if (!se) {
 		se = list_first_entry(head_global, struct sort_entry, list);
 	} else {
-		if (list_is_last(&se->list, head_global))
+		if (list_is_last(&se->list, head_global)) {
+			se = list_empty(head_local) ? NULL :
+			     list_first_entry(head_local, struct sort_entry,
+					      list);
+		} else if (list_is_last(&se->list, head_local))
 			se = NULL;
 		else
 			se = list_next_entry(se, list);
@@ -1398,3 +1403,8 @@ bool hists__next_se(struct hists *hists __maybe_unused, struct sort_entry **sep)
 
 	return se ? (*sep = se) : false;
 }
+
+void hists__sort_entry_add(struct hists *hists, struct sort_entry *se)
+{
+	list_add_tail(&se->list, &hists->sort_list);
+}
diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h
index f0d501e..77454ee 100644
--- a/tools/perf/util/sort.h
+++ b/tools/perf/util/sort.h
@@ -223,4 +223,6 @@ bool hists__next_se(struct hists *hists, struct sort_entry **sep);
 #define hists__for_each_se(hists, se) \
 	for (se = NULL; hists__next_se(hists, &se);)
 
+void hists__sort_entry_add(struct hists *hists, struct sort_entry *se);
+
 #endif	/* __PERF_SORT_H */
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 20/22] perf tools: Make hists col_len dynamicaly alocated
  2014-02-02 21:38 [RFC 00/22] perf tools: Display tracepoint enahncements Jiri Olsa
                   ` (18 preceding siblings ...)
  2014-02-02 21:39 ` [PATCH 19/22] perf tools: Add local hists sort entry list Jiri Olsa
@ 2014-02-02 21:39 ` Jiri Olsa
  2014-02-02 21:39 ` [PATCH 21/22] perf tools: Add raw info into hist entry Jiri Olsa
                   ` (3 subsequent siblings)
  23 siblings, 0 replies; 31+ messages in thread
From: Jiri Olsa @ 2014-02-02 21:39 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Corey Ashford, Frederic Weisbecker, Ingo Molnar,
	Namhyung Kim, Paul Mackerras, Peter Zijlstra,
	Arnaldo Carvalho de Melo, David Ahern

Making hists col_len dynamicaly allocated as a support
for dynamic sort entries.

Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: David Ahern <dsahern@gmail.com>
---
 tools/perf/util/evsel.c  | 23 ++++++++++++++++-------
 tools/perf/util/evsel.h  |  6 +++---
 tools/perf/util/hist.c   | 15 +++++++++++++++
 tools/perf/util/hist.h   |  4 +++-
 tools/perf/util/python.c |  3 +--
 5 files changed, 38 insertions(+), 13 deletions(-)

diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 5baf13b..2661870 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -115,7 +115,7 @@ void perf_evsel__calc_id_pos(struct perf_evsel *evsel)
 	evsel->is_pos = __perf_evsel__calc_is_pos(evsel->attr.sample_type);
 }
 
-void hists__init(struct hists *hists)
+int hists__init(struct hists *hists)
 {
 	memset(hists, 0, sizeof(*hists));
 	hists->entries_in_array[0] = hists->entries_in_array[1] = RB_ROOT;
@@ -124,6 +124,12 @@ void hists__init(struct hists *hists)
 	hists->entries = RB_ROOT;
 	INIT_LIST_HEAD(&hists->sort_list);
 	pthread_mutex_init(&hists->lock, NULL);
+	return hists__alloc_col_len(hists, HISTC_NR_COLS);
+}
+
+static void hists__exit(struct hists *hists)
+{
+	free(hists->col_len);
 }
 
 void __perf_evsel__set_sample_bit(struct perf_evsel *evsel,
@@ -158,8 +164,8 @@ void perf_evsel__set_sample_id(struct perf_evsel *evsel,
 	evsel->attr.read_format |= PERF_FORMAT_ID;
 }
 
-void perf_evsel__init(struct perf_evsel *evsel,
-		      struct perf_event_attr *attr, int idx)
+int perf_evsel__init(struct perf_evsel *evsel,
+		     struct perf_event_attr *attr, int idx)
 {
 	evsel->idx	   = idx;
 	evsel->attr	   = *attr;
@@ -167,19 +173,20 @@ void perf_evsel__init(struct perf_evsel *evsel,
 	evsel->unit	   = "";
 	evsel->scale	   = 1.0;
 	INIT_LIST_HEAD(&evsel->node);
-	hists__init(&evsel->hists);
 	evsel->sample_size = __perf_evsel__sample_size(attr->sample_type);
 	perf_evsel__calc_id_pos(evsel);
+	return hists__init(&evsel->hists);
 }
 
 struct perf_evsel *perf_evsel__new_idx(struct perf_event_attr *attr, int idx)
 {
 	struct perf_evsel *evsel = zalloc(sizeof(*evsel));
+	int err = -ENOMEM;
 
 	if (evsel != NULL)
-		perf_evsel__init(evsel, attr, idx);
+		err = perf_evsel__init(evsel, attr, idx);
 
-	return evsel;
+	return err ? NULL : evsel;
 }
 
 struct perf_evsel *perf_evsel__newtp_idx(const char *sys, const char *name, int idx)
@@ -203,7 +210,8 @@ struct perf_evsel *perf_evsel__newtp_idx(const char *sys, const char *name, int
 		event_attr_init(&attr);
 		attr.config = evsel->tp_format->id;
 		attr.sample_period = 1;
-		perf_evsel__init(evsel, &attr, idx);
+		if (perf_evsel__init(evsel, &attr, idx))
+			goto out_free;
 	}
 
 	return evsel;
@@ -776,6 +784,7 @@ void perf_evsel__exit(struct perf_evsel *evsel)
 	assert(list_empty(&evsel->node));
 	perf_evsel__free_fd(evsel);
 	perf_evsel__free_id(evsel);
+	hists__exit(&evsel->hists);
 }
 
 void perf_evsel__delete(struct perf_evsel *evsel)
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h
index f1b3256..cdc2681 100644
--- a/tools/perf/util/evsel.h
+++ b/tools/perf/util/evsel.h
@@ -114,8 +114,8 @@ static inline struct perf_evsel *perf_evsel__newtp(const char *sys, const char *
 
 struct event_format *event_format__new(const char *sys, const char *name);
 
-void perf_evsel__init(struct perf_evsel *evsel,
-		      struct perf_event_attr *attr, int idx);
+int perf_evsel__init(struct perf_evsel *evsel,
+		     struct perf_event_attr *attr, int idx);
 void perf_evsel__exit(struct perf_evsel *evsel);
 void perf_evsel__delete(struct perf_evsel *evsel);
 
@@ -272,7 +272,7 @@ static inline int perf_evsel__read_scaled(struct perf_evsel *evsel,
 	return __perf_evsel__read(evsel, ncpus, nthreads, true);
 }
 
-void hists__init(struct hists *hists);
+int hists__init(struct hists *hists);
 
 int perf_evsel__parse_sample(struct perf_evsel *evsel, union perf_event *event,
 			     struct perf_sample *sample);
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index 92c3d76..794d0cb 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -21,6 +21,21 @@ struct callchain_param	callchain_param = {
 	.key	= CCKEY_FUNCTION
 };
 
+int hists__alloc_col_len(struct hists *hists, int n)
+{
+	u16 *col_len = hists->col_len;
+	int old_n = hists->col_n;
+
+	col_len = realloc(col_len, n * sizeof(u16));
+	if (col_len) {
+		memset(col_len + old_n, 0, n - old_n);
+		hists->col_len = col_len;
+		hists->col_n   = n;
+	}
+
+	return col_len ? 0 : -ENOMEM;
+}
+
 u16 hists__col_len(struct hists *hists, enum hist_column col)
 {
 	return hists->col_len[col];
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h
index ff52c3bf..c2f4bd1 100644
--- a/tools/perf/util/hist.h
+++ b/tools/perf/util/hist.h
@@ -91,7 +91,8 @@ struct hists {
 	struct events_stats	stats;
 	u64			time_base;
 	u64			event_stream;
-	u16			col_len[HISTC_NR_COLS];
+	u16			*col_len;
+	int			col_n;
 	struct list_head	sort_list;
 };
 
@@ -168,6 +169,7 @@ void hists__filter_by_dso(struct hists *hists);
 void hists__filter_by_thread(struct hists *hists);
 void hists__filter_by_symbol(struct hists *hists);
 
+int hists__alloc_col_len(struct hists *hists, int n);
 u16 hists__col_len(struct hists *hists, enum hist_column col);
 void hists__set_col_len(struct hists *hists, enum hist_column col, u16 len);
 bool hists__new_col_len(struct hists *hists, enum hist_column col, u16 len);
diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c
index 122669c..b5824d2 100644
--- a/tools/perf/util/python.c
+++ b/tools/perf/util/python.c
@@ -605,8 +605,7 @@ static int pyrf_evsel__init(struct pyrf_evsel *pevsel,
 	attr.mmap_data	    = mmap_data;
 	attr.sample_id_all  = sample_id_all;
 
-	perf_evsel__init(&pevsel->evsel, &attr, idx);
-	return 0;
+	return perf_evsel__init(&pevsel->evsel, &attr, idx);
 }
 
 static void pyrf_evsel__delete(struct pyrf_evsel *pevsel)
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 21/22] perf tools: Add raw info into hist entry
  2014-02-02 21:38 [RFC 00/22] perf tools: Display tracepoint enahncements Jiri Olsa
                   ` (19 preceding siblings ...)
  2014-02-02 21:39 ` [PATCH 20/22] perf tools: Make hists col_len dynamicaly alocated Jiri Olsa
@ 2014-02-02 21:39 ` Jiri Olsa
  2014-02-02 21:39 ` [PATCH 22/22] perf tools: Add support for tracepoint fields Jiri Olsa
                   ` (2 subsequent siblings)
  23 siblings, 0 replies; 31+ messages in thread
From: Jiri Olsa @ 2014-02-02 21:39 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Corey Ashford, Frederic Weisbecker, Ingo Molnar,
	Namhyung Kim, Paul Mackerras, Peter Zijlstra,
	Arnaldo Carvalho de Melo, David Ahern

Adding support to store raw info into hist entry,
so we could use it for entries sorting and display.

Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: David Ahern <dsahern@gmail.com>
---
 tools/perf/builtin-annotate.c |  4 ++--
 tools/perf/builtin-diff.c     |  4 ++--
 tools/perf/builtin-report.c   | 31 ++++++++++++++++++++++++++++++-
 tools/perf/tests/hists_link.c |  6 ++++--
 tools/perf/util/hist.c        | 21 +++++++++++++++------
 tools/perf/util/hist.h        |  7 +++++--
 tools/perf/util/sort.h        |  6 ++++++
 7 files changed, 64 insertions(+), 15 deletions(-)

diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index 875c117..2f3ea9f 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -65,8 +65,8 @@ static int perf_evsel__add_sample(struct perf_evsel *evsel,
 		return 0;
 	}
 
-	he = __hists__add_entry(&evsel->hists, al, NULL, NULL, NULL, 1, 1, 0, 0,
-				true);
+	he = __hists__add_entry(&evsel->hists, al, NULL, NULL, NULL, NULL,
+				1, 1, 0, 0, true);
 	if (he == NULL)
 		return -ENOMEM;
 
diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c
index 92faed5..0b001d9 100644
--- a/tools/perf/builtin-diff.c
+++ b/tools/perf/builtin-diff.c
@@ -307,8 +307,8 @@ static int hists__add_entry(struct hists *hists,
 			    struct addr_location *al, u64 period,
 			    u64 weight, u64 transaction)
 {
-	if (__hists__add_entry(hists, al, NULL, NULL, NULL, period, weight,
-			       transaction, 0, true) != NULL)
+	if (__hists__add_entry(hists, al, NULL, NULL, NULL, NULL,
+			       period, weight, transaction, 0, true) != NULL)
 		return 0;
 	return -ENOMEM;
 }
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index a752687..0938c4e 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -47,6 +47,7 @@ struct report {
 	bool			dont_use_callchains;
 	bool			show_full_info;
 	bool			show_threads;
+	bool			raw_info;
 	bool			inverted_callchain;
 	bool			mem_mode;
 	bool			header;
@@ -108,6 +109,23 @@ out:
 	return err;
 }
 
+static int get_raw_info(struct raw_info **rawp, struct perf_sample *sample)
+{
+	struct raw_info *raw;
+
+	if (!sample->raw_data)
+		return 0;
+
+	raw = malloc(sizeof(*raw) + sample->raw_size);
+	if (raw) {
+		memcpy(&raw->data, sample->raw_data, sample->raw_size);
+		raw->size = sample->raw_size;
+	}
+
+	*rawp = raw;
+	return raw ? 0 : -ENOMEM;
+}
+
 static int process_sample_event(struct perf_tool *tool,
 				union perf_event *event,
 				struct perf_sample *sample,
@@ -119,6 +137,7 @@ static int process_sample_event(struct perf_tool *tool,
 	struct hist_entry_iter iter = {
 		.hide_unresolved = rep->hide_unresolved,
 	};
+	struct raw_info *raw = NULL;
 	int ret;
 
 	if (perf_event__preprocess_sample(event, machine, &al, sample) < 0) {
@@ -133,6 +152,12 @@ static int process_sample_event(struct perf_tool *tool,
 	if (rep->cpu_list && !test_bit(sample->cpu, rep->cpu_bitmap))
 		return 0;
 
+	if (rep->raw_info) {
+		ret = get_raw_info(&raw, sample);
+		if (ret)
+			return ret;
+	}
+
 	if (sort__mode == SORT_MODE__BRANCH)
 		iter.ops = &hist_iter_branch;
 	else if (rep->mem_mode == 1)
@@ -145,13 +170,17 @@ static int process_sample_event(struct perf_tool *tool,
 		iter.add_entry_cb = hist_iter_cb;
 	}
 
+	iter.raw = raw;
+
 	if (al.map != NULL)
 		al.map->dso->hit = 1;
 
 	ret = hist_entry_iter__add(&iter, &al, evsel, event, sample,
 				   rep->max_stack, NULL);
-	if (ret < 0)
+	if (ret < 0) {
 		pr_debug("problem adding hist entry, skipping event\n");
+		free(raw);
+	}
 
 	return ret;
 }
diff --git a/tools/perf/tests/hists_link.c b/tools/perf/tests/hists_link.c
index e3bc8a8..3eb56c57 100644
--- a/tools/perf/tests/hists_link.c
+++ b/tools/perf/tests/hists_link.c
@@ -223,7 +223,8 @@ static int add_hist_entries(struct perf_evlist *evlist, struct machine *machine)
 				goto out;
 
 			he = __hists__add_entry(&evsel->hists, &al, NULL,
-						NULL, NULL, 1, 1, 0, 0, true);
+						NULL, NULL, NULL, 1, 1, 0, 0,
+						true);
 			if (he == NULL)
 				goto out;
 
@@ -246,7 +247,8 @@ static int add_hist_entries(struct perf_evlist *evlist, struct machine *machine)
 				goto out;
 
 			he = __hists__add_entry(&evsel->hists, &al, NULL,
-						NULL, NULL, 1, 1, 0, 0, true);
+						NULL, NULL, NULL, 1, 1, 0, 0,
+						true);
 			if (he == NULL)
 				goto out;
 
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index 794d0cb..207437b 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -450,6 +450,7 @@ struct hist_entry *__hists__add_entry(struct hists *hists,
 				      struct symbol *sym_parent,
 				      struct branch_info *bi,
 				      struct mem_info *mi,
+				      struct raw_info *raw,
 				      u64 period, u64 weight, u64 transaction,
 				      u64 t, bool sample_self)
 {
@@ -474,6 +475,7 @@ struct hist_entry *__hists__add_entry(struct hists *hists,
 		.hists	= hists,
 		.branch_info = bi,
 		.mem_info = mi,
+		.raw_info = raw,
 		.transaction = transaction,
 		.time = t,
 		.idx  = idx++,
@@ -535,8 +537,8 @@ iter_add_single_mem_entry(struct hist_entry_iter *iter, struct addr_location *al
 	 * and this is indirectly achieved by passing period=weight here
 	 * and the he_stat__add_period() function.
 	 */
-	he = __hists__add_entry(&iter->evsel->hists, al, iter->parent, NULL, mi,
-				cost, cost, 0, 0, true);
+	he = __hists__add_entry(&iter->evsel->hists, al, iter->parent, NULL,
+				mi, NULL, cost, cost, 0, 0, true);
 	if (!he)
 		return -ENOMEM;
 
@@ -647,7 +649,8 @@ iter_add_next_branch_entry(struct hist_entry_iter *iter, struct addr_location *a
 	 * The report shows the percentage of total branches captured
 	 * and not events sampled. Thus we use a pseudo period of 1.
 	 */
-	he = __hists__add_entry(&evsel->hists, al, iter->parent, &bi[i], NULL,
+	he = __hists__add_entry(&evsel->hists, al, iter->parent,
+				&bi[i], NULL, NULL,
 				1, 1, 0, 0, true);
 	if (he == NULL)
 		return -ENOMEM;
@@ -692,7 +695,8 @@ iter_add_single_normal_entry(struct hist_entry_iter *iter, struct addr_location
 	struct perf_sample *sample = iter->sample;
 	struct hist_entry *he;
 
-	he = __hists__add_entry(&evsel->hists, al, iter->parent, NULL, NULL,
+	he = __hists__add_entry(&evsel->hists, al, iter->parent,
+				NULL, NULL, iter->raw,
 				sample->period, sample->weight,
 				sample->transaction, sample->time, true);
 	if (he == NULL)
@@ -748,7 +752,8 @@ iter_add_single_cumulative_entry(struct hist_entry_iter *iter,
 	struct hist_entry **he_cache = iter->priv;
 	struct hist_entry *he;
 
-	he = __hists__add_entry(&evsel->hists, al, iter->parent, NULL, NULL,
+	he = __hists__add_entry(&evsel->hists, al, iter->parent,
+				NULL, NULL, iter->raw,
 				sample->period, sample->weight,
 				sample->transaction, sample->time, true);
 	if (he == NULL)
@@ -803,6 +808,8 @@ iter_add_next_cumulative_entry(struct hist_entry_iter *iter,
 	int i;
 	struct callchain_cursor cursor;
 
+	he_tmp.raw_info = iter->raw;
+
 	callchain_cursor_snapshot(&cursor, &callchain_cursor);
 
 	callchain_cursor_advance(&callchain_cursor);
@@ -819,7 +826,8 @@ iter_add_next_cumulative_entry(struct hist_entry_iter *iter,
 		}
 	}
 
-	he = __hists__add_entry(&evsel->hists, al, iter->parent, NULL, NULL,
+	he = __hists__add_entry(&evsel->hists, al, iter->parent,
+				NULL, NULL, iter->raw,
 				sample->period, sample->weight,
 				sample->transaction, sample->time, false);
 	if (he == NULL)
@@ -961,6 +969,7 @@ hist_entry__collapse(struct hist_entry *left, struct hist_entry *right)
 
 void hist_entry__free(struct hist_entry *he)
 {
+	zfree(&he->raw_info);
 	zfree(&he->branch_info);
 	zfree(&he->mem_info);
 	zfree(&he->stat_acc);
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h
index c2f4bd1..ef64144 100644
--- a/tools/perf/util/hist.h
+++ b/tools/perf/util/hist.h
@@ -13,6 +13,7 @@ extern struct callchain_param callchain_param;
 struct hist_entry;
 struct addr_location;
 struct symbol;
+struct raw_info;
 
 enum hist_filter {
 	HIST_FILTER__DSO,
@@ -117,6 +118,7 @@ struct hist_entry_iter {
 	struct perf_sample *sample;
 	struct hist_entry *he;
 	struct symbol *parent;
+	struct raw_info *raw;
 	void *priv;
 
 	const struct hist_iter_ops *ops;
@@ -134,8 +136,9 @@ struct hist_entry *__hists__add_entry(struct hists *hists,
 				      struct addr_location *al,
 				      struct symbol *parent,
 				      struct branch_info *bi,
-				      struct mem_info *mi, u64 period,
-				      u64 weight, u64 transaction,
+				      struct mem_info *mi,
+				      struct raw_info *raw,
+				      u64 period, u64 weight, u64 transaction,
 				      u64 time, bool sample_self);
 int hist_entry_iter__add(struct hist_entry_iter *iter, struct addr_location *al,
 			 struct perf_evsel *evsel, const union perf_event *event,
diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h
index 77454ee..19b0278 100644
--- a/tools/perf/util/sort.h
+++ b/tools/perf/util/sort.h
@@ -67,6 +67,11 @@ struct hist_entry_diff {
 	s64	wdiff;
 };
 
+struct raw_info {
+	unsigned int	size;
+	unsigned char	data[];
+};
+
 /**
  * struct hist_entry - histogram entry
  *
@@ -111,6 +116,7 @@ struct hist_entry {
 	struct branch_info	*branch_info;
 	struct hists		*hists;
 	struct mem_info		*mem_info;
+	struct raw_info		*raw_info;
 	struct callchain_root	callchain[0]; /* must be last member */
 };
 
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 22/22] perf tools: Add support for tracepoint fields
  2014-02-02 21:38 [RFC 00/22] perf tools: Display tracepoint enahncements Jiri Olsa
                   ` (20 preceding siblings ...)
  2014-02-02 21:39 ` [PATCH 21/22] perf tools: Add raw info into hist entry Jiri Olsa
@ 2014-02-02 21:39 ` Jiri Olsa
  2014-02-02 21:45 ` [RFC 00/22] perf tools: Display tracepoint enahncements Jiri Olsa
  2014-02-05  1:58 ` Namhyung Kim
  23 siblings, 0 replies; 31+ messages in thread
From: Jiri Olsa @ 2014-02-02 21:39 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Corey Ashford, Frederic Weisbecker, Ingo Molnar,
	Namhyung Kim, Paul Mackerras, Peter Zijlstra,
	Arnaldo Carvalho de Melo, David Ahern

Adding '--tp' option for report command to show
tracepoint related info. Use can specify following
switches:
   - fields: shows separated tracepoint fields
   - format: shows tracepoints 'print fmt' in single column
             (This is default if no switch is given.)

  $ perf report --tp --no-children
  Samples: 4K of event 'sched:sched_switch', Event count (approx.): 4788
   Overhead          Command      Shared Object          Symbol  Print fmt
  +  26.27%          swapper  [kernel.kallsyms]  [k] __schedule  swapper/2:0 [120] R ==> offlineimap:22134 [120]
  +  26.27%      offlineimap  [kernel.kallsyms]  [k] __schedule  offlineimap:22134 [120] S ==> swapper/2:0 [120]
  -   8.15%          swapper  [kernel.kallsyms]  [k] __schedule  swapper/3:0 [120] R ==> offlineimap:22134 [120]
       __schedule
       schedule_preempt_disabled
       cpu_startup_entry
       start_secondary
  +   8.15%      offlineimap  [kernel.kallsyms]  [k] __schedule  offlineimap:22134 [120] S ==> swapper/3:0 [120]

  $ perf report --tp=fields --no-children
  Samples: 4K of event 'sched:sched_switch', Event count (approx.): 4788
    Overhead          Command      Shared Object          Symbol                       prev_comm    prev_pid   prev_prio          prev_state                       next_comm    next_pid   next_prio
  +   26.27%          swapper  [kernel.kallsyms]  [k] __schedule                       swapper/2           0         120                   0                     offlineimap       22134         120
  +   26.27%      offlineimap  [kernel.kallsyms]  [k] __schedule                     offlineimap       22134         120                   1                       swapper/2           0         120
  -    8.15%          swapper  [kernel.kallsyms]  [k] __schedule                       swapper/3           0         120                   0                     offlineimap       22134         120
       __schedule
       schedule_preempt_disabled
       cpu_startup_entry
       start_secondary
  +    8.15%      offlineimap  [kernel.kallsyms]  [k] __schedule                     offlineimap       22134         120                   1                       swapper/3           0         120

Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: David Ahern <dsahern@gmail.com>
---
 tools/perf/Documentation/perf-report.txt |   6 +
 tools/perf/Makefile.perf                 |   1 +
 tools/perf/builtin-report.c              |  15 ++
 tools/perf/util/report-tp.c              | 244 +++++++++++++++++++++++++++++++
 tools/perf/util/report-tp.h              |  18 +++
 5 files changed, 284 insertions(+)
 create mode 100644 tools/perf/util/report-tp.c
 create mode 100644 tools/perf/util/report-tp.h

diff --git a/tools/perf/Documentation/perf-report.txt b/tools/perf/Documentation/perf-report.txt
index 36eb187..ae1a0cf 100644
--- a/tools/perf/Documentation/perf-report.txt
+++ b/tools/perf/Documentation/perf-report.txt
@@ -263,6 +263,12 @@ OPTIONS
 --header-only::
 	Show only perf.data header (forces --stdio).
 
+--tp=::
+	Show tracepoint related info, following switches are supported:
+	- fields: shows separated tracepoint fields
+	- format: shows tracepoints 'print fmt' in single column
+		  (This is default if no switch is given.)
+
 SEE ALSO
 --------
 linkperf:perf-stat[1], linkperf:perf-annotate[1]
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 7257e7e..baccf1d 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -373,6 +373,7 @@ LIB_OBJS += $(OUTPUT)util/stat.o
 LIB_OBJS += $(OUTPUT)util/record.o
 LIB_OBJS += $(OUTPUT)util/srcline.o
 LIB_OBJS += $(OUTPUT)util/data.o
+LIB_OBJS += $(OUTPUT)util/report-tp.o
 
 LIB_OBJS += $(OUTPUT)ui/setup.o
 LIB_OBJS += $(OUTPUT)ui/helpline.o
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 0938c4e..a46bdc9 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -35,6 +35,7 @@
 #include "util/hist.h"
 #include "util/data.h"
 #include "arch/common.h"
+#include "util/report-tp.h"
 
 #include <dlfcn.h>
 #include <linux/bitmap.h>
@@ -664,6 +665,7 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
 		"perf report [<options>]",
 		NULL
 	};
+	enum report_tp_mode tp_mode;
 	struct report report = {
 		.tool = {
 			.sample		 = process_sample_event,
@@ -779,6 +781,9 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
 	OPT_CALLBACK(0, "percentage", NULL, "relative|absolute",
 		     "how to display percentage of filtered entries", parse_percentage),
 	OPT_BOOLEAN(0, "list", &symbol_conf.show_list, "Show events list"),
+	OPT_CALLBACK_DEFAULT(0, "tp", &tp_mode, "fields,[format]", NULL,
+			     &report_tp_parse_mode, "format"),
+
 	OPT_END()
 	};
 	struct perf_data_file file = {
@@ -924,6 +929,16 @@ repeat:
 	if (symbol_conf.show_list)
 		sort__setup_list();
 
+	if (tp_mode != REPORT_TO_MODE__NONE) {
+		ret = perf_evlist__add_tp_sort_entries(session->evlist,
+						       tp_mode);
+		if (ret) {
+			pr_err("failed to add tracepoints sort entries\n");
+			goto error;
+		}
+		report.raw_info = true;
+	}
+
 	ret = __cmd_report(&report);
 	if (ret == K_SWITCH_INPUT_DATA) {
 		perf_session__delete(session);
diff --git a/tools/perf/util/report-tp.c b/tools/perf/util/report-tp.c
new file mode 100644
index 0000000..9608fd2
--- /dev/null
+++ b/tools/perf/util/report-tp.c
@@ -0,0 +1,244 @@
+#include <traceevent/event-parse.h>
+#include "evlist.h"
+#include "evsel.h"
+#include "sort.h"
+#include "report-tp.h"
+
+struct tp_sort_entry {
+	union {
+		struct format_field	*field;
+		struct event_format	*format;
+	};
+	struct sort_entry se;
+};
+
+#define tp_sort_entry(se) \
+	container_of(se, struct tp_sort_entry, se)
+
+int report_tp_parse_mode(const struct option *opt,
+			 const char *str, int unset)
+{
+	int *tp_mode = opt->value;
+
+	if (unset) {
+		*tp_mode = REPORT_TO_MODE__NONE;
+		return 0;
+	}
+
+	if (!str || !strcmp(str, "fields"))
+		*tp_mode = REPORT_TO_MODE__FIELDS;
+	else if (!strcmp(str, "format"))
+		*tp_mode = REPORT_TO_MODE__FORMAT;
+
+	return 0;
+}
+
+static int64_t field_sort_entry__cmp(struct sort_entry *se,
+				     struct hist_entry *left,
+				     struct hist_entry *right)
+{
+	struct tp_sort_entry *field_se = tp_sort_entry(se);
+	struct raw_info *raw_left = left->raw_info;
+	struct raw_info *raw_right = right->raw_info;
+
+	return pevent_field_cmp(field_se->field, field_se->field,
+				raw_left->data, raw_left->size,
+				raw_right->data, raw_right->size);
+}
+
+static int field_sort_entry__snprintf(struct sort_entry *se,
+				   bool selected __maybe_unused,
+				   struct hist_entry *he,
+				   char *bf, size_t size,
+				   unsigned int width)
+{
+	struct tp_sort_entry *field_se = tp_sort_entry(se);
+	struct raw_info *raw = he->raw_info;
+	struct trace_seq s;
+	int n;
+
+	trace_seq_init(&s);
+
+	pevent_field_info(&s, field_se->field, raw->data, raw->size, false);
+	n = scnprintf(bf, size, "%*s", width, s.buffer);
+	trace_seq_destroy(&s);
+	return n;
+}
+
+static struct tp_sort_entry*
+field_sort_entry__new(struct format_field *field, int width_idx)
+{
+	struct tp_sort_entry *field_se = zalloc(sizeof(*field_se));
+
+	if (field_se) {
+		INIT_LIST_HEAD(&field_se->se.list);
+		field_se->se.se_header		= strdup(field->name);
+		field_se->se.se_cmp		= field_sort_entry__cmp;
+		field_se->se.se_snprintf	= field_sort_entry__snprintf;
+		field_se->se.se_width_idx	= width_idx;
+		field_se->field			= field;
+	}
+
+	return field_se;
+}
+
+static int perf_format_field__width(struct format_field *field)
+{
+	int len = field->size * 2 + 2 /* '0x' */;
+
+	if (field->flags & FIELD_IS_ARRAY)
+		len = 30;
+
+	return len;
+}
+
+static int add_tp_field_entries(struct perf_evsel *evsel)
+{
+	struct format_field **fields, **iter;
+	struct hists *hists = &evsel->hists;
+	struct tp_sort_entry *field_se;
+	int width, width_idx = HISTC_NR_COLS;
+	int ret = -1;
+
+	fields = iter = pevent_event_fields(evsel->tp_format);
+	if (!fields)
+		return 0;
+
+	while (*iter) {
+		field_se = field_sort_entry__new(*iter, width_idx);
+		if (!field_se)
+			goto out;
+
+		if (hists__alloc_col_len(hists, width_idx + 1))
+			goto out;
+
+		width = perf_format_field__width(*iter);
+		hists__set_col_len(hists, width_idx, width);
+
+		hists__sort_entry_add(hists, &field_se->se);
+
+		width_idx++;
+		iter++;
+	}
+
+	ret = 0;
+
+ out:
+	free(fields);
+	return ret;
+}
+
+static int64_t format_sort_entry__cmp(struct sort_entry *se,
+				      struct hist_entry *left,
+				      struct hist_entry *right)
+{
+	struct tp_sort_entry *format_se = tp_sort_entry(se);
+	struct raw_info *raw_left = left->raw_info;
+	struct raw_info *raw_right = right->raw_info;
+	struct format_field **fields, **iter;
+	int ret = 0;
+
+	fields = iter = pevent_event_fields(format_se->format);
+	if (!fields)
+		return 0;
+
+	while (*iter) {
+		struct format_field *field = *iter;
+
+		ret = pevent_field_cmp(field, field,
+				       raw_left->data, raw_left->size,
+				       raw_right->data, raw_right->size);
+		if (ret)
+			break;
+
+		iter++;
+	}
+
+	free(fields);
+	return ret;
+}
+
+static int format_sort_entry__snprintf(struct sort_entry *se,
+				       bool selected __maybe_unused,
+				       struct hist_entry *he,
+				       char *bf, size_t size,
+				       unsigned int width)
+{
+	struct tp_sort_entry *format_se = tp_sort_entry(se);
+	struct raw_info *raw = he->raw_info;
+	struct pevent_record record;
+	struct trace_seq s;
+	int n;
+
+	trace_seq_init(&s);
+
+	memset(&record, 0, sizeof(record));
+	record.cpu  = he->cpu;
+	record.size = raw->size;
+	record.data = raw->data;
+
+	pevent_event_info(&s, format_se->format, &record);
+	n = scnprintf(bf, size, "%*s", width, s.buffer);
+	trace_seq_destroy(&s);
+	return n;
+}
+
+static int add_tp_format_entry(struct perf_evsel *evsel)
+{
+	struct tp_sort_entry *format_se = zalloc(sizeof(*format_se));
+	struct hists *hists = &evsel->hists;
+	int width_idx = HISTC_NR_COLS;
+
+	if (!format_se)
+		return -ENOMEM;
+
+	INIT_LIST_HEAD(&format_se->se.list);
+	format_se->se.se_header		= "Print fmt";
+	format_se->se.se_cmp		= format_sort_entry__cmp;
+	format_se->se.se_snprintf	= format_sort_entry__snprintf;
+	format_se->se.se_width_idx	= width_idx;
+	format_se->format		= evsel->tp_format;
+
+	if (hists__alloc_col_len(hists, width_idx + 1)) {
+		free(format_se);
+		return -ENOMEM;
+	}
+
+	hists__set_col_len(hists, width_idx, 9);
+	hists__sort_entry_add(hists, &format_se->se);
+	return 0;
+}
+
+static bool perf_evsel__is_tracepoint(struct perf_evsel *evsel)
+{
+	return evsel->attr.type == PERF_TYPE_TRACEPOINT;
+}
+
+int perf_evlist__add_tp_sort_entries(struct perf_evlist *evlist,
+				     enum report_tp_mode mode)
+{
+	struct perf_evsel *evsel;
+	int ret = 0;
+
+	list_for_each_entry(evsel, &evlist->entries, node) {
+		if (!perf_evsel__is_tracepoint(evsel))
+			continue;
+
+		switch (mode) {
+		case REPORT_TO_MODE__FIELDS:
+			ret = add_tp_field_entries(evsel);
+			break;
+		case REPORT_TO_MODE__FORMAT:
+			ret = add_tp_format_entry(evsel);
+			break;
+		case REPORT_TO_MODE__NONE:
+		default:
+			BUG_ON(1);
+		}
+
+		if (ret)
+			break;
+	}
+
+	return ret;
+}
diff --git a/tools/perf/util/report-tp.h b/tools/perf/util/report-tp.h
new file mode 100644
index 0000000..e131982
--- /dev/null
+++ b/tools/perf/util/report-tp.h
@@ -0,0 +1,18 @@
+#ifndef PERF_REPORT_TP_H
+#define PERF_REPORT_TP_H
+
+#include "parse-options.h"
+
+enum report_tp_mode {
+	REPORT_TO_MODE__NONE,
+	REPORT_TO_MODE__FIELDS,
+	REPORT_TO_MODE__FORMAT,
+};
+
+int perf_evlist__add_tp_sort_entries(struct perf_evlist *evlist,
+				     enum report_tp_mode mode);
+
+int report_tp_parse_mode(const struct option *opt,
+			 const char *str, int unset);
+
+#endif /* PERF_REPORT_TP_H */
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* Re: [RFC 00/22] perf tools: Display tracepoint enahncements
  2014-02-02 21:38 [RFC 00/22] perf tools: Display tracepoint enahncements Jiri Olsa
                   ` (21 preceding siblings ...)
  2014-02-02 21:39 ` [PATCH 22/22] perf tools: Add support for tracepoint fields Jiri Olsa
@ 2014-02-02 21:45 ` Jiri Olsa
  2014-02-05  1:40   ` Namhyung Kim
  2014-02-05  1:58 ` Namhyung Kim
  23 siblings, 1 reply; 31+ messages in thread
From: Jiri Olsa @ 2014-02-02 21:45 UTC (permalink / raw)
  To: linux-kernel
  Cc: Corey Ashford, Frederic Weisbecker, Ingo Molnar, Namhyung Kim,
	Paul Mackerras, Peter Zijlstra, Arnaldo Carvalho de Melo,
	Steven Rostedt, David Ahern

On Sun, Feb 02, 2014 at 10:38:48PM +0100, Jiri Olsa wrote:
> hi,
> sending out tracepoint (mostly) events display enahncements.

forgot to mention.. the branch is in here:
  git://git.kernel.org/pub/scm/linux/kernel/git/jolsa/perf.git
  perf/core_tp

and it's based on namhyuung's perf/cumulate-v7 branch

jirka
> 
> * adding the '--tp' option for report command to show
>   tracepoint related info. Use can specify following switches:
>     fields: shows separated tracepoint fields
>     format: shows tracepoints 'print fmt' in single column
>              (This is default if no switch is given.)
> 
>   $ perf report --tp --no-children
>   Samples: 4K of event 'sched:sched_switch', Event count (approx.): 4788
>    Overhead          Command      Shared Object          Symbol  Print fmt
>   +  26.27%          swapper  [kernel.kallsyms]  [k] __schedule  swapper/2:0 [120] R ==> offlineimap:22134 [120]
>   +  26.27%      offlineimap  [kernel.kallsyms]  [k] __schedule  offlineimap:22134 [120] S ==> swapper/2:0 [120]
>   -   8.15%          swapper  [kernel.kallsyms]  [k] __schedule  swapper/3:0 [120] R ==> offlineimap:22134 [120]
>        __schedule
>        schedule_preempt_disabled
>        cpu_startup_entry
>        start_secondary
>   +   8.15%      offlineimap  [kernel.kallsyms]  [k] __schedule  offlineimap:22134 [120] S ==> swapper/3:0 [120]
> 
>   $ perf report --tp=fields --no-children
>   Samples: 4K of event 'sched:sched_switch', Event count (approx.): 4788
>     Overhead          Command      Shared Object          Symbol                       prev_comm    prev_pid   prev_prio          prev_state                       next_comm    next_pid   next_prio
>   +   26.27%          swapper  [kernel.kallsyms]  [k] __schedule                       swapper/2           0         120                   0                     offlineimap       22134         120
>   +   26.27%      offlineimap  [kernel.kallsyms]  [k] __schedule                     offlineimap       22134         120                   1                       swapper/2           0         120
>   -    8.15%          swapper  [kernel.kallsyms]  [k] __schedule                       swapper/3           0         120                   0                     offlineimap       22134         120
>        __schedule
>        schedule_preempt_disabled
>        cpu_startup_entry
>        start_secondary
>   +    8.15%      offlineimap  [kernel.kallsyms]  [k] __schedule                     offlineimap       22134         120                   1                       swapper/3           0         120
> 
> 
> * adding '--list' report option to display entries sequentialy:
> 
>   Samples: 2K of event 'sched:sched_switch', Event count (approx.): 2450
>         Self  Children                              Time          Command                Shared Object                                                       Symbol  Print fmt
>   +    0.04%     0.04%        9582.431783 +000000.000000          swapper  [kernel.kallsyms]            [k] __schedule                                               swapper/1:0 [120] R ==> perf:11168 [120]
>   -    0.00%     0.04%        9582.431783 +000000.000000          swapper  [kernel.kallsyms]            [k] __schedule                                               swapper/1:0 [120] R ==> perf:11168 [120]
>        __schedule
>        schedule
>        cpu_idle
>        start_secondary
>   +    0.00%     0.04%        9582.431783 +000000.000000          swapper  [kernel.kallsyms]            [k] schedule                                                 swapper/1:0 [120] R ==> perf:11168 [120]
>   +    0.00%     0.04%        9582.431783 +000000.000000          swapper  [kernel.kallsyms]            [k] cpu_idle                                                 swapper/1:0 [120] R ==> perf:11168 [120]
> 
> * adding 'H' key handler to togle header columns
> 
> 
> thanks for comments,
> jirka
> 
> 
> Signed-off-by: Jiri Olsa <jolsa@redhat.com>
> Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
> Cc: Frederic Weisbecker <fweisbec@gmail.com>
> Cc: Ingo Molnar <mingo@elte.hu>
> Cc: Namhyung Kim <namhyung@kernel.org>
> Cc: Paul Mackerras <paulus@samba.org>
> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
> Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
> Cc: Steven Rostedt <rostedt@goodmis.org>
> Cc: David Ahern <dsahern@gmail.com>
> ---
> Jiri Olsa (22):
>       perf tools: Fix memory leak in event_format__print function
>       perf tools: Add time sort entry
>       perf tools: Add idx sort entry
>       perf tools: Add --list report option
>       perf tools: Add sort_entry struct into sort entries callbacks
>       perf tools: Add selected bool into se_snprintf sort entries callback
>       perf tools: Implement selected bool se_snprintf callback logic
>       perf tools: Implement selected logic for time sort entry
>       perf tools: Factor ui_browser ops out of ui_browser struct
>       perf tools: Add header callback into ui_browser_ops struct
>       perf tools: Remove ev_name argument from perf_evsel__hists_browse
>       perf tools: Add header callback to hist browser
>       perf tools: Factor hpp_arg struct to carry hist_browser
>       perf tools tui: Display columns header text on 'H' press
>       tools lib traceevent: Factor print_event_fields function
>       tools lib traceevent: Make the name output optional in pevent_field_info
>       tools lib traceevent: Add pevent_field_cmp function
>       perf tools: Factor sort entries loops
>       perf tools: Add local hists sort entry list
>       perf tools: Make hists col_len dynamicaly alocated
>       perf tools: Add raw info into hist entry
>       perf tools: Add support for tracepoint fields
> 
>  tools/lib/traceevent/event-parse.c       | 181 +++++++++++++++++++++----------
>  tools/lib/traceevent/event-parse.h       |  10 ++
>  tools/perf/Documentation/perf-report.txt |   6 ++
>  tools/perf/Makefile.perf                 |   1 +
>  tools/perf/builtin-annotate.c            |   4 +-
>  tools/perf/builtin-diff.c                |   4 +-
>  tools/perf/builtin-report.c              |  52 ++++++++-
>  tools/perf/tests/hists_link.c            |   6 +-
>  tools/perf/ui/browser.c                  | 101 ++++++++++++-----
>  tools/perf/ui/browser.h                  |  31 ++++--
>  tools/perf/ui/browsers/annotate.c        |  19 ++--
>  tools/perf/ui/browsers/header.c          |   8 +-
>  tools/perf/ui/browsers/hists.c           | 168 ++++++++++++++++++++++-------
>  tools/perf/ui/browsers/map.c             |   8 +-
>  tools/perf/ui/browsers/scripts.c         |   2 +-
>  tools/perf/ui/gtk/hists.c                |   8 +-
>  tools/perf/ui/hist.c                     |  10 +-
>  tools/perf/ui/stdio/hist.c               |   6 +-
>  tools/perf/ui/tui/util.c                 |   8 +-
>  tools/perf/util/evsel.c                  |  24 +++--
>  tools/perf/util/evsel.h                  |   6 +-
>  tools/perf/util/hist.c                   |  65 ++++++++---
>  tools/perf/util/hist.h                   |  20 +++-
>  tools/perf/util/python.c                 |   3 +-
>  tools/perf/util/report-tp.c              | 244 +++++++++++++++++++++++++++++++++++++++++
>  tools/perf/util/report-tp.h              |  18 ++++
>  tools/perf/util/sort.c                   | 370 +++++++++++++++++++++++++++++++++++++++++++++++++--------------
>  tools/perf/util/sort.h                   |  29 ++++-
>  tools/perf/util/symbol.h                 |   3 +-
>  tools/perf/util/trace-event-parse.c      |   1 +
>  tools/perf/util/util.h                   |  17 +++
>  31 files changed, 1144 insertions(+), 289 deletions(-)
>  create mode 100644 tools/perf/util/report-tp.c
>  create mode 100644 tools/perf/util/report-tp.h

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [RFC 00/22] perf tools: Display tracepoint enahncements
  2014-02-02 21:45 ` [RFC 00/22] perf tools: Display tracepoint enahncements Jiri Olsa
@ 2014-02-05  1:40   ` Namhyung Kim
  2014-02-05  9:15     ` Jiri Olsa
  0 siblings, 1 reply; 31+ messages in thread
From: Namhyung Kim @ 2014-02-05  1:40 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: linux-kernel, Corey Ashford, Frederic Weisbecker, Ingo Molnar,
	Paul Mackerras, Peter Zijlstra, Arnaldo Carvalho de Melo,
	Steven Rostedt, David Ahern

On Sun, 2 Feb 2014 22:45:50 +0100, Jiri Olsa wrote:
> On Sun, Feb 02, 2014 at 10:38:48PM +0100, Jiri Olsa wrote:
>> hi,
>> sending out tracepoint (mostly) events display enahncements.
>
> forgot to mention.. the branch is in here:
>   git://git.kernel.org/pub/scm/linux/kernel/git/jolsa/perf.git
>   perf/core_tp

It's segfaulted with --group --tui option since the hpp->ptr is not
setup to point an evsel.  Not sure whose problem.. ;-)

Thanks,
Namhyung

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 01/22] perf tools: Fix memory leak in event_format__print function
  2014-02-02 21:38 ` [PATCH 01/22] perf tools: Fix memory leak in event_format__print function Jiri Olsa
@ 2014-02-05  1:41   ` Namhyung Kim
  2014-02-22 17:57   ` [tip:perf/core] " tip-bot for Jiri Olsa
  1 sibling, 0 replies; 31+ messages in thread
From: Namhyung Kim @ 2014-02-05  1:41 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: linux-kernel, Corey Ashford, Frederic Weisbecker, Ingo Molnar,
	Paul Mackerras, Peter Zijlstra, Arnaldo Carvalho de Melo,
	Steven Rostedt, David Ahern

On Sun,  2 Feb 2014 22:38:49 +0100, Jiri Olsa wrote:
> Properly destroying trace_seq object.
>
> Signed-off-by: Jiri Olsa <jolsa@redhat.com>
> Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
> Cc: Frederic Weisbecker <fweisbec@gmail.com>
> Cc: Ingo Molnar <mingo@elte.hu>

Acked-by: Namhyung Kim <namhyung@kernel.org>

Thanks,
Namhyung

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 04/22] perf tools: Add --list report option
  2014-02-02 21:38 ` [PATCH 04/22] perf tools: Add --list report option Jiri Olsa
@ 2014-02-05  1:50   ` Namhyung Kim
  2014-02-05  9:14     ` Jiri Olsa
  0 siblings, 1 reply; 31+ messages in thread
From: Namhyung Kim @ 2014-02-05  1:50 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: linux-kernel, Corey Ashford, Frederic Weisbecker, Ingo Molnar,
	Paul Mackerras, Peter Zijlstra, Arnaldo Carvalho de Melo,
	David Ahern

On Sun,  2 Feb 2014 22:38:52 +0100, Jiri Olsa wrote:
> Adding --list report option to display entries sequentialy:
>
>   $ perf report --list --stdio
>   ...
>        0.00%       13151.543527 +000000.000000       ls  [kernel.kallsyms]  [k] native_write_msr_safe
>        0.00%       13151.543530 +000000.000003       ls  [kernel.kallsyms]  [k] native_write_msr_safe
>        0.00%       13151.543532 +000000.000005       ls  [kernel.kallsyms]  [k] native_write_msr_safe
>        0.00%       13151.543534 +000000.000007       ls  [kernel.kallsyms]  [k] native_write_msr_safe
>        0.05%       13151.543536 +000000.000009       ls  [kernel.kallsyms]  [k] native_write_msr_safe
>        0.92%       13151.543538 +000000.000011       ls  [kernel.kallsyms]  [k] perf_event_comm
>       14.52%       13151.543560 +000000.000033       ls  [kernel.kallsyms]  [k] uprobe_mmap
>       30.10%       13151.543878 +000000.000351       ls  ld-2.17.so         [.] _dl_setup_hash
>       29.30%       13151.544531 +000000.001004       ls  ls                 [.] gobble_file.constprop.49
>       25.09%       13151.545613 +000000.002086       ls  [kernel.kallsyms]  [k] _cond_resched

Hmm.. it seems what this --list option does is very similar to
what "perf script -f time,comm,dso,sym,ip" tries to do, no?

Thanks,
Namhyung

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [RFC 00/22] perf tools: Display tracepoint enahncements
  2014-02-02 21:38 [RFC 00/22] perf tools: Display tracepoint enahncements Jiri Olsa
                   ` (22 preceding siblings ...)
  2014-02-02 21:45 ` [RFC 00/22] perf tools: Display tracepoint enahncements Jiri Olsa
@ 2014-02-05  1:58 ` Namhyung Kim
  23 siblings, 0 replies; 31+ messages in thread
From: Namhyung Kim @ 2014-02-05  1:58 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: linux-kernel, Corey Ashford, Frederic Weisbecker, Ingo Molnar,
	Paul Mackerras, Peter Zijlstra, Arnaldo Carvalho de Melo,
	Steven Rostedt, David Ahern

On Sun,  2 Feb 2014 22:38:48 +0100, Jiri Olsa wrote:
> hi,
> sending out tracepoint (mostly) events display enahncements.
>
> * adding the '--tp' option for report command to show
>   tracepoint related info. Use can specify following switches:
>     fields: shows separated tracepoint fields
>     format: shows tracepoints 'print fmt' in single column
>              (This is default if no switch is given.)

Looks like an useful feature.. but unfortunately it seems not to work
well with --children and (especially) --group options.  Do you have an
idea?

Also as Ingo requested I plan to extend controlling output column with
-F/--field option.  I think I need to more consideration..

Thanks,
Namhyung


>
>   $ perf report --tp --no-children
>   Samples: 4K of event 'sched:sched_switch', Event count (approx.): 4788
>    Overhead          Command      Shared Object          Symbol  Print fmt
>   +  26.27%          swapper  [kernel.kallsyms]  [k] __schedule  swapper/2:0 [120] R ==> offlineimap:22134 [120]
>   +  26.27%      offlineimap  [kernel.kallsyms]  [k] __schedule  offlineimap:22134 [120] S ==> swapper/2:0 [120]
>   -   8.15%          swapper  [kernel.kallsyms]  [k] __schedule  swapper/3:0 [120] R ==> offlineimap:22134 [120]
>        __schedule
>        schedule_preempt_disabled
>        cpu_startup_entry
>        start_secondary
>   +   8.15%      offlineimap  [kernel.kallsyms]  [k] __schedule  offlineimap:22134 [120] S ==> swapper/3:0 [120]
>
>   $ perf report --tp=fields --no-children
>   Samples: 4K of event 'sched:sched_switch', Event count (approx.): 4788
>     Overhead          Command      Shared Object          Symbol                       prev_comm    prev_pid   prev_prio          prev_state                       next_comm    next_pid   next_prio
>   +   26.27%          swapper  [kernel.kallsyms]  [k] __schedule                       swapper/2           0         120                   0                     offlineimap       22134         120
>   +   26.27%      offlineimap  [kernel.kallsyms]  [k] __schedule                     offlineimap       22134         120                   1                       swapper/2           0         120
>   -    8.15%          swapper  [kernel.kallsyms]  [k] __schedule                       swapper/3           0         120                   0                     offlineimap       22134         120
>        __schedule
>        schedule_preempt_disabled
>        cpu_startup_entry
>        start_secondary
>   +    8.15%      offlineimap  [kernel.kallsyms]  [k] __schedule                     offlineimap       22134         120                   1                       swapper/3           0         120
>
>
> * adding '--list' report option to display entries sequentialy:
>
>   Samples: 2K of event 'sched:sched_switch', Event count (approx.): 2450
>         Self  Children                              Time          Command                Shared Object                                                       Symbol  Print fmt
>   +    0.04%     0.04%        9582.431783 +000000.000000          swapper  [kernel.kallsyms]            [k] __schedule                                               swapper/1:0 [120] R ==> perf:11168 [120]
>   -    0.00%     0.04%        9582.431783 +000000.000000          swapper  [kernel.kallsyms]            [k] __schedule                                               swapper/1:0 [120] R ==> perf:11168 [120]
>        __schedule
>        schedule
>        cpu_idle
>        start_secondary
>   +    0.00%     0.04%        9582.431783 +000000.000000          swapper  [kernel.kallsyms]            [k] schedule                                                 swapper/1:0 [120] R ==> perf:11168 [120]
>   +    0.00%     0.04%        9582.431783 +000000.000000          swapper  [kernel.kallsyms]            [k] cpu_idle                                                 swapper/1:0 [120] R ==> perf:11168 [120]
>
> * adding 'H' key handler to togle header columns
>
>
> thanks for comments,
> jirka
>
>
> Signed-off-by: Jiri Olsa <jolsa@redhat.com>
> Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
> Cc: Frederic Weisbecker <fweisbec@gmail.com>
> Cc: Ingo Molnar <mingo@elte.hu>
> Cc: Namhyung Kim <namhyung@kernel.org>
> Cc: Paul Mackerras <paulus@samba.org>
> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
> Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
> Cc: Steven Rostedt <rostedt@goodmis.org>
> Cc: David Ahern <dsahern@gmail.com>
> ---
> Jiri Olsa (22):
>       perf tools: Fix memory leak in event_format__print function
>       perf tools: Add time sort entry
>       perf tools: Add idx sort entry
>       perf tools: Add --list report option
>       perf tools: Add sort_entry struct into sort entries callbacks
>       perf tools: Add selected bool into se_snprintf sort entries callback
>       perf tools: Implement selected bool se_snprintf callback logic
>       perf tools: Implement selected logic for time sort entry
>       perf tools: Factor ui_browser ops out of ui_browser struct
>       perf tools: Add header callback into ui_browser_ops struct
>       perf tools: Remove ev_name argument from perf_evsel__hists_browse
>       perf tools: Add header callback to hist browser
>       perf tools: Factor hpp_arg struct to carry hist_browser
>       perf tools tui: Display columns header text on 'H' press
>       tools lib traceevent: Factor print_event_fields function
>       tools lib traceevent: Make the name output optional in pevent_field_info
>       tools lib traceevent: Add pevent_field_cmp function
>       perf tools: Factor sort entries loops
>       perf tools: Add local hists sort entry list
>       perf tools: Make hists col_len dynamicaly alocated
>       perf tools: Add raw info into hist entry
>       perf tools: Add support for tracepoint fields
>
>  tools/lib/traceevent/event-parse.c       | 181 +++++++++++++++++++++----------
>  tools/lib/traceevent/event-parse.h       |  10 ++
>  tools/perf/Documentation/perf-report.txt |   6 ++
>  tools/perf/Makefile.perf                 |   1 +
>  tools/perf/builtin-annotate.c            |   4 +-
>  tools/perf/builtin-diff.c                |   4 +-
>  tools/perf/builtin-report.c              |  52 ++++++++-
>  tools/perf/tests/hists_link.c            |   6 +-
>  tools/perf/ui/browser.c                  | 101 ++++++++++++-----
>  tools/perf/ui/browser.h                  |  31 ++++--
>  tools/perf/ui/browsers/annotate.c        |  19 ++--
>  tools/perf/ui/browsers/header.c          |   8 +-
>  tools/perf/ui/browsers/hists.c           | 168 ++++++++++++++++++++++-------
>  tools/perf/ui/browsers/map.c             |   8 +-
>  tools/perf/ui/browsers/scripts.c         |   2 +-
>  tools/perf/ui/gtk/hists.c                |   8 +-
>  tools/perf/ui/hist.c                     |  10 +-
>  tools/perf/ui/stdio/hist.c               |   6 +-
>  tools/perf/ui/tui/util.c                 |   8 +-
>  tools/perf/util/evsel.c                  |  24 +++--
>  tools/perf/util/evsel.h                  |   6 +-
>  tools/perf/util/hist.c                   |  65 ++++++++---
>  tools/perf/util/hist.h                   |  20 +++-
>  tools/perf/util/python.c                 |   3 +-
>  tools/perf/util/report-tp.c              | 244 +++++++++++++++++++++++++++++++++++++++++
>  tools/perf/util/report-tp.h              |  18 ++++
>  tools/perf/util/sort.c                   | 370 +++++++++++++++++++++++++++++++++++++++++++++++++--------------
>  tools/perf/util/sort.h                   |  29 ++++-
>  tools/perf/util/symbol.h                 |   3 +-
>  tools/perf/util/trace-event-parse.c      |   1 +
>  tools/perf/util/util.h                   |  17 +++
>  31 files changed, 1144 insertions(+), 289 deletions(-)
>  create mode 100644 tools/perf/util/report-tp.c
>  create mode 100644 tools/perf/util/report-tp.h

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 04/22] perf tools: Add --list report option
  2014-02-05  1:50   ` Namhyung Kim
@ 2014-02-05  9:14     ` Jiri Olsa
  0 siblings, 0 replies; 31+ messages in thread
From: Jiri Olsa @ 2014-02-05  9:14 UTC (permalink / raw)
  To: Namhyung Kim
  Cc: linux-kernel, Corey Ashford, Frederic Weisbecker, Ingo Molnar,
	Paul Mackerras, Peter Zijlstra, Arnaldo Carvalho de Melo,
	David Ahern

On Wed, Feb 05, 2014 at 10:50:36AM +0900, Namhyung Kim wrote:
> On Sun,  2 Feb 2014 22:38:52 +0100, Jiri Olsa wrote:
> > Adding --list report option to display entries sequentialy:
> >
> >   $ perf report --list --stdio
> >   ...
> >        0.00%       13151.543527 +000000.000000       ls  [kernel.kallsyms]  [k] native_write_msr_safe
> >        0.00%       13151.543530 +000000.000003       ls  [kernel.kallsyms]  [k] native_write_msr_safe
> >        0.00%       13151.543532 +000000.000005       ls  [kernel.kallsyms]  [k] native_write_msr_safe
> >        0.00%       13151.543534 +000000.000007       ls  [kernel.kallsyms]  [k] native_write_msr_safe
> >        0.05%       13151.543536 +000000.000009       ls  [kernel.kallsyms]  [k] native_write_msr_safe
> >        0.92%       13151.543538 +000000.000011       ls  [kernel.kallsyms]  [k] perf_event_comm
> >       14.52%       13151.543560 +000000.000033       ls  [kernel.kallsyms]  [k] uprobe_mmap
> >       30.10%       13151.543878 +000000.000351       ls  ld-2.17.so         [.] _dl_setup_hash
> >       29.30%       13151.544531 +000000.001004       ls  ls                 [.] gobble_file.constprop.49
> >       25.09%       13151.545613 +000000.002086       ls  [kernel.kallsyms]  [k] _cond_resched
> 
> Hmm.. it seems what this --list option does is very similar to
> what "perf script -f time,comm,dso,sym,ip" tries to do, no?

correct.. it's just byproduct which I need for lock browser
I'm working on.. but this basic output seemed usefull and
actually missing from report portfolio ;-)

but as I said, it's a byproduct and I can leave it for
the lock change patchset

thanks,
jirka

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [RFC 00/22] perf tools: Display tracepoint enahncements
  2014-02-05  1:40   ` Namhyung Kim
@ 2014-02-05  9:15     ` Jiri Olsa
  0 siblings, 0 replies; 31+ messages in thread
From: Jiri Olsa @ 2014-02-05  9:15 UTC (permalink / raw)
  To: Namhyung Kim
  Cc: linux-kernel, Corey Ashford, Frederic Weisbecker, Ingo Molnar,
	Paul Mackerras, Peter Zijlstra, Arnaldo Carvalho de Melo,
	Steven Rostedt, David Ahern

On Wed, Feb 05, 2014 at 10:40:42AM +0900, Namhyung Kim wrote:
> On Sun, 2 Feb 2014 22:45:50 +0100, Jiri Olsa wrote:
> > On Sun, Feb 02, 2014 at 10:38:48PM +0100, Jiri Olsa wrote:
> >> hi,
> >> sending out tracepoint (mostly) events display enahncements.
> >
> > forgot to mention.. the branch is in here:
> >   git://git.kernel.org/pub/scm/linux/kernel/git/jolsa/perf.git
> >   perf/core_tp
> 
> It's segfaulted with --group --tui option since the hpp->ptr is not
> setup to point an evsel.  Not sure whose problem.. ;-)

will check ;-) thanks

jirka

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [tip:perf/core] perf tools: Fix memory leak in event_format__print function
  2014-02-02 21:38 ` [PATCH 01/22] perf tools: Fix memory leak in event_format__print function Jiri Olsa
  2014-02-05  1:41   ` Namhyung Kim
@ 2014-02-22 17:57   ` tip-bot for Jiri Olsa
  1 sibling, 0 replies; 31+ messages in thread
From: tip-bot for Jiri Olsa @ 2014-02-22 17:57 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: acme, linux-kernel, paulus, hpa, mingo, a.p.zijlstra, namhyung,
	jolsa, fweisbec, rostedt, dsahern, tglx, cjashfor, mingo

Commit-ID:  b58f608e31010cb76ee953a6919f9d96b4eb58d9
Gitweb:     http://git.kernel.org/tip/b58f608e31010cb76ee953a6919f9d96b4eb58d9
Author:     Jiri Olsa <jolsa@redhat.com>
AuthorDate: Sun, 2 Feb 2014 22:38:49 +0100
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Tue, 18 Feb 2014 09:34:47 -0300

perf tools: Fix memory leak in event_format__print function

Properly destroying trace_seq object.

Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Acked-by: Namhyung Kim <namhyung@kernel.org>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Steven Rostedt <rostedt@goodmis.org>
Link: http://lkml.kernel.org/r/1391377150-23920-2-git-send-email-jolsa@redhat.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/trace-event-parse.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/tools/perf/util/trace-event-parse.c b/tools/perf/util/trace-event-parse.c
index e0d6d07f..c36636f 100644
--- a/tools/perf/util/trace-event-parse.c
+++ b/tools/perf/util/trace-event-parse.c
@@ -126,6 +126,7 @@ void event_format__print(struct event_format *event,
 	trace_seq_init(&s);
 	pevent_event_info(&s, event, &record);
 	trace_seq_do_printf(&s);
+	trace_seq_destroy(&s);
 }
 
 void parse_proc_kallsyms(struct pevent *pevent,

^ permalink raw reply related	[flat|nested] 31+ messages in thread

end of thread, other threads:[~2014-02-22 17:59 UTC | newest]

Thread overview: 31+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-02-02 21:38 [RFC 00/22] perf tools: Display tracepoint enahncements Jiri Olsa
2014-02-02 21:38 ` [PATCH 01/22] perf tools: Fix memory leak in event_format__print function Jiri Olsa
2014-02-05  1:41   ` Namhyung Kim
2014-02-22 17:57   ` [tip:perf/core] " tip-bot for Jiri Olsa
2014-02-02 21:38 ` [PATCH 02/22] perf tools: Add time sort entry Jiri Olsa
2014-02-02 21:38 ` [PATCH 03/22] perf tools: Add idx " Jiri Olsa
2014-02-02 21:38 ` [PATCH 04/22] perf tools: Add --list report option Jiri Olsa
2014-02-05  1:50   ` Namhyung Kim
2014-02-05  9:14     ` Jiri Olsa
2014-02-02 21:38 ` [PATCH 05/22] perf tools: Add sort_entry struct into sort entries callbacks Jiri Olsa
2014-02-02 21:38 ` [PATCH 06/22] perf tools: Add selected bool into se_snprintf sort entries callback Jiri Olsa
2014-02-02 21:38 ` [PATCH 07/22] perf tools: Implement selected bool se_snprintf callback logic Jiri Olsa
2014-02-02 21:38 ` [PATCH 08/22] perf tools: Implement selected logic for time sort entry Jiri Olsa
2014-02-02 21:38 ` [PATCH 09/22] perf tools: Factor ui_browser ops out of ui_browser struct Jiri Olsa
2014-02-02 21:38 ` [PATCH 10/22] perf tools: Add header callback into ui_browser_ops struct Jiri Olsa
2014-02-02 21:38 ` [PATCH 11/22] perf tools: Remove ev_name argument from perf_evsel__hists_browse Jiri Olsa
2014-02-02 21:39 ` [PATCH 12/22] perf tools: Add header callback to hist browser Jiri Olsa
2014-02-02 21:39 ` [PATCH 13/22] perf tools: Factor hpp_arg struct to carry hist_browser Jiri Olsa
2014-02-02 21:39 ` [PATCH 14/22] perf tools tui: Display columns header text on 'H' press Jiri Olsa
2014-02-02 21:39 ` [PATCH 15/22] tools lib traceevent: Factor print_event_fields function Jiri Olsa
2014-02-02 21:39 ` [PATCH 16/22] tools lib traceevent: Make the name output optional in pevent_field_info Jiri Olsa
2014-02-02 21:39 ` [PATCH 17/22] tools lib traceevent: Add pevent_field_cmp function Jiri Olsa
2014-02-02 21:39 ` [PATCH 18/22] perf tools: Factor sort entries loops Jiri Olsa
2014-02-02 21:39 ` [PATCH 19/22] perf tools: Add local hists sort entry list Jiri Olsa
2014-02-02 21:39 ` [PATCH 20/22] perf tools: Make hists col_len dynamicaly alocated Jiri Olsa
2014-02-02 21:39 ` [PATCH 21/22] perf tools: Add raw info into hist entry Jiri Olsa
2014-02-02 21:39 ` [PATCH 22/22] perf tools: Add support for tracepoint fields Jiri Olsa
2014-02-02 21:45 ` [RFC 00/22] perf tools: Display tracepoint enahncements Jiri Olsa
2014-02-05  1:40   ` Namhyung Kim
2014-02-05  9:15     ` Jiri Olsa
2014-02-05  1:58 ` Namhyung Kim

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).