xref: /linux/tools/perf/util/thread-stack.c (revision 92a9e4f7db89a013e1bdef2e548928fc71e9867c)
100447ccdSAdrian Hunter /*
200447ccdSAdrian Hunter  * thread-stack.c: Synthesize a thread's stack using call / return events
300447ccdSAdrian Hunter  * Copyright (c) 2014, Intel Corporation.
400447ccdSAdrian Hunter  *
500447ccdSAdrian Hunter  * This program is free software; you can redistribute it and/or modify it
600447ccdSAdrian Hunter  * under the terms and conditions of the GNU General Public License,
700447ccdSAdrian Hunter  * version 2, as published by the Free Software Foundation.
800447ccdSAdrian Hunter  *
900447ccdSAdrian Hunter  * This program is distributed in the hope it will be useful, but WITHOUT
1000447ccdSAdrian Hunter  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1100447ccdSAdrian Hunter  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
1200447ccdSAdrian Hunter  * more details.
1300447ccdSAdrian Hunter  *
1400447ccdSAdrian Hunter  */
1500447ccdSAdrian Hunter 
16*92a9e4f7SAdrian Hunter #include <linux/rbtree.h>
17*92a9e4f7SAdrian Hunter #include <linux/list.h>
1800447ccdSAdrian Hunter #include "thread.h"
1900447ccdSAdrian Hunter #include "event.h"
20*92a9e4f7SAdrian Hunter #include "machine.h"
2100447ccdSAdrian Hunter #include "util.h"
2200447ccdSAdrian Hunter #include "debug.h"
23*92a9e4f7SAdrian Hunter #include "symbol.h"
24*92a9e4f7SAdrian Hunter #include "comm.h"
2500447ccdSAdrian Hunter #include "thread-stack.h"
2600447ccdSAdrian Hunter 
27*92a9e4f7SAdrian Hunter #define CALL_PATH_BLOCK_SHIFT 8
28*92a9e4f7SAdrian Hunter #define CALL_PATH_BLOCK_SIZE (1 << CALL_PATH_BLOCK_SHIFT)
29*92a9e4f7SAdrian Hunter #define CALL_PATH_BLOCK_MASK (CALL_PATH_BLOCK_SIZE - 1)
3000447ccdSAdrian Hunter 
31*92a9e4f7SAdrian Hunter struct call_path_block {
32*92a9e4f7SAdrian Hunter 	struct call_path cp[CALL_PATH_BLOCK_SIZE];
33*92a9e4f7SAdrian Hunter 	struct list_head node;
3400447ccdSAdrian Hunter };
3500447ccdSAdrian Hunter 
36*92a9e4f7SAdrian Hunter /**
37*92a9e4f7SAdrian Hunter  * struct call_path_root - root of all call paths.
38*92a9e4f7SAdrian Hunter  * @call_path: root call path
39*92a9e4f7SAdrian Hunter  * @blocks: list of blocks to store call paths
40*92a9e4f7SAdrian Hunter  * @next: next free space
41*92a9e4f7SAdrian Hunter  * @sz: number of spaces
42*92a9e4f7SAdrian Hunter  */
43*92a9e4f7SAdrian Hunter struct call_path_root {
44*92a9e4f7SAdrian Hunter 	struct call_path call_path;
45*92a9e4f7SAdrian Hunter 	struct list_head blocks;
46*92a9e4f7SAdrian Hunter 	size_t next;
47*92a9e4f7SAdrian Hunter 	size_t sz;
48*92a9e4f7SAdrian Hunter };
49*92a9e4f7SAdrian Hunter 
50*92a9e4f7SAdrian Hunter /**
51*92a9e4f7SAdrian Hunter  * struct call_return_processor - provides a call-back to consume call-return
52*92a9e4f7SAdrian Hunter  *                                information.
53*92a9e4f7SAdrian Hunter  * @cpr: call path root
54*92a9e4f7SAdrian Hunter  * @process: call-back that accepts call/return information
55*92a9e4f7SAdrian Hunter  * @data: anonymous data for call-back
56*92a9e4f7SAdrian Hunter  */
57*92a9e4f7SAdrian Hunter struct call_return_processor {
58*92a9e4f7SAdrian Hunter 	struct call_path_root *cpr;
59*92a9e4f7SAdrian Hunter 	int (*process)(struct call_return *cr, void *data);
60*92a9e4f7SAdrian Hunter 	void *data;
61*92a9e4f7SAdrian Hunter };
62*92a9e4f7SAdrian Hunter 
63*92a9e4f7SAdrian Hunter #define STACK_GROWTH 2048
64*92a9e4f7SAdrian Hunter 
65*92a9e4f7SAdrian Hunter /**
66*92a9e4f7SAdrian Hunter  * struct thread_stack_entry - thread stack entry.
67*92a9e4f7SAdrian Hunter  * @ret_addr: return address
68*92a9e4f7SAdrian Hunter  * @timestamp: timestamp (if known)
69*92a9e4f7SAdrian Hunter  * @ref: external reference (e.g. db_id of sample)
70*92a9e4f7SAdrian Hunter  * @branch_count: the branch count when the entry was created
71*92a9e4f7SAdrian Hunter  * @cp: call path
72*92a9e4f7SAdrian Hunter  * @no_call: a 'call' was not seen
73*92a9e4f7SAdrian Hunter  */
74*92a9e4f7SAdrian Hunter struct thread_stack_entry {
75*92a9e4f7SAdrian Hunter 	u64 ret_addr;
76*92a9e4f7SAdrian Hunter 	u64 timestamp;
77*92a9e4f7SAdrian Hunter 	u64 ref;
78*92a9e4f7SAdrian Hunter 	u64 branch_count;
79*92a9e4f7SAdrian Hunter 	struct call_path *cp;
80*92a9e4f7SAdrian Hunter 	bool no_call;
81*92a9e4f7SAdrian Hunter };
82*92a9e4f7SAdrian Hunter 
83*92a9e4f7SAdrian Hunter /**
84*92a9e4f7SAdrian Hunter  * struct thread_stack - thread stack constructed from 'call' and 'return'
85*92a9e4f7SAdrian Hunter  *                       branch samples.
86*92a9e4f7SAdrian Hunter  * @stack: array that holds the stack
87*92a9e4f7SAdrian Hunter  * @cnt: number of entries in the stack
88*92a9e4f7SAdrian Hunter  * @sz: current maximum stack size
89*92a9e4f7SAdrian Hunter  * @trace_nr: current trace number
90*92a9e4f7SAdrian Hunter  * @branch_count: running branch count
91*92a9e4f7SAdrian Hunter  * @kernel_start: kernel start address
92*92a9e4f7SAdrian Hunter  * @last_time: last timestamp
93*92a9e4f7SAdrian Hunter  * @crp: call/return processor
94*92a9e4f7SAdrian Hunter  * @comm: current comm
95*92a9e4f7SAdrian Hunter  */
9600447ccdSAdrian Hunter struct thread_stack {
9700447ccdSAdrian Hunter 	struct thread_stack_entry *stack;
9800447ccdSAdrian Hunter 	size_t cnt;
9900447ccdSAdrian Hunter 	size_t sz;
10000447ccdSAdrian Hunter 	u64 trace_nr;
101*92a9e4f7SAdrian Hunter 	u64 branch_count;
102*92a9e4f7SAdrian Hunter 	u64 kernel_start;
103*92a9e4f7SAdrian Hunter 	u64 last_time;
104*92a9e4f7SAdrian Hunter 	struct call_return_processor *crp;
105*92a9e4f7SAdrian Hunter 	struct comm *comm;
10600447ccdSAdrian Hunter };
10700447ccdSAdrian Hunter 
10800447ccdSAdrian Hunter static int thread_stack__grow(struct thread_stack *ts)
10900447ccdSAdrian Hunter {
11000447ccdSAdrian Hunter 	struct thread_stack_entry *new_stack;
11100447ccdSAdrian Hunter 	size_t sz, new_sz;
11200447ccdSAdrian Hunter 
11300447ccdSAdrian Hunter 	new_sz = ts->sz + STACK_GROWTH;
11400447ccdSAdrian Hunter 	sz = new_sz * sizeof(struct thread_stack_entry);
11500447ccdSAdrian Hunter 
11600447ccdSAdrian Hunter 	new_stack = realloc(ts->stack, sz);
11700447ccdSAdrian Hunter 	if (!new_stack)
11800447ccdSAdrian Hunter 		return -ENOMEM;
11900447ccdSAdrian Hunter 
12000447ccdSAdrian Hunter 	ts->stack = new_stack;
12100447ccdSAdrian Hunter 	ts->sz = new_sz;
12200447ccdSAdrian Hunter 
12300447ccdSAdrian Hunter 	return 0;
12400447ccdSAdrian Hunter }
12500447ccdSAdrian Hunter 
126*92a9e4f7SAdrian Hunter static struct thread_stack *thread_stack__new(struct thread *thread,
127*92a9e4f7SAdrian Hunter 					      struct call_return_processor *crp)
12800447ccdSAdrian Hunter {
12900447ccdSAdrian Hunter 	struct thread_stack *ts;
13000447ccdSAdrian Hunter 
13100447ccdSAdrian Hunter 	ts = zalloc(sizeof(struct thread_stack));
13200447ccdSAdrian Hunter 	if (!ts)
13300447ccdSAdrian Hunter 		return NULL;
13400447ccdSAdrian Hunter 
13500447ccdSAdrian Hunter 	if (thread_stack__grow(ts)) {
13600447ccdSAdrian Hunter 		free(ts);
13700447ccdSAdrian Hunter 		return NULL;
13800447ccdSAdrian Hunter 	}
13900447ccdSAdrian Hunter 
140*92a9e4f7SAdrian Hunter 	if (thread->mg && thread->mg->machine)
141*92a9e4f7SAdrian Hunter 		ts->kernel_start = machine__kernel_start(thread->mg->machine);
142*92a9e4f7SAdrian Hunter 	else
143*92a9e4f7SAdrian Hunter 		ts->kernel_start = 1ULL << 63;
144*92a9e4f7SAdrian Hunter 	ts->crp = crp;
145*92a9e4f7SAdrian Hunter 
14600447ccdSAdrian Hunter 	return ts;
14700447ccdSAdrian Hunter }
14800447ccdSAdrian Hunter 
14900447ccdSAdrian Hunter static int thread_stack__push(struct thread_stack *ts, u64 ret_addr)
15000447ccdSAdrian Hunter {
15100447ccdSAdrian Hunter 	int err = 0;
15200447ccdSAdrian Hunter 
15300447ccdSAdrian Hunter 	if (ts->cnt == ts->sz) {
15400447ccdSAdrian Hunter 		err = thread_stack__grow(ts);
15500447ccdSAdrian Hunter 		if (err) {
15600447ccdSAdrian Hunter 			pr_warning("Out of memory: discarding thread stack\n");
15700447ccdSAdrian Hunter 			ts->cnt = 0;
15800447ccdSAdrian Hunter 		}
15900447ccdSAdrian Hunter 	}
16000447ccdSAdrian Hunter 
16100447ccdSAdrian Hunter 	ts->stack[ts->cnt++].ret_addr = ret_addr;
16200447ccdSAdrian Hunter 
16300447ccdSAdrian Hunter 	return err;
16400447ccdSAdrian Hunter }
16500447ccdSAdrian Hunter 
16600447ccdSAdrian Hunter static void thread_stack__pop(struct thread_stack *ts, u64 ret_addr)
16700447ccdSAdrian Hunter {
16800447ccdSAdrian Hunter 	size_t i;
16900447ccdSAdrian Hunter 
17000447ccdSAdrian Hunter 	/*
17100447ccdSAdrian Hunter 	 * In some cases there may be functions which are not seen to return.
17200447ccdSAdrian Hunter 	 * For example when setjmp / longjmp has been used.  Or the perf context
17300447ccdSAdrian Hunter 	 * switch in the kernel which doesn't stop and start tracing in exactly
17400447ccdSAdrian Hunter 	 * the same code path.  When that happens the return address will be
17500447ccdSAdrian Hunter 	 * further down the stack.  If the return address is not found at all,
17600447ccdSAdrian Hunter 	 * we assume the opposite (i.e. this is a return for a call that wasn't
17700447ccdSAdrian Hunter 	 * seen for some reason) and leave the stack alone.
17800447ccdSAdrian Hunter 	 */
17900447ccdSAdrian Hunter 	for (i = ts->cnt; i; ) {
18000447ccdSAdrian Hunter 		if (ts->stack[--i].ret_addr == ret_addr) {
18100447ccdSAdrian Hunter 			ts->cnt = i;
18200447ccdSAdrian Hunter 			return;
18300447ccdSAdrian Hunter 		}
18400447ccdSAdrian Hunter 	}
18500447ccdSAdrian Hunter }
18600447ccdSAdrian Hunter 
187*92a9e4f7SAdrian Hunter static bool thread_stack__in_kernel(struct thread_stack *ts)
188*92a9e4f7SAdrian Hunter {
189*92a9e4f7SAdrian Hunter 	if (!ts->cnt)
190*92a9e4f7SAdrian Hunter 		return false;
191*92a9e4f7SAdrian Hunter 
192*92a9e4f7SAdrian Hunter 	return ts->stack[ts->cnt - 1].cp->in_kernel;
193*92a9e4f7SAdrian Hunter }
194*92a9e4f7SAdrian Hunter 
195*92a9e4f7SAdrian Hunter static int thread_stack__call_return(struct thread *thread,
196*92a9e4f7SAdrian Hunter 				     struct thread_stack *ts, size_t idx,
197*92a9e4f7SAdrian Hunter 				     u64 timestamp, u64 ref, bool no_return)
198*92a9e4f7SAdrian Hunter {
199*92a9e4f7SAdrian Hunter 	struct call_return_processor *crp = ts->crp;
200*92a9e4f7SAdrian Hunter 	struct thread_stack_entry *tse;
201*92a9e4f7SAdrian Hunter 	struct call_return cr = {
202*92a9e4f7SAdrian Hunter 		.thread = thread,
203*92a9e4f7SAdrian Hunter 		.comm = ts->comm,
204*92a9e4f7SAdrian Hunter 		.db_id = 0,
205*92a9e4f7SAdrian Hunter 	};
206*92a9e4f7SAdrian Hunter 
207*92a9e4f7SAdrian Hunter 	tse = &ts->stack[idx];
208*92a9e4f7SAdrian Hunter 	cr.cp = tse->cp;
209*92a9e4f7SAdrian Hunter 	cr.call_time = tse->timestamp;
210*92a9e4f7SAdrian Hunter 	cr.return_time = timestamp;
211*92a9e4f7SAdrian Hunter 	cr.branch_count = ts->branch_count - tse->branch_count;
212*92a9e4f7SAdrian Hunter 	cr.call_ref = tse->ref;
213*92a9e4f7SAdrian Hunter 	cr.return_ref = ref;
214*92a9e4f7SAdrian Hunter 	if (tse->no_call)
215*92a9e4f7SAdrian Hunter 		cr.flags |= CALL_RETURN_NO_CALL;
216*92a9e4f7SAdrian Hunter 	if (no_return)
217*92a9e4f7SAdrian Hunter 		cr.flags |= CALL_RETURN_NO_RETURN;
218*92a9e4f7SAdrian Hunter 
219*92a9e4f7SAdrian Hunter 	return crp->process(&cr, crp->data);
220*92a9e4f7SAdrian Hunter }
221*92a9e4f7SAdrian Hunter 
222*92a9e4f7SAdrian Hunter static int thread_stack__flush(struct thread *thread, struct thread_stack *ts)
223*92a9e4f7SAdrian Hunter {
224*92a9e4f7SAdrian Hunter 	struct call_return_processor *crp = ts->crp;
225*92a9e4f7SAdrian Hunter 	int err;
226*92a9e4f7SAdrian Hunter 
227*92a9e4f7SAdrian Hunter 	if (!crp) {
228*92a9e4f7SAdrian Hunter 		ts->cnt = 0;
229*92a9e4f7SAdrian Hunter 		return 0;
230*92a9e4f7SAdrian Hunter 	}
231*92a9e4f7SAdrian Hunter 
232*92a9e4f7SAdrian Hunter 	while (ts->cnt) {
233*92a9e4f7SAdrian Hunter 		err = thread_stack__call_return(thread, ts, --ts->cnt,
234*92a9e4f7SAdrian Hunter 						ts->last_time, 0, true);
235*92a9e4f7SAdrian Hunter 		if (err) {
236*92a9e4f7SAdrian Hunter 			pr_err("Error flushing thread stack!\n");
237*92a9e4f7SAdrian Hunter 			ts->cnt = 0;
238*92a9e4f7SAdrian Hunter 			return err;
239*92a9e4f7SAdrian Hunter 		}
240*92a9e4f7SAdrian Hunter 	}
241*92a9e4f7SAdrian Hunter 
242*92a9e4f7SAdrian Hunter 	return 0;
243*92a9e4f7SAdrian Hunter }
244*92a9e4f7SAdrian Hunter 
24500447ccdSAdrian Hunter int thread_stack__event(struct thread *thread, u32 flags, u64 from_ip,
24600447ccdSAdrian Hunter 			u64 to_ip, u16 insn_len, u64 trace_nr)
24700447ccdSAdrian Hunter {
24800447ccdSAdrian Hunter 	if (!thread)
24900447ccdSAdrian Hunter 		return -EINVAL;
25000447ccdSAdrian Hunter 
25100447ccdSAdrian Hunter 	if (!thread->ts) {
252*92a9e4f7SAdrian Hunter 		thread->ts = thread_stack__new(thread, NULL);
25300447ccdSAdrian Hunter 		if (!thread->ts) {
25400447ccdSAdrian Hunter 			pr_warning("Out of memory: no thread stack\n");
25500447ccdSAdrian Hunter 			return -ENOMEM;
25600447ccdSAdrian Hunter 		}
25700447ccdSAdrian Hunter 		thread->ts->trace_nr = trace_nr;
25800447ccdSAdrian Hunter 	}
25900447ccdSAdrian Hunter 
26000447ccdSAdrian Hunter 	/*
26100447ccdSAdrian Hunter 	 * When the trace is discontinuous, the trace_nr changes.  In that case
26200447ccdSAdrian Hunter 	 * the stack might be completely invalid.  Better to report nothing than
263*92a9e4f7SAdrian Hunter 	 * to report something misleading, so flush the stack.
26400447ccdSAdrian Hunter 	 */
26500447ccdSAdrian Hunter 	if (trace_nr != thread->ts->trace_nr) {
266*92a9e4f7SAdrian Hunter 		if (thread->ts->trace_nr)
267*92a9e4f7SAdrian Hunter 			thread_stack__flush(thread, thread->ts);
26800447ccdSAdrian Hunter 		thread->ts->trace_nr = trace_nr;
26900447ccdSAdrian Hunter 	}
27000447ccdSAdrian Hunter 
271*92a9e4f7SAdrian Hunter 	/* Stop here if thread_stack__process() is in use */
272*92a9e4f7SAdrian Hunter 	if (thread->ts->crp)
273*92a9e4f7SAdrian Hunter 		return 0;
274*92a9e4f7SAdrian Hunter 
27500447ccdSAdrian Hunter 	if (flags & PERF_IP_FLAG_CALL) {
27600447ccdSAdrian Hunter 		u64 ret_addr;
27700447ccdSAdrian Hunter 
27800447ccdSAdrian Hunter 		if (!to_ip)
27900447ccdSAdrian Hunter 			return 0;
28000447ccdSAdrian Hunter 		ret_addr = from_ip + insn_len;
28100447ccdSAdrian Hunter 		if (ret_addr == to_ip)
28200447ccdSAdrian Hunter 			return 0; /* Zero-length calls are excluded */
28300447ccdSAdrian Hunter 		return thread_stack__push(thread->ts, ret_addr);
28400447ccdSAdrian Hunter 	} else if (flags & PERF_IP_FLAG_RETURN) {
28500447ccdSAdrian Hunter 		if (!from_ip)
28600447ccdSAdrian Hunter 			return 0;
28700447ccdSAdrian Hunter 		thread_stack__pop(thread->ts, to_ip);
28800447ccdSAdrian Hunter 	}
28900447ccdSAdrian Hunter 
29000447ccdSAdrian Hunter 	return 0;
29100447ccdSAdrian Hunter }
29200447ccdSAdrian Hunter 
293*92a9e4f7SAdrian Hunter void thread_stack__set_trace_nr(struct thread *thread, u64 trace_nr)
294*92a9e4f7SAdrian Hunter {
295*92a9e4f7SAdrian Hunter 	if (!thread || !thread->ts)
296*92a9e4f7SAdrian Hunter 		return;
297*92a9e4f7SAdrian Hunter 
298*92a9e4f7SAdrian Hunter 	if (trace_nr != thread->ts->trace_nr) {
299*92a9e4f7SAdrian Hunter 		if (thread->ts->trace_nr)
300*92a9e4f7SAdrian Hunter 			thread_stack__flush(thread, thread->ts);
301*92a9e4f7SAdrian Hunter 		thread->ts->trace_nr = trace_nr;
302*92a9e4f7SAdrian Hunter 	}
303*92a9e4f7SAdrian Hunter }
304*92a9e4f7SAdrian Hunter 
30500447ccdSAdrian Hunter void thread_stack__free(struct thread *thread)
30600447ccdSAdrian Hunter {
30700447ccdSAdrian Hunter 	if (thread->ts) {
308*92a9e4f7SAdrian Hunter 		thread_stack__flush(thread, thread->ts);
30900447ccdSAdrian Hunter 		zfree(&thread->ts->stack);
31000447ccdSAdrian Hunter 		zfree(&thread->ts);
31100447ccdSAdrian Hunter 	}
31200447ccdSAdrian Hunter }
31300447ccdSAdrian Hunter 
31400447ccdSAdrian Hunter void thread_stack__sample(struct thread *thread, struct ip_callchain *chain,
31500447ccdSAdrian Hunter 			  size_t sz, u64 ip)
31600447ccdSAdrian Hunter {
31700447ccdSAdrian Hunter 	size_t i;
31800447ccdSAdrian Hunter 
31900447ccdSAdrian Hunter 	if (!thread || !thread->ts)
32000447ccdSAdrian Hunter 		chain->nr = 1;
32100447ccdSAdrian Hunter 	else
32200447ccdSAdrian Hunter 		chain->nr = min(sz, thread->ts->cnt + 1);
32300447ccdSAdrian Hunter 
32400447ccdSAdrian Hunter 	chain->ips[0] = ip;
32500447ccdSAdrian Hunter 
32600447ccdSAdrian Hunter 	for (i = 1; i < chain->nr; i++)
32700447ccdSAdrian Hunter 		chain->ips[i] = thread->ts->stack[thread->ts->cnt - i].ret_addr;
32800447ccdSAdrian Hunter }
329*92a9e4f7SAdrian Hunter 
330*92a9e4f7SAdrian Hunter static void call_path__init(struct call_path *cp, struct call_path *parent,
331*92a9e4f7SAdrian Hunter 			    struct symbol *sym, u64 ip, bool in_kernel)
332*92a9e4f7SAdrian Hunter {
333*92a9e4f7SAdrian Hunter 	cp->parent = parent;
334*92a9e4f7SAdrian Hunter 	cp->sym = sym;
335*92a9e4f7SAdrian Hunter 	cp->ip = sym ? 0 : ip;
336*92a9e4f7SAdrian Hunter 	cp->db_id = 0;
337*92a9e4f7SAdrian Hunter 	cp->in_kernel = in_kernel;
338*92a9e4f7SAdrian Hunter 	RB_CLEAR_NODE(&cp->rb_node);
339*92a9e4f7SAdrian Hunter 	cp->children = RB_ROOT;
340*92a9e4f7SAdrian Hunter }
341*92a9e4f7SAdrian Hunter 
342*92a9e4f7SAdrian Hunter static struct call_path_root *call_path_root__new(void)
343*92a9e4f7SAdrian Hunter {
344*92a9e4f7SAdrian Hunter 	struct call_path_root *cpr;
345*92a9e4f7SAdrian Hunter 
346*92a9e4f7SAdrian Hunter 	cpr = zalloc(sizeof(struct call_path_root));
347*92a9e4f7SAdrian Hunter 	if (!cpr)
348*92a9e4f7SAdrian Hunter 		return NULL;
349*92a9e4f7SAdrian Hunter 	call_path__init(&cpr->call_path, NULL, NULL, 0, false);
350*92a9e4f7SAdrian Hunter 	INIT_LIST_HEAD(&cpr->blocks);
351*92a9e4f7SAdrian Hunter 	return cpr;
352*92a9e4f7SAdrian Hunter }
353*92a9e4f7SAdrian Hunter 
354*92a9e4f7SAdrian Hunter static void call_path_root__free(struct call_path_root *cpr)
355*92a9e4f7SAdrian Hunter {
356*92a9e4f7SAdrian Hunter 	struct call_path_block *pos, *n;
357*92a9e4f7SAdrian Hunter 
358*92a9e4f7SAdrian Hunter 	list_for_each_entry_safe(pos, n, &cpr->blocks, node) {
359*92a9e4f7SAdrian Hunter 		list_del(&pos->node);
360*92a9e4f7SAdrian Hunter 		free(pos);
361*92a9e4f7SAdrian Hunter 	}
362*92a9e4f7SAdrian Hunter 	free(cpr);
363*92a9e4f7SAdrian Hunter }
364*92a9e4f7SAdrian Hunter 
365*92a9e4f7SAdrian Hunter static struct call_path *call_path__new(struct call_path_root *cpr,
366*92a9e4f7SAdrian Hunter 					struct call_path *parent,
367*92a9e4f7SAdrian Hunter 					struct symbol *sym, u64 ip,
368*92a9e4f7SAdrian Hunter 					bool in_kernel)
369*92a9e4f7SAdrian Hunter {
370*92a9e4f7SAdrian Hunter 	struct call_path_block *cpb;
371*92a9e4f7SAdrian Hunter 	struct call_path *cp;
372*92a9e4f7SAdrian Hunter 	size_t n;
373*92a9e4f7SAdrian Hunter 
374*92a9e4f7SAdrian Hunter 	if (cpr->next < cpr->sz) {
375*92a9e4f7SAdrian Hunter 		cpb = list_last_entry(&cpr->blocks, struct call_path_block,
376*92a9e4f7SAdrian Hunter 				      node);
377*92a9e4f7SAdrian Hunter 	} else {
378*92a9e4f7SAdrian Hunter 		cpb = zalloc(sizeof(struct call_path_block));
379*92a9e4f7SAdrian Hunter 		if (!cpb)
380*92a9e4f7SAdrian Hunter 			return NULL;
381*92a9e4f7SAdrian Hunter 		list_add_tail(&cpb->node, &cpr->blocks);
382*92a9e4f7SAdrian Hunter 		cpr->sz += CALL_PATH_BLOCK_SIZE;
383*92a9e4f7SAdrian Hunter 	}
384*92a9e4f7SAdrian Hunter 
385*92a9e4f7SAdrian Hunter 	n = cpr->next++ & CALL_PATH_BLOCK_MASK;
386*92a9e4f7SAdrian Hunter 	cp = &cpb->cp[n];
387*92a9e4f7SAdrian Hunter 
388*92a9e4f7SAdrian Hunter 	call_path__init(cp, parent, sym, ip, in_kernel);
389*92a9e4f7SAdrian Hunter 
390*92a9e4f7SAdrian Hunter 	return cp;
391*92a9e4f7SAdrian Hunter }
392*92a9e4f7SAdrian Hunter 
393*92a9e4f7SAdrian Hunter static struct call_path *call_path__findnew(struct call_path_root *cpr,
394*92a9e4f7SAdrian Hunter 					    struct call_path *parent,
395*92a9e4f7SAdrian Hunter 					    struct symbol *sym, u64 ip, u64 ks)
396*92a9e4f7SAdrian Hunter {
397*92a9e4f7SAdrian Hunter 	struct rb_node **p;
398*92a9e4f7SAdrian Hunter 	struct rb_node *node_parent = NULL;
399*92a9e4f7SAdrian Hunter 	struct call_path *cp;
400*92a9e4f7SAdrian Hunter 	bool in_kernel = ip >= ks;
401*92a9e4f7SAdrian Hunter 
402*92a9e4f7SAdrian Hunter 	if (sym)
403*92a9e4f7SAdrian Hunter 		ip = 0;
404*92a9e4f7SAdrian Hunter 
405*92a9e4f7SAdrian Hunter 	if (!parent)
406*92a9e4f7SAdrian Hunter 		return call_path__new(cpr, parent, sym, ip, in_kernel);
407*92a9e4f7SAdrian Hunter 
408*92a9e4f7SAdrian Hunter 	p = &parent->children.rb_node;
409*92a9e4f7SAdrian Hunter 	while (*p != NULL) {
410*92a9e4f7SAdrian Hunter 		node_parent = *p;
411*92a9e4f7SAdrian Hunter 		cp = rb_entry(node_parent, struct call_path, rb_node);
412*92a9e4f7SAdrian Hunter 
413*92a9e4f7SAdrian Hunter 		if (cp->sym == sym && cp->ip == ip)
414*92a9e4f7SAdrian Hunter 			return cp;
415*92a9e4f7SAdrian Hunter 
416*92a9e4f7SAdrian Hunter 		if (sym < cp->sym || (sym == cp->sym && ip < cp->ip))
417*92a9e4f7SAdrian Hunter 			p = &(*p)->rb_left;
418*92a9e4f7SAdrian Hunter 		else
419*92a9e4f7SAdrian Hunter 			p = &(*p)->rb_right;
420*92a9e4f7SAdrian Hunter 	}
421*92a9e4f7SAdrian Hunter 
422*92a9e4f7SAdrian Hunter 	cp = call_path__new(cpr, parent, sym, ip, in_kernel);
423*92a9e4f7SAdrian Hunter 	if (!cp)
424*92a9e4f7SAdrian Hunter 		return NULL;
425*92a9e4f7SAdrian Hunter 
426*92a9e4f7SAdrian Hunter 	rb_link_node(&cp->rb_node, node_parent, p);
427*92a9e4f7SAdrian Hunter 	rb_insert_color(&cp->rb_node, &parent->children);
428*92a9e4f7SAdrian Hunter 
429*92a9e4f7SAdrian Hunter 	return cp;
430*92a9e4f7SAdrian Hunter }
431*92a9e4f7SAdrian Hunter 
432*92a9e4f7SAdrian Hunter struct call_return_processor *
433*92a9e4f7SAdrian Hunter call_return_processor__new(int (*process)(struct call_return *cr, void *data),
434*92a9e4f7SAdrian Hunter 			   void *data)
435*92a9e4f7SAdrian Hunter {
436*92a9e4f7SAdrian Hunter 	struct call_return_processor *crp;
437*92a9e4f7SAdrian Hunter 
438*92a9e4f7SAdrian Hunter 	crp = zalloc(sizeof(struct call_return_processor));
439*92a9e4f7SAdrian Hunter 	if (!crp)
440*92a9e4f7SAdrian Hunter 		return NULL;
441*92a9e4f7SAdrian Hunter 	crp->cpr = call_path_root__new();
442*92a9e4f7SAdrian Hunter 	if (!crp->cpr)
443*92a9e4f7SAdrian Hunter 		goto out_free;
444*92a9e4f7SAdrian Hunter 	crp->process = process;
445*92a9e4f7SAdrian Hunter 	crp->data = data;
446*92a9e4f7SAdrian Hunter 	return crp;
447*92a9e4f7SAdrian Hunter 
448*92a9e4f7SAdrian Hunter out_free:
449*92a9e4f7SAdrian Hunter 	free(crp);
450*92a9e4f7SAdrian Hunter 	return NULL;
451*92a9e4f7SAdrian Hunter }
452*92a9e4f7SAdrian Hunter 
453*92a9e4f7SAdrian Hunter void call_return_processor__free(struct call_return_processor *crp)
454*92a9e4f7SAdrian Hunter {
455*92a9e4f7SAdrian Hunter 	if (crp) {
456*92a9e4f7SAdrian Hunter 		call_path_root__free(crp->cpr);
457*92a9e4f7SAdrian Hunter 		free(crp);
458*92a9e4f7SAdrian Hunter 	}
459*92a9e4f7SAdrian Hunter }
460*92a9e4f7SAdrian Hunter 
461*92a9e4f7SAdrian Hunter static int thread_stack__push_cp(struct thread_stack *ts, u64 ret_addr,
462*92a9e4f7SAdrian Hunter 				 u64 timestamp, u64 ref, struct call_path *cp,
463*92a9e4f7SAdrian Hunter 				 bool no_call)
464*92a9e4f7SAdrian Hunter {
465*92a9e4f7SAdrian Hunter 	struct thread_stack_entry *tse;
466*92a9e4f7SAdrian Hunter 	int err;
467*92a9e4f7SAdrian Hunter 
468*92a9e4f7SAdrian Hunter 	if (ts->cnt == ts->sz) {
469*92a9e4f7SAdrian Hunter 		err = thread_stack__grow(ts);
470*92a9e4f7SAdrian Hunter 		if (err)
471*92a9e4f7SAdrian Hunter 			return err;
472*92a9e4f7SAdrian Hunter 	}
473*92a9e4f7SAdrian Hunter 
474*92a9e4f7SAdrian Hunter 	tse = &ts->stack[ts->cnt++];
475*92a9e4f7SAdrian Hunter 	tse->ret_addr = ret_addr;
476*92a9e4f7SAdrian Hunter 	tse->timestamp = timestamp;
477*92a9e4f7SAdrian Hunter 	tse->ref = ref;
478*92a9e4f7SAdrian Hunter 	tse->branch_count = ts->branch_count;
479*92a9e4f7SAdrian Hunter 	tse->cp = cp;
480*92a9e4f7SAdrian Hunter 	tse->no_call = no_call;
481*92a9e4f7SAdrian Hunter 
482*92a9e4f7SAdrian Hunter 	return 0;
483*92a9e4f7SAdrian Hunter }
484*92a9e4f7SAdrian Hunter 
485*92a9e4f7SAdrian Hunter static int thread_stack__pop_cp(struct thread *thread, struct thread_stack *ts,
486*92a9e4f7SAdrian Hunter 				u64 ret_addr, u64 timestamp, u64 ref,
487*92a9e4f7SAdrian Hunter 				struct symbol *sym)
488*92a9e4f7SAdrian Hunter {
489*92a9e4f7SAdrian Hunter 	int err;
490*92a9e4f7SAdrian Hunter 
491*92a9e4f7SAdrian Hunter 	if (!ts->cnt)
492*92a9e4f7SAdrian Hunter 		return 1;
493*92a9e4f7SAdrian Hunter 
494*92a9e4f7SAdrian Hunter 	if (ts->cnt == 1) {
495*92a9e4f7SAdrian Hunter 		struct thread_stack_entry *tse = &ts->stack[0];
496*92a9e4f7SAdrian Hunter 
497*92a9e4f7SAdrian Hunter 		if (tse->cp->sym == sym)
498*92a9e4f7SAdrian Hunter 			return thread_stack__call_return(thread, ts, --ts->cnt,
499*92a9e4f7SAdrian Hunter 							 timestamp, ref, false);
500*92a9e4f7SAdrian Hunter 	}
501*92a9e4f7SAdrian Hunter 
502*92a9e4f7SAdrian Hunter 	if (ts->stack[ts->cnt - 1].ret_addr == ret_addr) {
503*92a9e4f7SAdrian Hunter 		return thread_stack__call_return(thread, ts, --ts->cnt,
504*92a9e4f7SAdrian Hunter 						 timestamp, ref, false);
505*92a9e4f7SAdrian Hunter 	} else {
506*92a9e4f7SAdrian Hunter 		size_t i = ts->cnt - 1;
507*92a9e4f7SAdrian Hunter 
508*92a9e4f7SAdrian Hunter 		while (i--) {
509*92a9e4f7SAdrian Hunter 			if (ts->stack[i].ret_addr != ret_addr)
510*92a9e4f7SAdrian Hunter 				continue;
511*92a9e4f7SAdrian Hunter 			i += 1;
512*92a9e4f7SAdrian Hunter 			while (ts->cnt > i) {
513*92a9e4f7SAdrian Hunter 				err = thread_stack__call_return(thread, ts,
514*92a9e4f7SAdrian Hunter 								--ts->cnt,
515*92a9e4f7SAdrian Hunter 								timestamp, ref,
516*92a9e4f7SAdrian Hunter 								true);
517*92a9e4f7SAdrian Hunter 				if (err)
518*92a9e4f7SAdrian Hunter 					return err;
519*92a9e4f7SAdrian Hunter 			}
520*92a9e4f7SAdrian Hunter 			return thread_stack__call_return(thread, ts, --ts->cnt,
521*92a9e4f7SAdrian Hunter 							 timestamp, ref, false);
522*92a9e4f7SAdrian Hunter 		}
523*92a9e4f7SAdrian Hunter 	}
524*92a9e4f7SAdrian Hunter 
525*92a9e4f7SAdrian Hunter 	return 1;
526*92a9e4f7SAdrian Hunter }
527*92a9e4f7SAdrian Hunter 
528*92a9e4f7SAdrian Hunter static int thread_stack__bottom(struct thread *thread, struct thread_stack *ts,
529*92a9e4f7SAdrian Hunter 				struct perf_sample *sample,
530*92a9e4f7SAdrian Hunter 				struct addr_location *from_al,
531*92a9e4f7SAdrian Hunter 				struct addr_location *to_al, u64 ref)
532*92a9e4f7SAdrian Hunter {
533*92a9e4f7SAdrian Hunter 	struct call_path_root *cpr = ts->crp->cpr;
534*92a9e4f7SAdrian Hunter 	struct call_path *cp;
535*92a9e4f7SAdrian Hunter 	struct symbol *sym;
536*92a9e4f7SAdrian Hunter 	u64 ip;
537*92a9e4f7SAdrian Hunter 
538*92a9e4f7SAdrian Hunter 	if (sample->ip) {
539*92a9e4f7SAdrian Hunter 		ip = sample->ip;
540*92a9e4f7SAdrian Hunter 		sym = from_al->sym;
541*92a9e4f7SAdrian Hunter 	} else if (sample->addr) {
542*92a9e4f7SAdrian Hunter 		ip = sample->addr;
543*92a9e4f7SAdrian Hunter 		sym = to_al->sym;
544*92a9e4f7SAdrian Hunter 	} else {
545*92a9e4f7SAdrian Hunter 		return 0;
546*92a9e4f7SAdrian Hunter 	}
547*92a9e4f7SAdrian Hunter 
548*92a9e4f7SAdrian Hunter 	cp = call_path__findnew(cpr, &cpr->call_path, sym, ip,
549*92a9e4f7SAdrian Hunter 				ts->kernel_start);
550*92a9e4f7SAdrian Hunter 	if (!cp)
551*92a9e4f7SAdrian Hunter 		return -ENOMEM;
552*92a9e4f7SAdrian Hunter 
553*92a9e4f7SAdrian Hunter 	return thread_stack__push_cp(thread->ts, ip, sample->time, ref, cp,
554*92a9e4f7SAdrian Hunter 				     true);
555*92a9e4f7SAdrian Hunter }
556*92a9e4f7SAdrian Hunter 
557*92a9e4f7SAdrian Hunter static int thread_stack__no_call_return(struct thread *thread,
558*92a9e4f7SAdrian Hunter 					struct thread_stack *ts,
559*92a9e4f7SAdrian Hunter 					struct perf_sample *sample,
560*92a9e4f7SAdrian Hunter 					struct addr_location *from_al,
561*92a9e4f7SAdrian Hunter 					struct addr_location *to_al, u64 ref)
562*92a9e4f7SAdrian Hunter {
563*92a9e4f7SAdrian Hunter 	struct call_path_root *cpr = ts->crp->cpr;
564*92a9e4f7SAdrian Hunter 	struct call_path *cp, *parent;
565*92a9e4f7SAdrian Hunter 	u64 ks = ts->kernel_start;
566*92a9e4f7SAdrian Hunter 	int err;
567*92a9e4f7SAdrian Hunter 
568*92a9e4f7SAdrian Hunter 	if (sample->ip >= ks && sample->addr < ks) {
569*92a9e4f7SAdrian Hunter 		/* Return to userspace, so pop all kernel addresses */
570*92a9e4f7SAdrian Hunter 		while (thread_stack__in_kernel(ts)) {
571*92a9e4f7SAdrian Hunter 			err = thread_stack__call_return(thread, ts, --ts->cnt,
572*92a9e4f7SAdrian Hunter 							sample->time, ref,
573*92a9e4f7SAdrian Hunter 							true);
574*92a9e4f7SAdrian Hunter 			if (err)
575*92a9e4f7SAdrian Hunter 				return err;
576*92a9e4f7SAdrian Hunter 		}
577*92a9e4f7SAdrian Hunter 
578*92a9e4f7SAdrian Hunter 		/* If the stack is empty, push the userspace address */
579*92a9e4f7SAdrian Hunter 		if (!ts->cnt) {
580*92a9e4f7SAdrian Hunter 			cp = call_path__findnew(cpr, &cpr->call_path,
581*92a9e4f7SAdrian Hunter 						to_al->sym, sample->addr,
582*92a9e4f7SAdrian Hunter 						ts->kernel_start);
583*92a9e4f7SAdrian Hunter 			if (!cp)
584*92a9e4f7SAdrian Hunter 				return -ENOMEM;
585*92a9e4f7SAdrian Hunter 			return thread_stack__push_cp(ts, 0, sample->time, ref,
586*92a9e4f7SAdrian Hunter 						     cp, true);
587*92a9e4f7SAdrian Hunter 		}
588*92a9e4f7SAdrian Hunter 	} else if (thread_stack__in_kernel(ts) && sample->ip < ks) {
589*92a9e4f7SAdrian Hunter 		/* Return to userspace, so pop all kernel addresses */
590*92a9e4f7SAdrian Hunter 		while (thread_stack__in_kernel(ts)) {
591*92a9e4f7SAdrian Hunter 			err = thread_stack__call_return(thread, ts, --ts->cnt,
592*92a9e4f7SAdrian Hunter 							sample->time, ref,
593*92a9e4f7SAdrian Hunter 							true);
594*92a9e4f7SAdrian Hunter 			if (err)
595*92a9e4f7SAdrian Hunter 				return err;
596*92a9e4f7SAdrian Hunter 		}
597*92a9e4f7SAdrian Hunter 	}
598*92a9e4f7SAdrian Hunter 
599*92a9e4f7SAdrian Hunter 	if (ts->cnt)
600*92a9e4f7SAdrian Hunter 		parent = ts->stack[ts->cnt - 1].cp;
601*92a9e4f7SAdrian Hunter 	else
602*92a9e4f7SAdrian Hunter 		parent = &cpr->call_path;
603*92a9e4f7SAdrian Hunter 
604*92a9e4f7SAdrian Hunter 	/* This 'return' had no 'call', so push and pop top of stack */
605*92a9e4f7SAdrian Hunter 	cp = call_path__findnew(cpr, parent, from_al->sym, sample->ip,
606*92a9e4f7SAdrian Hunter 				ts->kernel_start);
607*92a9e4f7SAdrian Hunter 	if (!cp)
608*92a9e4f7SAdrian Hunter 		return -ENOMEM;
609*92a9e4f7SAdrian Hunter 
610*92a9e4f7SAdrian Hunter 	err = thread_stack__push_cp(ts, sample->addr, sample->time, ref, cp,
611*92a9e4f7SAdrian Hunter 				    true);
612*92a9e4f7SAdrian Hunter 	if (err)
613*92a9e4f7SAdrian Hunter 		return err;
614*92a9e4f7SAdrian Hunter 
615*92a9e4f7SAdrian Hunter 	return thread_stack__pop_cp(thread, ts, sample->addr, sample->time, ref,
616*92a9e4f7SAdrian Hunter 				    to_al->sym);
617*92a9e4f7SAdrian Hunter }
618*92a9e4f7SAdrian Hunter 
619*92a9e4f7SAdrian Hunter static int thread_stack__trace_begin(struct thread *thread,
620*92a9e4f7SAdrian Hunter 				     struct thread_stack *ts, u64 timestamp,
621*92a9e4f7SAdrian Hunter 				     u64 ref)
622*92a9e4f7SAdrian Hunter {
623*92a9e4f7SAdrian Hunter 	struct thread_stack_entry *tse;
624*92a9e4f7SAdrian Hunter 	int err;
625*92a9e4f7SAdrian Hunter 
626*92a9e4f7SAdrian Hunter 	if (!ts->cnt)
627*92a9e4f7SAdrian Hunter 		return 0;
628*92a9e4f7SAdrian Hunter 
629*92a9e4f7SAdrian Hunter 	/* Pop trace end */
630*92a9e4f7SAdrian Hunter 	tse = &ts->stack[ts->cnt - 1];
631*92a9e4f7SAdrian Hunter 	if (tse->cp->sym == NULL && tse->cp->ip == 0) {
632*92a9e4f7SAdrian Hunter 		err = thread_stack__call_return(thread, ts, --ts->cnt,
633*92a9e4f7SAdrian Hunter 						timestamp, ref, false);
634*92a9e4f7SAdrian Hunter 		if (err)
635*92a9e4f7SAdrian Hunter 			return err;
636*92a9e4f7SAdrian Hunter 	}
637*92a9e4f7SAdrian Hunter 
638*92a9e4f7SAdrian Hunter 	return 0;
639*92a9e4f7SAdrian Hunter }
640*92a9e4f7SAdrian Hunter 
641*92a9e4f7SAdrian Hunter static int thread_stack__trace_end(struct thread_stack *ts,
642*92a9e4f7SAdrian Hunter 				   struct perf_sample *sample, u64 ref)
643*92a9e4f7SAdrian Hunter {
644*92a9e4f7SAdrian Hunter 	struct call_path_root *cpr = ts->crp->cpr;
645*92a9e4f7SAdrian Hunter 	struct call_path *cp;
646*92a9e4f7SAdrian Hunter 	u64 ret_addr;
647*92a9e4f7SAdrian Hunter 
648*92a9e4f7SAdrian Hunter 	/* No point having 'trace end' on the bottom of the stack */
649*92a9e4f7SAdrian Hunter 	if (!ts->cnt || (ts->cnt == 1 && ts->stack[0].ref == ref))
650*92a9e4f7SAdrian Hunter 		return 0;
651*92a9e4f7SAdrian Hunter 
652*92a9e4f7SAdrian Hunter 	cp = call_path__findnew(cpr, ts->stack[ts->cnt - 1].cp, NULL, 0,
653*92a9e4f7SAdrian Hunter 				ts->kernel_start);
654*92a9e4f7SAdrian Hunter 	if (!cp)
655*92a9e4f7SAdrian Hunter 		return -ENOMEM;
656*92a9e4f7SAdrian Hunter 
657*92a9e4f7SAdrian Hunter 	ret_addr = sample->ip + sample->insn_len;
658*92a9e4f7SAdrian Hunter 
659*92a9e4f7SAdrian Hunter 	return thread_stack__push_cp(ts, ret_addr, sample->time, ref, cp,
660*92a9e4f7SAdrian Hunter 				     false);
661*92a9e4f7SAdrian Hunter }
662*92a9e4f7SAdrian Hunter 
663*92a9e4f7SAdrian Hunter int thread_stack__process(struct thread *thread, struct comm *comm,
664*92a9e4f7SAdrian Hunter 			  struct perf_sample *sample,
665*92a9e4f7SAdrian Hunter 			  struct addr_location *from_al,
666*92a9e4f7SAdrian Hunter 			  struct addr_location *to_al, u64 ref,
667*92a9e4f7SAdrian Hunter 			  struct call_return_processor *crp)
668*92a9e4f7SAdrian Hunter {
669*92a9e4f7SAdrian Hunter 	struct thread_stack *ts = thread->ts;
670*92a9e4f7SAdrian Hunter 	int err = 0;
671*92a9e4f7SAdrian Hunter 
672*92a9e4f7SAdrian Hunter 	if (ts) {
673*92a9e4f7SAdrian Hunter 		if (!ts->crp) {
674*92a9e4f7SAdrian Hunter 			/* Supersede thread_stack__event() */
675*92a9e4f7SAdrian Hunter 			thread_stack__free(thread);
676*92a9e4f7SAdrian Hunter 			thread->ts = thread_stack__new(thread, crp);
677*92a9e4f7SAdrian Hunter 			if (!thread->ts)
678*92a9e4f7SAdrian Hunter 				return -ENOMEM;
679*92a9e4f7SAdrian Hunter 			ts = thread->ts;
680*92a9e4f7SAdrian Hunter 			ts->comm = comm;
681*92a9e4f7SAdrian Hunter 		}
682*92a9e4f7SAdrian Hunter 	} else {
683*92a9e4f7SAdrian Hunter 		thread->ts = thread_stack__new(thread, crp);
684*92a9e4f7SAdrian Hunter 		if (!thread->ts)
685*92a9e4f7SAdrian Hunter 			return -ENOMEM;
686*92a9e4f7SAdrian Hunter 		ts = thread->ts;
687*92a9e4f7SAdrian Hunter 		ts->comm = comm;
688*92a9e4f7SAdrian Hunter 	}
689*92a9e4f7SAdrian Hunter 
690*92a9e4f7SAdrian Hunter 	/* Flush stack on exec */
691*92a9e4f7SAdrian Hunter 	if (ts->comm != comm && thread->pid_ == thread->tid) {
692*92a9e4f7SAdrian Hunter 		err = thread_stack__flush(thread, ts);
693*92a9e4f7SAdrian Hunter 		if (err)
694*92a9e4f7SAdrian Hunter 			return err;
695*92a9e4f7SAdrian Hunter 		ts->comm = comm;
696*92a9e4f7SAdrian Hunter 	}
697*92a9e4f7SAdrian Hunter 
698*92a9e4f7SAdrian Hunter 	/* If the stack is empty, put the current symbol on the stack */
699*92a9e4f7SAdrian Hunter 	if (!ts->cnt) {
700*92a9e4f7SAdrian Hunter 		err = thread_stack__bottom(thread, ts, sample, from_al, to_al,
701*92a9e4f7SAdrian Hunter 					   ref);
702*92a9e4f7SAdrian Hunter 		if (err)
703*92a9e4f7SAdrian Hunter 			return err;
704*92a9e4f7SAdrian Hunter 	}
705*92a9e4f7SAdrian Hunter 
706*92a9e4f7SAdrian Hunter 	ts->branch_count += 1;
707*92a9e4f7SAdrian Hunter 	ts->last_time = sample->time;
708*92a9e4f7SAdrian Hunter 
709*92a9e4f7SAdrian Hunter 	if (sample->flags & PERF_IP_FLAG_CALL) {
710*92a9e4f7SAdrian Hunter 		struct call_path_root *cpr = ts->crp->cpr;
711*92a9e4f7SAdrian Hunter 		struct call_path *cp;
712*92a9e4f7SAdrian Hunter 		u64 ret_addr;
713*92a9e4f7SAdrian Hunter 
714*92a9e4f7SAdrian Hunter 		if (!sample->ip || !sample->addr)
715*92a9e4f7SAdrian Hunter 			return 0;
716*92a9e4f7SAdrian Hunter 
717*92a9e4f7SAdrian Hunter 		ret_addr = sample->ip + sample->insn_len;
718*92a9e4f7SAdrian Hunter 		if (ret_addr == sample->addr)
719*92a9e4f7SAdrian Hunter 			return 0; /* Zero-length calls are excluded */
720*92a9e4f7SAdrian Hunter 
721*92a9e4f7SAdrian Hunter 		cp = call_path__findnew(cpr, ts->stack[ts->cnt - 1].cp,
722*92a9e4f7SAdrian Hunter 					to_al->sym, sample->addr,
723*92a9e4f7SAdrian Hunter 					ts->kernel_start);
724*92a9e4f7SAdrian Hunter 		if (!cp)
725*92a9e4f7SAdrian Hunter 			return -ENOMEM;
726*92a9e4f7SAdrian Hunter 		err = thread_stack__push_cp(ts, ret_addr, sample->time, ref,
727*92a9e4f7SAdrian Hunter 					    cp, false);
728*92a9e4f7SAdrian Hunter 	} else if (sample->flags & PERF_IP_FLAG_RETURN) {
729*92a9e4f7SAdrian Hunter 		if (!sample->ip || !sample->addr)
730*92a9e4f7SAdrian Hunter 			return 0;
731*92a9e4f7SAdrian Hunter 
732*92a9e4f7SAdrian Hunter 		err = thread_stack__pop_cp(thread, ts, sample->addr,
733*92a9e4f7SAdrian Hunter 					   sample->time, ref, from_al->sym);
734*92a9e4f7SAdrian Hunter 		if (err) {
735*92a9e4f7SAdrian Hunter 			if (err < 0)
736*92a9e4f7SAdrian Hunter 				return err;
737*92a9e4f7SAdrian Hunter 			err = thread_stack__no_call_return(thread, ts, sample,
738*92a9e4f7SAdrian Hunter 							   from_al, to_al, ref);
739*92a9e4f7SAdrian Hunter 		}
740*92a9e4f7SAdrian Hunter 	} else if (sample->flags & PERF_IP_FLAG_TRACE_BEGIN) {
741*92a9e4f7SAdrian Hunter 		err = thread_stack__trace_begin(thread, ts, sample->time, ref);
742*92a9e4f7SAdrian Hunter 	} else if (sample->flags & PERF_IP_FLAG_TRACE_END) {
743*92a9e4f7SAdrian Hunter 		err = thread_stack__trace_end(ts, sample, ref);
744*92a9e4f7SAdrian Hunter 	}
745*92a9e4f7SAdrian Hunter 
746*92a9e4f7SAdrian Hunter 	return err;
747*92a9e4f7SAdrian Hunter }
748