linux-perf-users.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Arnaldo Carvalho de Melo <acme@kernel.org>
To: Ingo Molnar <mingo@kernel.org>
Cc: Clark Williams <williams@redhat.com>,
	linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org,
	Adrian Hunter <adrian.hunter@intel.com>,
	Andi Kleen <ak@linux.intel.com>, Jiri Olsa <jolsa@redhat.com>,
	Arnaldo Carvalho de Melo <acme@redhat.com>
Subject: [PATCH 23/27] perf tools: Improve thread_stack__event() for trace begin / end
Date: Mon, 24 Sep 2018 12:02:38 -0300	[thread overview]
Message-ID: <20180924150242.14235-24-acme@kernel.org> (raw)
In-Reply-To: <20180924150242.14235-1-acme@kernel.org>

From: Adrian Hunter <adrian.hunter@intel.com>

thread_stack__event() is used to create call stacks, by keeping track of
calls and returns. Improve the handling of trace begin / end to allow
for a trace that ends in a call.

Previously, the Intel PT decoder would indicate begin / end by a branch
from / to zero. That hides useful information, in particular when a
trace ends with a call. Before remedying that, enhance the thread stack
so that it does not expect to see the 'return' for a 'call' that ends
the trace.

Committer notes:

Added this:

                return thread_stack__push(thread->ts, ret_addr,
-                                         flags && PERF_IP_FLAG_TRACE_END);
+                                         flags & PERF_IP_FLAG_TRACE_END);

To fix problem spotted by:

debian:9:            clang version 3.8.1-24 (tags/RELEASE_381/final)
debian:experimental: clang version 6.0.1-6 (tags/RELEASE_601/final)

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Cc: Andi Kleen <ak@linux.intel.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Link: http://lkml.kernel.org/r/20180920130048.31432-4-adrian.hunter@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/thread-stack.c | 35 ++++++++++++++++++++++++++++++-----
 1 file changed, 30 insertions(+), 5 deletions(-)

diff --git a/tools/perf/util/thread-stack.c b/tools/perf/util/thread-stack.c
index dd17d6a38d3a..e3f7dfecafa9 100644
--- a/tools/perf/util/thread-stack.c
+++ b/tools/perf/util/thread-stack.c
@@ -36,6 +36,7 @@
  * @branch_count: the branch count when the entry was created
  * @cp: call path
  * @no_call: a 'call' was not seen
+ * @trace_end: a 'call' but trace ended
  */
 struct thread_stack_entry {
 	u64 ret_addr;
@@ -44,6 +45,7 @@ struct thread_stack_entry {
 	u64 branch_count;
 	struct call_path *cp;
 	bool no_call;
+	bool trace_end;
 };
 
 /**
@@ -112,7 +114,8 @@ static struct thread_stack *thread_stack__new(struct thread *thread,
 	return ts;
 }
 
-static int thread_stack__push(struct thread_stack *ts, u64 ret_addr)
+static int thread_stack__push(struct thread_stack *ts, u64 ret_addr,
+			      bool trace_end)
 {
 	int err = 0;
 
@@ -124,6 +127,7 @@ static int thread_stack__push(struct thread_stack *ts, u64 ret_addr)
 		}
 	}
 
+	ts->stack[ts->cnt].trace_end = trace_end;
 	ts->stack[ts->cnt++].ret_addr = ret_addr;
 
 	return err;
@@ -150,6 +154,18 @@ static void thread_stack__pop(struct thread_stack *ts, u64 ret_addr)
 	}
 }
 
+static void thread_stack__pop_trace_end(struct thread_stack *ts)
+{
+	size_t i;
+
+	for (i = ts->cnt; i; ) {
+		if (ts->stack[--i].trace_end)
+			ts->cnt = i;
+		else
+			return;
+	}
+}
+
 static bool thread_stack__in_kernel(struct thread_stack *ts)
 {
 	if (!ts->cnt)
@@ -254,10 +270,19 @@ int thread_stack__event(struct thread *thread, u32 flags, u64 from_ip,
 		ret_addr = from_ip + insn_len;
 		if (ret_addr == to_ip)
 			return 0; /* Zero-length calls are excluded */
-		return thread_stack__push(thread->ts, ret_addr);
-	} else if (flags & PERF_IP_FLAG_RETURN) {
-		if (!from_ip)
-			return 0;
+		return thread_stack__push(thread->ts, ret_addr,
+					  flags & PERF_IP_FLAG_TRACE_END);
+	} else if (flags & PERF_IP_FLAG_TRACE_BEGIN) {
+		/*
+		 * If the caller did not change the trace number (which would
+		 * have flushed the stack) then try to make sense of the stack.
+		 * Possibly, tracing began after returning to the current
+		 * address, so try to pop that. Also, do not expect a call made
+		 * when the trace ended, to return, so pop that.
+		 */
+		thread_stack__pop(thread->ts, to_ip);
+		thread_stack__pop_trace_end(thread->ts);
+	} else if ((flags & PERF_IP_FLAG_RETURN) && from_ip) {
 		thread_stack__pop(thread->ts, to_ip);
 	}
 
