aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/thread-stack.c
diff options
context:
space:
mode:
authorAdrian Hunter <adrian.hunter@intel.com>2015-05-29 09:33:30 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2015-06-19 15:03:33 -0400
commita5499b37197ab4b5fed101370df7ccadacbb4340 (patch)
tree6c7651403a51c38af7d62e5dadf04f106f4cf31a /tools/perf/util/thread-stack.c
parent79928928c5a27d58ae48285d2a3f7aa835db7547 (diff)
perf tools: Ensure thread-stack is flushed
The thread-stack represents a thread's current stack. When a thread exits there can still be many functions on the stack e.g. exit() can be called many levels deep, so all the callers will never return. To get that information output, the thread-stack must be flushed. Previously it was assumed the thread-stack would be flushed when the struct thread was deleted. With thread ref-counting it is no longer clear when that will be, if ever. So instead explicitly flush all the thread-stacks at the end of a session. Signed-off-by: Adrian Hunter <adrian.hunter@intel.com> Cc: Jiri Olsa <jolsa@redhat.com> Link: http://lkml.kernel.org/r/1432906425-9911-3-git-send-email-adrian.hunter@intel.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/util/thread-stack.c')
-rw-r--r--tools/perf/util/thread-stack.c18
1 files changed, 13 insertions, 5 deletions
diff --git a/tools/perf/util/thread-stack.c b/tools/perf/util/thread-stack.c
index 9ed59a452d1f..679688e70ae7 100644
--- a/tools/perf/util/thread-stack.c
+++ b/tools/perf/util/thread-stack.c
@@ -219,7 +219,7 @@ static int thread_stack__call_return(struct thread *thread,
219 return crp->process(&cr, crp->data); 219 return crp->process(&cr, crp->data);
220} 220}
221 221
222static int thread_stack__flush(struct thread *thread, struct thread_stack *ts) 222static int __thread_stack__flush(struct thread *thread, struct thread_stack *ts)
223{ 223{
224 struct call_return_processor *crp = ts->crp; 224 struct call_return_processor *crp = ts->crp;
225 int err; 225 int err;
@@ -242,6 +242,14 @@ static int thread_stack__flush(struct thread *thread, struct thread_stack *ts)
242 return 0; 242 return 0;
243} 243}
244 244
245int thread_stack__flush(struct thread *thread)
246{
247 if (thread->ts)
248 return __thread_stack__flush(thread, thread->ts);
249
250 return 0;
251}
252
245int thread_stack__event(struct thread *thread, u32 flags, u64 from_ip, 253int thread_stack__event(struct thread *thread, u32 flags, u64 from_ip,
246 u64 to_ip, u16 insn_len, u64 trace_nr) 254 u64 to_ip, u16 insn_len, u64 trace_nr)
247{ 255{
@@ -264,7 +272,7 @@ int thread_stack__event(struct thread *thread, u32 flags, u64 from_ip,
264 */ 272 */
265 if (trace_nr != thread->ts->trace_nr) { 273 if (trace_nr != thread->ts->trace_nr) {
266 if (thread->ts->trace_nr) 274 if (thread->ts->trace_nr)
267 thread_stack__flush(thread, thread->ts); 275 __thread_stack__flush(thread, thread->ts);
268 thread->ts->trace_nr = trace_nr; 276 thread->ts->trace_nr = trace_nr;
269 } 277 }
270 278
@@ -297,7 +305,7 @@ void thread_stack__set_trace_nr(struct thread *thread, u64 trace_nr)
297 305
298 if (trace_nr != thread->ts->trace_nr) { 306 if (trace_nr != thread->ts->trace_nr) {
299 if (thread->ts->trace_nr) 307 if (thread->ts->trace_nr)
300 thread_stack__flush(thread, thread->ts); 308 __thread_stack__flush(thread, thread->ts);
301 thread->ts->trace_nr = trace_nr; 309 thread->ts->trace_nr = trace_nr;
302 } 310 }
303} 311}
@@ -305,7 +313,7 @@ void thread_stack__set_trace_nr(struct thread *thread, u64 trace_nr)
305void thread_stack__free(struct thread *thread) 313void thread_stack__free(struct thread *thread)
306{ 314{
307 if (thread->ts) { 315 if (thread->ts) {
308 thread_stack__flush(thread, thread->ts); 316 __thread_stack__flush(thread, thread->ts);
309 zfree(&thread->ts->stack); 317 zfree(&thread->ts->stack);
310 zfree(&thread->ts); 318 zfree(&thread->ts);
311 } 319 }
@@ -689,7 +697,7 @@ int thread_stack__process(struct thread *thread, struct comm *comm,
689 697
690 /* Flush stack on exec */ 698 /* Flush stack on exec */
691 if (ts->comm != comm && thread->pid_ == thread->tid) { 699 if (ts->comm != comm && thread->pid_ == thread->tid) {
692 err = thread_stack__flush(thread, ts); 700 err = __thread_stack__flush(thread, ts);
693 if (err) 701 if (err)
694 return err; 702 return err;
695 ts->comm = comm; 703 ts->comm = comm;