xref: /OK3568_Linux_fs/kernel/tools/perf/util/thread-stack.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-only */
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * thread-stack.h: Synthesize a thread's stack using call / return events
4*4882a593Smuzhiyun  * Copyright (c) 2014, Intel Corporation.
5*4882a593Smuzhiyun  */
6*4882a593Smuzhiyun 
7*4882a593Smuzhiyun #ifndef __PERF_THREAD_STACK_H
8*4882a593Smuzhiyun #define __PERF_THREAD_STACK_H
9*4882a593Smuzhiyun 
10*4882a593Smuzhiyun #include <sys/types.h>
11*4882a593Smuzhiyun 
12*4882a593Smuzhiyun #include <linux/types.h>
13*4882a593Smuzhiyun 
14*4882a593Smuzhiyun struct thread;
15*4882a593Smuzhiyun struct comm;
16*4882a593Smuzhiyun struct ip_callchain;
17*4882a593Smuzhiyun struct symbol;
18*4882a593Smuzhiyun struct dso;
19*4882a593Smuzhiyun struct comm;
20*4882a593Smuzhiyun struct perf_sample;
21*4882a593Smuzhiyun struct addr_location;
22*4882a593Smuzhiyun struct call_path;
23*4882a593Smuzhiyun 
24*4882a593Smuzhiyun /*
25*4882a593Smuzhiyun  * Call/Return flags.
26*4882a593Smuzhiyun  *
27*4882a593Smuzhiyun  * CALL_RETURN_NO_CALL: 'return' but no matching 'call'
28*4882a593Smuzhiyun  * CALL_RETURN_NO_RETURN: 'call' but no matching 'return'
29*4882a593Smuzhiyun  * CALL_RETURN_NON_CALL: a branch but not a 'call' to the start of a different
30*4882a593Smuzhiyun  *                       symbol
31*4882a593Smuzhiyun  */
32*4882a593Smuzhiyun enum {
33*4882a593Smuzhiyun 	CALL_RETURN_NO_CALL	= 1 << 0,
34*4882a593Smuzhiyun 	CALL_RETURN_NO_RETURN	= 1 << 1,
35*4882a593Smuzhiyun 	CALL_RETURN_NON_CALL	= 1 << 2,
36*4882a593Smuzhiyun };
37*4882a593Smuzhiyun 
38*4882a593Smuzhiyun /**
39*4882a593Smuzhiyun  * struct call_return - paired call/return information.
40*4882a593Smuzhiyun  * @thread: thread in which call/return occurred
41*4882a593Smuzhiyun  * @comm: comm in which call/return occurred
42*4882a593Smuzhiyun  * @cp: call path
43*4882a593Smuzhiyun  * @call_time: timestamp of call (if known)
44*4882a593Smuzhiyun  * @return_time: timestamp of return (if known)
45*4882a593Smuzhiyun  * @branch_count: number of branches seen between call and return
46*4882a593Smuzhiyun  * @insn_count: approx. number of instructions between call and return
47*4882a593Smuzhiyun  * @cyc_count: approx. number of cycles between call and return
48*4882a593Smuzhiyun  * @call_ref: external reference to 'call' sample (e.g. db_id)
49*4882a593Smuzhiyun  * @return_ref:  external reference to 'return' sample (e.g. db_id)
50*4882a593Smuzhiyun  * @db_id: id used for db-export
51*4882a593Smuzhiyun  * @parent_db_id: id of parent call used for db-export
52*4882a593Smuzhiyun  * @flags: Call/Return flags
53*4882a593Smuzhiyun  */
54*4882a593Smuzhiyun struct call_return {
55*4882a593Smuzhiyun 	struct thread *thread;
56*4882a593Smuzhiyun 	struct comm *comm;
57*4882a593Smuzhiyun 	struct call_path *cp;
58*4882a593Smuzhiyun 	u64 call_time;
59*4882a593Smuzhiyun 	u64 return_time;
60*4882a593Smuzhiyun 	u64 branch_count;
61*4882a593Smuzhiyun 	u64 insn_count;
62*4882a593Smuzhiyun 	u64 cyc_count;
63*4882a593Smuzhiyun 	u64 call_ref;
64*4882a593Smuzhiyun 	u64 return_ref;
65*4882a593Smuzhiyun 	u64 db_id;
66*4882a593Smuzhiyun 	u64 parent_db_id;
67*4882a593Smuzhiyun 	u32 flags;
68*4882a593Smuzhiyun };
69*4882a593Smuzhiyun 
70*4882a593Smuzhiyun /**
71*4882a593Smuzhiyun  * struct call_return_processor - provides a call-back to consume call-return
72*4882a593Smuzhiyun  *                                information.
73*4882a593Smuzhiyun  * @cpr: call path root
74*4882a593Smuzhiyun  * @process: call-back that accepts call/return information
75*4882a593Smuzhiyun  * @data: anonymous data for call-back
76*4882a593Smuzhiyun  */
77*4882a593Smuzhiyun struct call_return_processor {
78*4882a593Smuzhiyun 	struct call_path_root *cpr;
79*4882a593Smuzhiyun 	int (*process)(struct call_return *cr, u64 *parent_db_id, void *data);
80*4882a593Smuzhiyun 	void *data;
81*4882a593Smuzhiyun };
82*4882a593Smuzhiyun 
83*4882a593Smuzhiyun int thread_stack__event(struct thread *thread, int cpu, u32 flags, u64 from_ip,
84*4882a593Smuzhiyun 			u64 to_ip, u16 insn_len, u64 trace_nr, bool callstack,
85*4882a593Smuzhiyun 			unsigned int br_stack_sz, bool mispred_all);
86*4882a593Smuzhiyun void thread_stack__set_trace_nr(struct thread *thread, int cpu, u64 trace_nr);
87*4882a593Smuzhiyun void thread_stack__sample(struct thread *thread, int cpu, struct ip_callchain *chain,
88*4882a593Smuzhiyun 			  size_t sz, u64 ip, u64 kernel_start);
89*4882a593Smuzhiyun void thread_stack__sample_late(struct thread *thread, int cpu,
90*4882a593Smuzhiyun 			       struct ip_callchain *chain, size_t sz, u64 ip,
91*4882a593Smuzhiyun 			       u64 kernel_start);
92*4882a593Smuzhiyun void thread_stack__br_sample(struct thread *thread, int cpu,
93*4882a593Smuzhiyun 			     struct branch_stack *dst, unsigned int sz);
94*4882a593Smuzhiyun void thread_stack__br_sample_late(struct thread *thread, int cpu,
95*4882a593Smuzhiyun 				  struct branch_stack *dst, unsigned int sz,
96*4882a593Smuzhiyun 				  u64 sample_ip, u64 kernel_start);
97*4882a593Smuzhiyun int thread_stack__flush(struct thread *thread);
98*4882a593Smuzhiyun void thread_stack__free(struct thread *thread);
99*4882a593Smuzhiyun size_t thread_stack__depth(struct thread *thread, int cpu);
100*4882a593Smuzhiyun 
101*4882a593Smuzhiyun struct call_return_processor *
102*4882a593Smuzhiyun call_return_processor__new(int (*process)(struct call_return *cr, u64 *parent_db_id, void *data),
103*4882a593Smuzhiyun 			   void *data);
104*4882a593Smuzhiyun void call_return_processor__free(struct call_return_processor *crp);
105*4882a593Smuzhiyun int thread_stack__process(struct thread *thread, struct comm *comm,
106*4882a593Smuzhiyun 			  struct perf_sample *sample,
107*4882a593Smuzhiyun 			  struct addr_location *from_al,
108*4882a593Smuzhiyun 			  struct addr_location *to_al, u64 ref,
109*4882a593Smuzhiyun 			  struct call_return_processor *crp);
110*4882a593Smuzhiyun 
111*4882a593Smuzhiyun #endif
112