-- 
2.14.4

  parent reply	other threads:[~2018-09-24 15:02 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-09-24 15:02 [GIT PULL 00/27] perf/core improvements and fixes Arnaldo Carvalho de Melo
2018-09-24 15:02 ` [PATCH 01/27] perf help: Add missing subcommand `version` Arnaldo Carvalho de Melo
2018-09-24 15:02 ` [PATCH 02/27] perf tools: Report itrace options in help Arnaldo Carvalho de Melo
2018-09-24 15:02 ` [PATCH 03/27] tools lib subcmd: Support overwriting the pager Arnaldo Carvalho de Melo
2018-09-24 15:02 ` [PATCH 04/27] perf script: Allow sym and dso without ip, addr Arnaldo Carvalho de Melo
2018-09-24 15:02 ` [PATCH 05/27] perf script: Print DSO for callindent Arnaldo Carvalho de Melo
2018-09-24 15:02 ` [PATCH 06/27] tools lib traceevent, perf tools: Rename struct event_format to struct tep_event_format Arnaldo Carvalho de Melo
2018-09-24 15:02 ` [PATCH 07/27] tools lib traceevent, perf tools: Rename struct format{_field} to struct tep_format{_field} Arnaldo Carvalho de Melo
2018-09-24 15:02 ` [PATCH 08/27] tools lib traceevent, perf tools: Rename enum format_flags to enum tep_format_flags Arnaldo Carvalho de Melo
2018-09-24 15:02 ` [PATCH 09/27] tools lib traceevent: Rename enum event_{sort_}type to enum tep_event_{sort_}type Arnaldo Carvalho de Melo
2018-09-24 15:02 ` [PATCH 10/27] tools lib traceevent: Add prefix TEP_ to all EVENT_FL_* flags Arnaldo Carvalho de Melo
2018-09-24 15:02 ` [PATCH 11/27] tools lib traceevent, perf tools: Add prefix tep_ to all print_* structures Arnaldo Carvalho de Melo
2018-09-24 15:02 ` [PATCH 12/27] tools lib traceevent, perf tools: Rename enum print_arg_type to enum tep_print_arg_type Arnaldo Carvalho de Melo
2018-09-24 15:02 ` [PATCH 13/27] tools lib traceevent: Add prefix tep_ to enums filter_{boolean,op,cmp}_type Arnaldo Carvalho de Melo
2018-09-24 15:02 ` [PATCH 14/27] tools lib traceevent: Add prefix tep_ to enums filter_{exp,arg}_type Arnaldo Carvalho de Melo
2018-09-24 15:02 ` [PATCH 15/27] tools lib traceevent: Add prefix tep_ to struct filter_{arg,value_type} Arnaldo Carvalho de Melo
2018-09-24 15:02 ` [PATCH 16/27] tools lib traceevent: Add prefix tep_ to various structs filter_arg_* Arnaldo Carvalho de Melo
2018-09-24 15:02 ` [PATCH 17/27] tools lib traceevent: Add prefix tep_ to structs filter_type and event_filter Arnaldo Carvalho de Melo
2018-09-24 15:02 ` [PATCH 18/27] tools lib traceevent: Rename struct plugin_list to struct tep_plugin_list Arnaldo Carvalho de Melo
2018-09-24 15:02 ` [PATCH 19/27] tools lib traceevent: Rename data2host*() APIs Arnaldo Carvalho de Melo
2018-09-24 15:02 ` [PATCH 20/27] tools lib traceevent: Add prefix tep_ to enum filter_trivial_type Arnaldo Carvalho de Melo
2018-09-24 15:02 ` [PATCH 21/27] perf script: Enhance sample flags for trace begin / end Arnaldo Carvalho de Melo
2018-09-24 15:02 ` [PATCH 22/27] perf db-export: Add trace begin / end branch type variants Arnaldo Carvalho de Melo
2018-09-24 15:02 ` Arnaldo Carvalho de Melo [this message]
2018-09-24 15:02 ` [PATCH 24/27] perf tools: Improve thread_stack__process() for trace begin / end Arnaldo Carvalho de Melo
2018-09-24 15:02 ` [PATCH 25/27] perf intel-pt: Add decoder flags " Arnaldo Carvalho de Melo
2018-09-24 15:02 ` [PATCH 26/27] perf intel-pt: Implement " Arnaldo Carvalho de Melo
2018-09-24 15:02 ` [PATCH 27/27] perf vendor events arm64: Revise core JSON events for eMAG Arnaldo Carvalho de Melo

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180924150242.14235-24-acme@kernel.org \
    --to=acme@kernel.org \
    --cc=acme@redhat.com \
    --cc=adrian.hunter@intel.com \
    --cc=ak@linux.intel.com \
    --cc=jolsa@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-perf-users@vger.kernel.org \
    --cc=mingo@kernel.org \
    --cc=williams@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).