blob: 7f8eff018c16c67ae373b2f7cd9b5ee055226168 [file] [log] [blame]
Adrian Hunter00447cc2014-10-30 16:09:42 +02001/*
2 * thread-stack.c: Synthesize a thread's stack using call / return events
3 * Copyright (c) 2014, Intel Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 */
15
Adrian Hunter92a9e4f2014-10-30 16:09:45 +020016#include <linux/rbtree.h>
17#include <linux/list.h>
Adrian Hunter256d92b2018-12-21 14:06:19 +020018#include <linux/log2.h>
Arnaldo Carvalho de Meloa43783a2017-04-18 10:46:11 -030019#include <errno.h>
Adrian Hunter00447cc2014-10-30 16:09:42 +020020#include "thread.h"
21#include "event.h"
Adrian Hunter92a9e4f2014-10-30 16:09:45 +020022#include "machine.h"
Adrian Hunter00447cc2014-10-30 16:09:42 +020023#include "util.h"
24#include "debug.h"
Adrian Hunter92a9e4f2014-10-30 16:09:45 +020025#include "symbol.h"
26#include "comm.h"
Chris Phlipot451db122016-04-28 01:19:07 -070027#include "call-path.h"
Adrian Hunter00447cc2014-10-30 16:09:42 +020028#include "thread-stack.h"
29
Adrian Hunter92a9e4f2014-10-30 16:09:45 +020030#define STACK_GROWTH 2048
31
32/**
33 * struct thread_stack_entry - thread stack entry.
34 * @ret_addr: return address
35 * @timestamp: timestamp (if known)
36 * @ref: external reference (e.g. db_id of sample)
37 * @branch_count: the branch count when the entry was created
38 * @cp: call path
39 * @no_call: a 'call' was not seen
Adrian Hunter4d60e5e2018-09-20 16:00:45 +030040 * @trace_end: a 'call' but trace ended
Adrian Hunter92a9e4f2014-10-30 16:09:45 +020041 */
42struct thread_stack_entry {
43 u64 ret_addr;
44 u64 timestamp;
45 u64 ref;
46 u64 branch_count;
47 struct call_path *cp;
48 bool no_call;
Adrian Hunter4d60e5e2018-09-20 16:00:45 +030049 bool trace_end;
Adrian Hunter92a9e4f2014-10-30 16:09:45 +020050};
51
52/**
53 * struct thread_stack - thread stack constructed from 'call' and 'return'
54 * branch samples.
55 * @stack: array that holds the stack
56 * @cnt: number of entries in the stack
57 * @sz: current maximum stack size
58 * @trace_nr: current trace number
59 * @branch_count: running branch count
60 * @kernel_start: kernel start address
61 * @last_time: last timestamp
62 * @crp: call/return processor
63 * @comm: current comm
Adrian Hunterf6060ac2018-12-21 14:06:16 +020064 * @arr_sz: size of array if this is the first element of an array
Adrian Hunter92a9e4f2014-10-30 16:09:45 +020065 */
Adrian Hunter00447cc2014-10-30 16:09:42 +020066struct thread_stack {
67 struct thread_stack_entry *stack;
68 size_t cnt;
69 size_t sz;
70 u64 trace_nr;
Adrian Hunter92a9e4f2014-10-30 16:09:45 +020071 u64 branch_count;
72 u64 kernel_start;
73 u64 last_time;
74 struct call_return_processor *crp;
75 struct comm *comm;
Adrian Hunterf6060ac2018-12-21 14:06:16 +020076 unsigned int arr_sz;
Adrian Hunter00447cc2014-10-30 16:09:42 +020077};
78
Adrian Hunter256d92b2018-12-21 14:06:19 +020079/*
80 * Assume pid == tid == 0 identifies the idle task as defined by
81 * perf_session__register_idle_thread(). The idle task is really 1 task per cpu,
82 * and therefore requires a stack for each cpu.
83 */
84static inline bool thread_stack__per_cpu(struct thread *thread)
85{
86 return !(thread->tid || thread->pid_);
87}
88
Adrian Hunter00447cc2014-10-30 16:09:42 +020089static int thread_stack__grow(struct thread_stack *ts)
90{
91 struct thread_stack_entry *new_stack;
92 size_t sz, new_sz;
93
94 new_sz = ts->sz + STACK_GROWTH;
95 sz = new_sz * sizeof(struct thread_stack_entry);
96
97 new_stack = realloc(ts->stack, sz);
98 if (!new_stack)
99 return -ENOMEM;
100
101 ts->stack = new_stack;
102 ts->sz = new_sz;
103
104 return 0;
105}
106
Adrian Hunter2e9e8682018-12-21 14:06:17 +0200107static int thread_stack__init(struct thread_stack *ts, struct thread *thread,
108 struct call_return_processor *crp)
109{
110 int err;
111
112 err = thread_stack__grow(ts);
113 if (err)
114 return err;
115
116 if (thread->mg && thread->mg->machine)
117 ts->kernel_start = machine__kernel_start(thread->mg->machine);
118 else
119 ts->kernel_start = 1ULL << 63;
120 ts->crp = crp;
121
122 return 0;
123}
124
Adrian Hunter256d92b2018-12-21 14:06:19 +0200125static struct thread_stack *thread_stack__new(struct thread *thread, int cpu,
Adrian Hunter92a9e4f2014-10-30 16:09:45 +0200126 struct call_return_processor *crp)
Adrian Hunter00447cc2014-10-30 16:09:42 +0200127{
Adrian Hunter139f42f2018-12-21 14:06:18 +0200128 struct thread_stack *ts = thread->ts, *new_ts;
129 unsigned int old_sz = ts ? ts->arr_sz : 0;
130 unsigned int new_sz = 1;
Adrian Hunter00447cc2014-10-30 16:09:42 +0200131
Adrian Hunter256d92b2018-12-21 14:06:19 +0200132 if (thread_stack__per_cpu(thread) && cpu > 0)
133 new_sz = roundup_pow_of_two(cpu + 1);
134
Adrian Hunter139f42f2018-12-21 14:06:18 +0200135 if (!ts || new_sz > old_sz) {
136 new_ts = calloc(new_sz, sizeof(*ts));
137 if (!new_ts)
138 return NULL;
139 if (ts)
140 memcpy(new_ts, ts, old_sz * sizeof(*ts));
141 new_ts->arr_sz = new_sz;
142 zfree(&thread->ts);
143 thread->ts = new_ts;
144 ts = new_ts;
Adrian Hunter00447cc2014-10-30 16:09:42 +0200145 }
146
Adrian Hunter256d92b2018-12-21 14:06:19 +0200147 if (thread_stack__per_cpu(thread) && cpu > 0 &&
148 (unsigned int)cpu < ts->arr_sz)
149 ts += cpu;
150
Adrian Hunter139f42f2018-12-21 14:06:18 +0200151 if (!ts->stack &&
152 thread_stack__init(ts, thread, crp))
153 return NULL;
Adrian Hunterbd8e68a2018-12-21 14:06:15 +0200154
Adrian Hunter00447cc2014-10-30 16:09:42 +0200155 return ts;
156}
157
Adrian Hunter256d92b2018-12-21 14:06:19 +0200158static struct thread_stack *thread__cpu_stack(struct thread *thread, int cpu)
Adrian Hunterbd8e68a2018-12-21 14:06:15 +0200159{
Adrian Hunter256d92b2018-12-21 14:06:19 +0200160 struct thread_stack *ts = thread->ts;
161
162 if (cpu < 0)
163 cpu = 0;
164
165 if (!ts || (unsigned int)cpu >= ts->arr_sz)
166 return NULL;
167
168 ts += cpu;
169
170 if (!ts->stack)
171 return NULL;
172
173 return ts;
174}
175
176static inline struct thread_stack *thread__stack(struct thread *thread,
177 int cpu)
178{
179 if (!thread)
180 return NULL;
181
182 if (thread_stack__per_cpu(thread))
183 return thread__cpu_stack(thread, cpu);
184
185 return thread->ts;
Adrian Hunterbd8e68a2018-12-21 14:06:15 +0200186}
187
Adrian Hunter4d60e5e2018-09-20 16:00:45 +0300188static int thread_stack__push(struct thread_stack *ts, u64 ret_addr,
189 bool trace_end)
Adrian Hunter00447cc2014-10-30 16:09:42 +0200190{
191 int err = 0;
192
193 if (ts->cnt == ts->sz) {
194 err = thread_stack__grow(ts);
195 if (err) {
196 pr_warning("Out of memory: discarding thread stack\n");
197 ts->cnt = 0;
198 }
199 }
200
Adrian Hunter4d60e5e2018-09-20 16:00:45 +0300201 ts->stack[ts->cnt].trace_end = trace_end;
Adrian Hunter00447cc2014-10-30 16:09:42 +0200202 ts->stack[ts->cnt++].ret_addr = ret_addr;
203
204 return err;
205}
206
207static void thread_stack__pop(struct thread_stack *ts, u64 ret_addr)
208{
209 size_t i;
210
211 /*
212 * In some cases there may be functions which are not seen to return.
213 * For example when setjmp / longjmp has been used. Or the perf context
214 * switch in the kernel which doesn't stop and start tracing in exactly
215 * the same code path. When that happens the return address will be
216 * further down the stack. If the return address is not found at all,
217 * we assume the opposite (i.e. this is a return for a call that wasn't
218 * seen for some reason) and leave the stack alone.
219 */
220 for (i = ts->cnt; i; ) {
221 if (ts->stack[--i].ret_addr == ret_addr) {
222 ts->cnt = i;
223 return;
224 }
225 }
226}
227
Adrian Hunter4d60e5e2018-09-20 16:00:45 +0300228static void thread_stack__pop_trace_end(struct thread_stack *ts)
229{
230 size_t i;
231
232 for (i = ts->cnt; i; ) {
233 if (ts->stack[--i].trace_end)
234 ts->cnt = i;
235 else
236 return;
237 }
238}
239
Adrian Hunter92a9e4f2014-10-30 16:09:45 +0200240static bool thread_stack__in_kernel(struct thread_stack *ts)
241{
242 if (!ts->cnt)
243 return false;
244
245 return ts->stack[ts->cnt - 1].cp->in_kernel;
246}
247
248static int thread_stack__call_return(struct thread *thread,
249 struct thread_stack *ts, size_t idx,
250 u64 timestamp, u64 ref, bool no_return)
251{
252 struct call_return_processor *crp = ts->crp;
253 struct thread_stack_entry *tse;
254 struct call_return cr = {
255 .thread = thread,
256 .comm = ts->comm,
257 .db_id = 0,
258 };
259
260 tse = &ts->stack[idx];
261 cr.cp = tse->cp;
262 cr.call_time = tse->timestamp;
263 cr.return_time = timestamp;
264 cr.branch_count = ts->branch_count - tse->branch_count;
265 cr.call_ref = tse->ref;
266 cr.return_ref = ref;
267 if (tse->no_call)
268 cr.flags |= CALL_RETURN_NO_CALL;
269 if (no_return)
270 cr.flags |= CALL_RETURN_NO_RETURN;
271
272 return crp->process(&cr, crp->data);
273}
274
Adrian Huntera5499b32015-05-29 16:33:30 +0300275static int __thread_stack__flush(struct thread *thread, struct thread_stack *ts)
Adrian Hunter92a9e4f2014-10-30 16:09:45 +0200276{
277 struct call_return_processor *crp = ts->crp;
278 int err;
279
280 if (!crp) {
281 ts->cnt = 0;
282 return 0;
283 }
284
285 while (ts->cnt) {
286 err = thread_stack__call_return(thread, ts, --ts->cnt,
287 ts->last_time, 0, true);
288 if (err) {
289 pr_err("Error flushing thread stack!\n");
290 ts->cnt = 0;
291 return err;
292 }
293 }
294
295 return 0;
296}
297
Adrian Huntera5499b32015-05-29 16:33:30 +0300298int thread_stack__flush(struct thread *thread)
299{
Adrian Hunterbd8e68a2018-12-21 14:06:15 +0200300 struct thread_stack *ts = thread->ts;
Adrian Hunterf6060ac2018-12-21 14:06:16 +0200301 unsigned int pos;
302 int err = 0;
Adrian Hunterbd8e68a2018-12-21 14:06:15 +0200303
Adrian Hunterf6060ac2018-12-21 14:06:16 +0200304 if (ts) {
305 for (pos = 0; pos < ts->arr_sz; pos++) {
306 int ret = __thread_stack__flush(thread, ts + pos);
Adrian Huntera5499b32015-05-29 16:33:30 +0300307
Adrian Hunterf6060ac2018-12-21 14:06:16 +0200308 if (ret)
309 err = ret;
310 }
311 }
312
313 return err;
Adrian Huntera5499b32015-05-29 16:33:30 +0300314}
315
Adrian Hunter256d92b2018-12-21 14:06:19 +0200316int thread_stack__event(struct thread *thread, int cpu, u32 flags, u64 from_ip,
Adrian Hunter00447cc2014-10-30 16:09:42 +0200317 u64 to_ip, u16 insn_len, u64 trace_nr)
318{
Adrian Hunter256d92b2018-12-21 14:06:19 +0200319 struct thread_stack *ts = thread__stack(thread, cpu);
Adrian Hunterbd8e68a2018-12-21 14:06:15 +0200320
Adrian Hunter00447cc2014-10-30 16:09:42 +0200321 if (!thread)
322 return -EINVAL;
323
Adrian Hunterbd8e68a2018-12-21 14:06:15 +0200324 if (!ts) {
Adrian Hunter256d92b2018-12-21 14:06:19 +0200325 ts = thread_stack__new(thread, cpu, NULL);
Adrian Hunterbd8e68a2018-12-21 14:06:15 +0200326 if (!ts) {
Adrian Hunter00447cc2014-10-30 16:09:42 +0200327 pr_warning("Out of memory: no thread stack\n");
328 return -ENOMEM;
329 }
Adrian Hunterbd8e68a2018-12-21 14:06:15 +0200330 ts->trace_nr = trace_nr;
Adrian Hunter00447cc2014-10-30 16:09:42 +0200331 }
332
333 /*
334 * When the trace is discontinuous, the trace_nr changes. In that case
335 * the stack might be completely invalid. Better to report nothing than
Adrian Hunter92a9e4f2014-10-30 16:09:45 +0200336 * to report something misleading, so flush the stack.
Adrian Hunter00447cc2014-10-30 16:09:42 +0200337 */
Adrian Hunterbd8e68a2018-12-21 14:06:15 +0200338 if (trace_nr != ts->trace_nr) {
339 if (ts->trace_nr)
340 __thread_stack__flush(thread, ts);
341 ts->trace_nr = trace_nr;
Adrian Hunter00447cc2014-10-30 16:09:42 +0200342 }
343
Adrian Hunter92a9e4f2014-10-30 16:09:45 +0200344 /* Stop here if thread_stack__process() is in use */
Adrian Hunterbd8e68a2018-12-21 14:06:15 +0200345 if (ts->crp)
Adrian Hunter92a9e4f2014-10-30 16:09:45 +0200346 return 0;
347
Adrian Hunter00447cc2014-10-30 16:09:42 +0200348 if (flags & PERF_IP_FLAG_CALL) {
349 u64 ret_addr;
350
351 if (!to_ip)
352 return 0;
353 ret_addr = from_ip + insn_len;
354 if (ret_addr == to_ip)
355 return 0; /* Zero-length calls are excluded */
Adrian Hunterbd8e68a2018-12-21 14:06:15 +0200356 return thread_stack__push(ts, ret_addr,
Adrian Hunter4d60e5e2018-09-20 16:00:45 +0300357 flags & PERF_IP_FLAG_TRACE_END);
358 } else if (flags & PERF_IP_FLAG_TRACE_BEGIN) {
359 /*
360 * If the caller did not change the trace number (which would
361 * have flushed the stack) then try to make sense of the stack.
362 * Possibly, tracing began after returning to the current
363 * address, so try to pop that. Also, do not expect a call made
364 * when the trace ended, to return, so pop that.
365 */
Adrian Hunterbd8e68a2018-12-21 14:06:15 +0200366 thread_stack__pop(ts, to_ip);
367 thread_stack__pop_trace_end(ts);
Adrian Hunter4d60e5e2018-09-20 16:00:45 +0300368 } else if ((flags & PERF_IP_FLAG_RETURN) && from_ip) {
Adrian Hunterbd8e68a2018-12-21 14:06:15 +0200369 thread_stack__pop(ts, to_ip);
Adrian Hunter00447cc2014-10-30 16:09:42 +0200370 }
371
372 return 0;
373}
374
Adrian Hunter256d92b2018-12-21 14:06:19 +0200375void thread_stack__set_trace_nr(struct thread *thread, int cpu, u64 trace_nr)
Adrian Hunter92a9e4f2014-10-30 16:09:45 +0200376{
Adrian Hunter256d92b2018-12-21 14:06:19 +0200377 struct thread_stack *ts = thread__stack(thread, cpu);
Adrian Hunterbd8e68a2018-12-21 14:06:15 +0200378
379 if (!ts)
Adrian Hunter92a9e4f2014-10-30 16:09:45 +0200380 return;
381
Adrian Hunterbd8e68a2018-12-21 14:06:15 +0200382 if (trace_nr != ts->trace_nr) {
383 if (ts->trace_nr)
384 __thread_stack__flush(thread, ts);
385 ts->trace_nr = trace_nr;
Adrian Hunter92a9e4f2014-10-30 16:09:45 +0200386 }
387}
388
Adrian Hunterf6060ac2018-12-21 14:06:16 +0200389static void __thread_stack__free(struct thread *thread, struct thread_stack *ts)
390{
391 __thread_stack__flush(thread, ts);
392 zfree(&ts->stack);
393}
394
395static void thread_stack__reset(struct thread *thread, struct thread_stack *ts)
396{
397 unsigned int arr_sz = ts->arr_sz;
398
399 __thread_stack__free(thread, ts);
400 memset(ts, 0, sizeof(*ts));
401 ts->arr_sz = arr_sz;
402}
403
Adrian Hunter00447cc2014-10-30 16:09:42 +0200404void thread_stack__free(struct thread *thread)
405{
Adrian Hunterbd8e68a2018-12-21 14:06:15 +0200406 struct thread_stack *ts = thread->ts;
Adrian Hunterf6060ac2018-12-21 14:06:16 +0200407 unsigned int pos;
Adrian Hunterbd8e68a2018-12-21 14:06:15 +0200408
409 if (ts) {
Adrian Hunterf6060ac2018-12-21 14:06:16 +0200410 for (pos = 0; pos < ts->arr_sz; pos++)
411 __thread_stack__free(thread, ts + pos);
Adrian Hunter00447cc2014-10-30 16:09:42 +0200412 zfree(&thread->ts);
413 }
414}
415
Adrian Hunter24248302018-10-31 11:10:42 +0200416static inline u64 callchain_context(u64 ip, u64 kernel_start)
Adrian Hunter00447cc2014-10-30 16:09:42 +0200417{
Adrian Hunter24248302018-10-31 11:10:42 +0200418 return ip < kernel_start ? PERF_CONTEXT_USER : PERF_CONTEXT_KERNEL;
419}
Adrian Hunter00447cc2014-10-30 16:09:42 +0200420
Adrian Hunter256d92b2018-12-21 14:06:19 +0200421void thread_stack__sample(struct thread *thread, int cpu,
422 struct ip_callchain *chain,
Adrian Hunter24248302018-10-31 11:10:42 +0200423 size_t sz, u64 ip, u64 kernel_start)
424{
Adrian Hunter256d92b2018-12-21 14:06:19 +0200425 struct thread_stack *ts = thread__stack(thread, cpu);
Adrian Hunter24248302018-10-31 11:10:42 +0200426 u64 context = callchain_context(ip, kernel_start);
427 u64 last_context;
428 size_t i, j;
Adrian Hunter00447cc2014-10-30 16:09:42 +0200429
Adrian Hunter24248302018-10-31 11:10:42 +0200430 if (sz < 2) {
431 chain->nr = 0;
432 return;
433 }
Adrian Hunter00447cc2014-10-30 16:09:42 +0200434
Adrian Hunter24248302018-10-31 11:10:42 +0200435 chain->ips[0] = context;
436 chain->ips[1] = ip;
437
Adrian Hunterbd8e68a2018-12-21 14:06:15 +0200438 if (!ts) {
Adrian Hunter24248302018-10-31 11:10:42 +0200439 chain->nr = 2;
440 return;
441 }
442
443 last_context = context;
444
Adrian Hunterbd8e68a2018-12-21 14:06:15 +0200445 for (i = 2, j = 1; i < sz && j <= ts->cnt; i++, j++) {
446 ip = ts->stack[ts->cnt - j].ret_addr;
Adrian Hunter24248302018-10-31 11:10:42 +0200447 context = callchain_context(ip, kernel_start);
448 if (context != last_context) {
449 if (i >= sz - 1)
450 break;
451 chain->ips[i++] = context;
452 last_context = context;
453 }
454 chain->ips[i] = ip;
455 }
456
457 chain->nr = i;
Adrian Hunter00447cc2014-10-30 16:09:42 +0200458}
Adrian Hunter92a9e4f2014-10-30 16:09:45 +0200459
Adrian Hunter92a9e4f2014-10-30 16:09:45 +0200460struct call_return_processor *
461call_return_processor__new(int (*process)(struct call_return *cr, void *data),
462 void *data)
463{
464 struct call_return_processor *crp;
465
466 crp = zalloc(sizeof(struct call_return_processor));
467 if (!crp)
468 return NULL;
469 crp->cpr = call_path_root__new();
470 if (!crp->cpr)
471 goto out_free;
472 crp->process = process;
473 crp->data = data;
474 return crp;
475
476out_free:
477 free(crp);
478 return NULL;
479}
480
481void call_return_processor__free(struct call_return_processor *crp)
482{
483 if (crp) {
484 call_path_root__free(crp->cpr);
485 free(crp);
486 }
487}
488
489static int thread_stack__push_cp(struct thread_stack *ts, u64 ret_addr,
490 u64 timestamp, u64 ref, struct call_path *cp,
Adrian Hunter2dcde4e2018-09-20 16:00:46 +0300491 bool no_call, bool trace_end)
Adrian Hunter92a9e4f2014-10-30 16:09:45 +0200492{
493 struct thread_stack_entry *tse;
494 int err;
495
Adrian Huntere7a3a052019-01-09 11:18:31 +0200496 if (!cp)
497 return -ENOMEM;
498
Adrian Hunter92a9e4f2014-10-30 16:09:45 +0200499 if (ts->cnt == ts->sz) {
500 err = thread_stack__grow(ts);
501 if (err)
502 return err;
503 }
504
505 tse = &ts->stack[ts->cnt++];
506 tse->ret_addr = ret_addr;
507 tse->timestamp = timestamp;
508 tse->ref = ref;
509 tse->branch_count = ts->branch_count;
510 tse->cp = cp;
511 tse->no_call = no_call;
Adrian Hunter2dcde4e2018-09-20 16:00:46 +0300512 tse->trace_end = trace_end;
Adrian Hunter92a9e4f2014-10-30 16:09:45 +0200513
514 return 0;
515}
516
517static int thread_stack__pop_cp(struct thread *thread, struct thread_stack *ts,
518 u64 ret_addr, u64 timestamp, u64 ref,
519 struct symbol *sym)
520{
521 int err;
522
523 if (!ts->cnt)
524 return 1;
525
526 if (ts->cnt == 1) {
527 struct thread_stack_entry *tse = &ts->stack[0];
528
529 if (tse->cp->sym == sym)
530 return thread_stack__call_return(thread, ts, --ts->cnt,
531 timestamp, ref, false);
532 }
533
534 if (ts->stack[ts->cnt - 1].ret_addr == ret_addr) {
535 return thread_stack__call_return(thread, ts, --ts->cnt,
536 timestamp, ref, false);
537 } else {
538 size_t i = ts->cnt - 1;
539
540 while (i--) {
541 if (ts->stack[i].ret_addr != ret_addr)
542 continue;
543 i += 1;
544 while (ts->cnt > i) {
545 err = thread_stack__call_return(thread, ts,
546 --ts->cnt,
547 timestamp, ref,
548 true);
549 if (err)
550 return err;
551 }
552 return thread_stack__call_return(thread, ts, --ts->cnt,
553 timestamp, ref, false);
554 }
555 }
556
557 return 1;
558}
559
Adrian Huntere0b89512018-12-21 14:06:14 +0200560static int thread_stack__bottom(struct thread_stack *ts,
Adrian Hunter92a9e4f2014-10-30 16:09:45 +0200561 struct perf_sample *sample,
562 struct addr_location *from_al,
563 struct addr_location *to_al, u64 ref)
564{
565 struct call_path_root *cpr = ts->crp->cpr;
566 struct call_path *cp;
567 struct symbol *sym;
568 u64 ip;
569
570 if (sample->ip) {
571 ip = sample->ip;
572 sym = from_al->sym;
573 } else if (sample->addr) {
574 ip = sample->addr;
575 sym = to_al->sym;
576 } else {
577 return 0;
578 }
579
580 cp = call_path__findnew(cpr, &cpr->call_path, sym, ip,
581 ts->kernel_start);
Adrian Hunter92a9e4f2014-10-30 16:09:45 +0200582
Adrian Huntere0b89512018-12-21 14:06:14 +0200583 return thread_stack__push_cp(ts, ip, sample->time, ref, cp,
Adrian Hunter2dcde4e2018-09-20 16:00:46 +0300584 true, false);
Adrian Hunter92a9e4f2014-10-30 16:09:45 +0200585}
586
587static int thread_stack__no_call_return(struct thread *thread,
588 struct thread_stack *ts,
589 struct perf_sample *sample,
590 struct addr_location *from_al,
591 struct addr_location *to_al, u64 ref)
592{
593 struct call_path_root *cpr = ts->crp->cpr;
Adrian Hunter90c2cda2019-01-09 11:18:32 +0200594 struct call_path *root = &cpr->call_path;
595 struct symbol *fsym = from_al->sym;
596 struct symbol *tsym = to_al->sym;
Adrian Hunter92a9e4f2014-10-30 16:09:45 +0200597 struct call_path *cp, *parent;
598 u64 ks = ts->kernel_start;
Adrian Hunter90c2cda2019-01-09 11:18:32 +0200599 u64 addr = sample->addr;
600 u64 tm = sample->time;
601 u64 ip = sample->ip;
Adrian Hunter92a9e4f2014-10-30 16:09:45 +0200602 int err;
603
Adrian Hunter90c2cda2019-01-09 11:18:32 +0200604 if (ip >= ks && addr < ks) {
Adrian Hunter92a9e4f2014-10-30 16:09:45 +0200605 /* Return to userspace, so pop all kernel addresses */
606 while (thread_stack__in_kernel(ts)) {
607 err = thread_stack__call_return(thread, ts, --ts->cnt,
Adrian Hunter90c2cda2019-01-09 11:18:32 +0200608 tm, ref, true);
Adrian Hunter92a9e4f2014-10-30 16:09:45 +0200609 if (err)
610 return err;
611 }
612
613 /* If the stack is empty, push the userspace address */
614 if (!ts->cnt) {
Adrian Hunter90c2cda2019-01-09 11:18:32 +0200615 cp = call_path__findnew(cpr, root, tsym, addr, ks);
616 return thread_stack__push_cp(ts, 0, tm, ref, cp, true,
617 false);
Adrian Hunter92a9e4f2014-10-30 16:09:45 +0200618 }
Adrian Hunter90c2cda2019-01-09 11:18:32 +0200619 } else if (thread_stack__in_kernel(ts) && ip < ks) {
Adrian Hunter92a9e4f2014-10-30 16:09:45 +0200620 /* Return to userspace, so pop all kernel addresses */
621 while (thread_stack__in_kernel(ts)) {
622 err = thread_stack__call_return(thread, ts, --ts->cnt,
Adrian Hunter90c2cda2019-01-09 11:18:32 +0200623 tm, ref, true);
Adrian Hunter92a9e4f2014-10-30 16:09:45 +0200624 if (err)
625 return err;
626 }
627 }
628
629 if (ts->cnt)
630 parent = ts->stack[ts->cnt - 1].cp;
631 else
Adrian Hunter90c2cda2019-01-09 11:18:32 +0200632 parent = root;
Adrian Hunter92a9e4f2014-10-30 16:09:45 +0200633
634 /* This 'return' had no 'call', so push and pop top of stack */
Adrian Hunter90c2cda2019-01-09 11:18:32 +0200635 cp = call_path__findnew(cpr, parent, fsym, ip, ks);
Adrian Hunter92a9e4f2014-10-30 16:09:45 +0200636
Adrian Hunter90c2cda2019-01-09 11:18:32 +0200637 err = thread_stack__push_cp(ts, addr, tm, ref, cp, true, false);
Adrian Hunter92a9e4f2014-10-30 16:09:45 +0200638 if (err)
639 return err;
640
Adrian Hunter90c2cda2019-01-09 11:18:32 +0200641 return thread_stack__pop_cp(thread, ts, addr, tm, ref, tsym);
Adrian Hunter92a9e4f2014-10-30 16:09:45 +0200642}
643
644static int thread_stack__trace_begin(struct thread *thread,
645 struct thread_stack *ts, u64 timestamp,
646 u64 ref)
647{
648 struct thread_stack_entry *tse;
649 int err;
650
651 if (!ts->cnt)
652 return 0;
653
654 /* Pop trace end */
655 tse = &ts->stack[ts->cnt - 1];
Adrian Hunter2dcde4e2018-09-20 16:00:46 +0300656 if (tse->trace_end) {
Adrian Hunter92a9e4f2014-10-30 16:09:45 +0200657 err = thread_stack__call_return(thread, ts, --ts->cnt,
658 timestamp, ref, false);
659 if (err)
660 return err;
661 }
662
663 return 0;
664}
665
666static int thread_stack__trace_end(struct thread_stack *ts,
667 struct perf_sample *sample, u64 ref)
668{
669 struct call_path_root *cpr = ts->crp->cpr;
670 struct call_path *cp;
671 u64 ret_addr;
672
673 /* No point having 'trace end' on the bottom of the stack */
674 if (!ts->cnt || (ts->cnt == 1 && ts->stack[0].ref == ref))
675 return 0;
676
677 cp = call_path__findnew(cpr, ts->stack[ts->cnt - 1].cp, NULL, 0,
678 ts->kernel_start);
Adrian Hunter92a9e4f2014-10-30 16:09:45 +0200679
680 ret_addr = sample->ip + sample->insn_len;
681
682 return thread_stack__push_cp(ts, ret_addr, sample->time, ref, cp,
Adrian Hunter2dcde4e2018-09-20 16:00:46 +0300683 false, true);
Adrian Hunter92a9e4f2014-10-30 16:09:45 +0200684}
685
686int thread_stack__process(struct thread *thread, struct comm *comm,
687 struct perf_sample *sample,
688 struct addr_location *from_al,
689 struct addr_location *to_al, u64 ref,
690 struct call_return_processor *crp)
691{
Adrian Hunter256d92b2018-12-21 14:06:19 +0200692 struct thread_stack *ts = thread__stack(thread, sample->cpu);
Adrian Hunter92a9e4f2014-10-30 16:09:45 +0200693 int err = 0;
694
Adrian Hunter03b32cb2018-12-21 14:06:13 +0200695 if (ts && !ts->crp) {
696 /* Supersede thread_stack__event() */
Adrian Hunterf6060ac2018-12-21 14:06:16 +0200697 thread_stack__reset(thread, ts);
Adrian Hunter03b32cb2018-12-21 14:06:13 +0200698 ts = NULL;
699 }
700
701 if (!ts) {
Adrian Hunter256d92b2018-12-21 14:06:19 +0200702 ts = thread_stack__new(thread, sample->cpu, crp);
Adrian Hunterbd8e68a2018-12-21 14:06:15 +0200703 if (!ts)
Adrian Hunter92a9e4f2014-10-30 16:09:45 +0200704 return -ENOMEM;
Adrian Hunter92a9e4f2014-10-30 16:09:45 +0200705 ts->comm = comm;
706 }
707
708 /* Flush stack on exec */
709 if (ts->comm != comm && thread->pid_ == thread->tid) {
Adrian Huntera5499b32015-05-29 16:33:30 +0300710 err = __thread_stack__flush(thread, ts);
Adrian Hunter92a9e4f2014-10-30 16:09:45 +0200711 if (err)
712 return err;
713 ts->comm = comm;
714 }
715
716 /* If the stack is empty, put the current symbol on the stack */
717 if (!ts->cnt) {
Adrian Huntere0b89512018-12-21 14:06:14 +0200718 err = thread_stack__bottom(ts, sample, from_al, to_al, ref);
Adrian Hunter92a9e4f2014-10-30 16:09:45 +0200719 if (err)
720 return err;
721 }
722
723 ts->branch_count += 1;
724 ts->last_time = sample->time;
725
726 if (sample->flags & PERF_IP_FLAG_CALL) {
Adrian Hunter2dcde4e2018-09-20 16:00:46 +0300727 bool trace_end = sample->flags & PERF_IP_FLAG_TRACE_END;
Adrian Hunter92a9e4f2014-10-30 16:09:45 +0200728 struct call_path_root *cpr = ts->crp->cpr;
729 struct call_path *cp;
730 u64 ret_addr;
731
732 if (!sample->ip || !sample->addr)
733 return 0;
734
735 ret_addr = sample->ip + sample->insn_len;
736 if (ret_addr == sample->addr)
737 return 0; /* Zero-length calls are excluded */
738
739 cp = call_path__findnew(cpr, ts->stack[ts->cnt - 1].cp,
740 to_al->sym, sample->addr,
741 ts->kernel_start);
Adrian Hunter92a9e4f2014-10-30 16:09:45 +0200742 err = thread_stack__push_cp(ts, ret_addr, sample->time, ref,
Adrian Hunter2dcde4e2018-09-20 16:00:46 +0300743 cp, false, trace_end);
Adrian Hunter92a9e4f2014-10-30 16:09:45 +0200744 } else if (sample->flags & PERF_IP_FLAG_RETURN) {
745 if (!sample->ip || !sample->addr)
746 return 0;
747
748 err = thread_stack__pop_cp(thread, ts, sample->addr,
749 sample->time, ref, from_al->sym);
750 if (err) {
751 if (err < 0)
752 return err;
753 err = thread_stack__no_call_return(thread, ts, sample,
754 from_al, to_al, ref);
755 }
756 } else if (sample->flags & PERF_IP_FLAG_TRACE_BEGIN) {
757 err = thread_stack__trace_begin(thread, ts, sample->time, ref);
758 } else if (sample->flags & PERF_IP_FLAG_TRACE_END) {
759 err = thread_stack__trace_end(ts, sample, ref);
760 }
761
762 return err;
763}
Adrian Huntere2167082016-06-23 16:40:58 +0300764
Adrian Hunter256d92b2018-12-21 14:06:19 +0200765size_t thread_stack__depth(struct thread *thread, int cpu)
Adrian Huntere2167082016-06-23 16:40:58 +0300766{
Adrian Hunter256d92b2018-12-21 14:06:19 +0200767 struct thread_stack *ts = thread__stack(thread, cpu);
Adrian Hunterbd8e68a2018-12-21 14:06:15 +0200768
769 if (!ts)
Adrian Huntere2167082016-06-23 16:40:58 +0300770 return 0;
Adrian Hunterbd8e68a2018-12-21 14:06:15 +0200771 return ts->cnt;
Adrian Huntere2167082016-06-23 16:40:58 +0300772}