xref: /openbmc/linux/tools/perf/util/kwork.h (revision 7ae9fb1b7ecbb5d85d07857943f677fd1a559b18)
10f70d8e9SYang Jihong #ifndef PERF_UTIL_KWORK_H
20f70d8e9SYang Jihong #define PERF_UTIL_KWORK_H
30f70d8e9SYang Jihong 
40f70d8e9SYang Jihong #include "util/tool.h"
50f70d8e9SYang Jihong #include "util/time-utils.h"
60f70d8e9SYang Jihong 
70f70d8e9SYang Jihong #include <linux/bitmap.h>
8*628d6999SArnaldo Carvalho de Melo #include <linux/list.h>
9*628d6999SArnaldo Carvalho de Melo #include <linux/rbtree.h>
10*628d6999SArnaldo Carvalho de Melo #include <linux/types.h>
11*628d6999SArnaldo Carvalho de Melo 
12*628d6999SArnaldo Carvalho de Melo struct perf_sample;
13*628d6999SArnaldo Carvalho de Melo struct perf_session;
140f70d8e9SYang Jihong 
150f70d8e9SYang Jihong enum kwork_class_type {
164f8ae962SYang Jihong 	KWORK_CLASS_IRQ,
17e6439321SYang Jihong 	KWORK_CLASS_SOFTIRQ,
1897179d9dSYang Jihong 	KWORK_CLASS_WORKQUEUE,
190f70d8e9SYang Jihong 	KWORK_CLASS_MAX,
200f70d8e9SYang Jihong };
210f70d8e9SYang Jihong 
22f98919ecSYang Jihong enum kwork_report_type {
23f98919ecSYang Jihong 	KWORK_REPORT_RUNTIME,
24ad3d9f7aSYang Jihong 	KWORK_REPORT_LATENCY,
25bcc8b3e8SYang Jihong 	KWORK_REPORT_TIMEHIST,
26f98919ecSYang Jihong };
27f98919ecSYang Jihong 
28f98919ecSYang Jihong enum kwork_trace_type {
29ad3d9f7aSYang Jihong 	KWORK_TRACE_RAISE,
30f98919ecSYang Jihong 	KWORK_TRACE_ENTRY,
31f98919ecSYang Jihong 	KWORK_TRACE_EXIT,
32f98919ecSYang Jihong 	KWORK_TRACE_MAX,
33f98919ecSYang Jihong };
34f98919ecSYang Jihong 
35f98919ecSYang Jihong /*
36f98919ecSYang Jihong  * data structure:
37f98919ecSYang Jihong  *
38f98919ecSYang Jihong  *                 +==================+ +============+ +======================+
39f98919ecSYang Jihong  *                 |      class       | |    work    | |         atom         |
40f98919ecSYang Jihong  *                 +==================+ +============+ +======================+
41f98919ecSYang Jihong  * +------------+  |  +-----+         | |  +------+  | |  +-------+   +-----+ |
42f98919ecSYang Jihong  * | perf_kwork | +-> | irq | --------|+-> | eth0 | --+-> | raise | - | ... | --+   +-----------+
43f98919ecSYang Jihong  * +-----+------+ ||  +-----+         |||  +------+  |||  +-------+   +-----+ | |   |           |
44f98919ecSYang Jihong  *       |        ||                  |||            |||                      | +-> | atom_page |
45f98919ecSYang Jihong  *       |        ||                  |||            |||  +-------+   +-----+ |     |           |
46f98919ecSYang Jihong  *       |  class_list                |||            |+-> | entry | - | ... | ----> |           |
47f98919ecSYang Jihong  *       |        ||                  |||            |||  +-------+   +-----+ |     |           |
48f98919ecSYang Jihong  *       |        ||                  |||            |||                      | +-> |           |
49f98919ecSYang Jihong  *       |        ||                  |||            |||  +-------+   +-----+ | |   |           |
50f98919ecSYang Jihong  *       |        ||                  |||            |+-> | exit  | - | ... | --+   +-----+-----+
51f98919ecSYang Jihong  *       |        ||                  |||            | |  +-------+   +-----+ |           |
52f98919ecSYang Jihong  *       |        ||                  |||            | |                      |           |
53f98919ecSYang Jihong  *       |        ||                  |||  +-----+   | |                      |           |
54f98919ecSYang Jihong  *       |        ||                  |+-> | ... |   | |                      |           |
55f98919ecSYang Jihong  *       |        ||                  | |  +-----+   | |                      |           |
56f98919ecSYang Jihong  *       |        ||                  | |            | |                      |           |
57f98919ecSYang Jihong  *       |        ||  +---------+     | |  +-----+   | |  +-------+   +-----+ |           |
58f98919ecSYang Jihong  *       |        +-> | softirq | -------> | RCU | ---+-> | raise | - | ... | --+   +-----+-----+
59f98919ecSYang Jihong  *       |        ||  +---------+     | |  +-----+   |||  +-------+   +-----+ | |   |           |
60f98919ecSYang Jihong  *       |        ||                  | |            |||                      | +-> | atom_page |
61f98919ecSYang Jihong  *       |        ||                  | |            |||  +-------+   +-----+ |     |           |
62f98919ecSYang Jihong  *       |        ||                  | |            |+-> | entry | - | ... | ----> |           |
63f98919ecSYang Jihong  *       |        ||                  | |            |||  +-------+   +-----+ |     |           |
64f98919ecSYang Jihong  *       |        ||                  | |            |||                      | +-> |           |
65f98919ecSYang Jihong  *       |        ||                  | |            |||  +-------+   +-----+ | |   |           |
66f98919ecSYang Jihong  *       |        ||                  | |            |+-> | exit  | - | ... | --+   +-----+-----+
67f98919ecSYang Jihong  *       |        ||                  | |            | |  +-------+   +-----+ |           |
68f98919ecSYang Jihong  *       |        ||                  | |            | |                      |           |
69f98919ecSYang Jihong  *       |        ||  +-----------+   | |  +-----+   | |                      |           |
70f98919ecSYang Jihong  *       |        +-> | workqueue | -----> | ... |   | |                      |           |
71f98919ecSYang Jihong  *       |         |  +-----------+   | |  +-----+   | |                      |           |
72f98919ecSYang Jihong  *       |         +==================+ +============+ +======================+           |
73f98919ecSYang Jihong  *       |                                                                                |
74f98919ecSYang Jihong  *       +---->  atom_page_list  ---------------------------------------------------------+
75f98919ecSYang Jihong  *
76f98919ecSYang Jihong  */
77f98919ecSYang Jihong 
78f98919ecSYang Jihong struct kwork_atom {
79f98919ecSYang Jihong 	struct list_head list;
80f98919ecSYang Jihong 	u64 time;
81f98919ecSYang Jihong 	struct kwork_atom *prev;
82f98919ecSYang Jihong 
83f98919ecSYang Jihong 	void *page_addr;
84f98919ecSYang Jihong 	unsigned long bit_inpage;
85f98919ecSYang Jihong };
86f98919ecSYang Jihong 
87f98919ecSYang Jihong #define NR_ATOM_PER_PAGE 128
88f98919ecSYang Jihong struct kwork_atom_page {
89f98919ecSYang Jihong 	struct list_head list;
90f98919ecSYang Jihong 	struct kwork_atom atoms[NR_ATOM_PER_PAGE];
91f98919ecSYang Jihong 	DECLARE_BITMAP(bitmap, NR_ATOM_PER_PAGE);
92f98919ecSYang Jihong };
93f98919ecSYang Jihong 
94f98919ecSYang Jihong struct kwork_class;
95f98919ecSYang Jihong struct kwork_work {
96f98919ecSYang Jihong 	/*
97f98919ecSYang Jihong 	 * class field
98f98919ecSYang Jihong 	 */
99f98919ecSYang Jihong 	struct rb_node node;
100f98919ecSYang Jihong 	struct kwork_class *class;
101f98919ecSYang Jihong 
102f98919ecSYang Jihong 	/*
103f98919ecSYang Jihong 	 * work field
104f98919ecSYang Jihong 	 */
105f98919ecSYang Jihong 	u64 id;
106f98919ecSYang Jihong 	int cpu;
107f98919ecSYang Jihong 	char *name;
108f98919ecSYang Jihong 
109f98919ecSYang Jihong 	/*
110f98919ecSYang Jihong 	 * atom field
111f98919ecSYang Jihong 	 */
112f98919ecSYang Jihong 	u64 nr_atoms;
113f98919ecSYang Jihong 	struct list_head atom_list[KWORK_TRACE_MAX];
114f98919ecSYang Jihong 
115f98919ecSYang Jihong 	/*
116f98919ecSYang Jihong 	 * runtime report
117f98919ecSYang Jihong 	 */
118f98919ecSYang Jihong 	u64 max_runtime;
119f98919ecSYang Jihong 	u64 max_runtime_start;
120f98919ecSYang Jihong 	u64 max_runtime_end;
121f98919ecSYang Jihong 	u64 total_runtime;
122ad3d9f7aSYang Jihong 
123ad3d9f7aSYang Jihong 	/*
124ad3d9f7aSYang Jihong 	 * latency report
125ad3d9f7aSYang Jihong 	 */
126ad3d9f7aSYang Jihong 	u64 max_latency;
127ad3d9f7aSYang Jihong 	u64 max_latency_start;
128ad3d9f7aSYang Jihong 	u64 max_latency_end;
129ad3d9f7aSYang Jihong 	u64 total_latency;
130f98919ecSYang Jihong };
131f98919ecSYang Jihong 
1320f70d8e9SYang Jihong struct kwork_class {
1330f70d8e9SYang Jihong 	struct list_head list;
1340f70d8e9SYang Jihong 	const char *name;
1350f70d8e9SYang Jihong 	enum kwork_class_type type;
1360f70d8e9SYang Jihong 
1370f70d8e9SYang Jihong 	unsigned int nr_tracepoints;
1380f70d8e9SYang Jihong 	const struct evsel_str_handler *tp_handlers;
139f98919ecSYang Jihong 
140f98919ecSYang Jihong 	struct rb_root_cached work_root;
141f98919ecSYang Jihong 
142f98919ecSYang Jihong 	int (*class_init)(struct kwork_class *class,
143f98919ecSYang Jihong 			  struct perf_session *session);
144f98919ecSYang Jihong 
145f98919ecSYang Jihong 	void (*work_init)(struct kwork_class *class,
146f98919ecSYang Jihong 			  struct kwork_work *work,
147f98919ecSYang Jihong 			  struct evsel *evsel,
148f98919ecSYang Jihong 			  struct perf_sample *sample,
149f98919ecSYang Jihong 			  struct machine *machine);
150f98919ecSYang Jihong 
151f98919ecSYang Jihong 	void (*work_name)(struct kwork_work *work,
152f98919ecSYang Jihong 			  char *buf, int len);
153f98919ecSYang Jihong };
154f98919ecSYang Jihong 
155f98919ecSYang Jihong struct perf_kwork;
156f98919ecSYang Jihong struct trace_kwork_handler {
157ad3d9f7aSYang Jihong 	int (*raise_event)(struct perf_kwork *kwork,
158ad3d9f7aSYang Jihong 			   struct kwork_class *class, struct evsel *evsel,
159ad3d9f7aSYang Jihong 			   struct perf_sample *sample, struct machine *machine);
160ad3d9f7aSYang Jihong 
161f98919ecSYang Jihong 	int (*entry_event)(struct perf_kwork *kwork,
162f98919ecSYang Jihong 			   struct kwork_class *class, struct evsel *evsel,
163f98919ecSYang Jihong 			   struct perf_sample *sample, struct machine *machine);
164f98919ecSYang Jihong 
165f98919ecSYang Jihong 	int (*exit_event)(struct perf_kwork *kwork,
166f98919ecSYang Jihong 			  struct kwork_class *class, struct evsel *evsel,
167f98919ecSYang Jihong 			  struct perf_sample *sample, struct machine *machine);
1680f70d8e9SYang Jihong };
1690f70d8e9SYang Jihong 
1700f70d8e9SYang Jihong struct perf_kwork {
1710f70d8e9SYang Jihong 	/*
1720f70d8e9SYang Jihong 	 * metadata
1730f70d8e9SYang Jihong 	 */
174f98919ecSYang Jihong 	struct perf_tool tool;
1750f70d8e9SYang Jihong 	struct list_head class_list;
176f98919ecSYang Jihong 	struct list_head atom_page_list;
177f98919ecSYang Jihong 	struct list_head sort_list, cmp_id;
178f98919ecSYang Jihong 	struct rb_root_cached sorted_work_root;
179f98919ecSYang Jihong 	const struct trace_kwork_handler *tp_handler;
180f98919ecSYang Jihong 
181f98919ecSYang Jihong 	/*
182f98919ecSYang Jihong 	 * profile filters
183f98919ecSYang Jihong 	 */
184f98919ecSYang Jihong 	const char *profile_name;
185f98919ecSYang Jihong 
186f98919ecSYang Jihong 	const char *cpu_list;
187f98919ecSYang Jihong 	DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS);
188f98919ecSYang Jihong 
189f98919ecSYang Jihong 	const char *time_str;
190f98919ecSYang Jihong 	struct perf_time_interval ptime;
1910f70d8e9SYang Jihong 
1920f70d8e9SYang Jihong 	/*
1930f70d8e9SYang Jihong 	 * options for command
1940f70d8e9SYang Jihong 	 */
1950f70d8e9SYang Jihong 	bool force;
1960f70d8e9SYang Jihong 	const char *event_list_str;
197f98919ecSYang Jihong 	enum kwork_report_type report;
198f98919ecSYang Jihong 
199f98919ecSYang Jihong 	/*
200f98919ecSYang Jihong 	 * options for subcommand
201f98919ecSYang Jihong 	 */
202f98919ecSYang Jihong 	bool summary;
203f98919ecSYang Jihong 	const char *sort_order;
204bcc8b3e8SYang Jihong 	bool show_callchain;
205bcc8b3e8SYang Jihong 	unsigned int max_stack;
206daf07d22SYang Jihong 	bool use_bpf;
207f98919ecSYang Jihong 
208f98919ecSYang Jihong 	/*
209f98919ecSYang Jihong 	 * statistics
210f98919ecSYang Jihong 	 */
211f98919ecSYang Jihong 	u64 timestart;
212f98919ecSYang Jihong 	u64 timeend;
213f98919ecSYang Jihong 
214f98919ecSYang Jihong 	unsigned long nr_events;
215f98919ecSYang Jihong 	unsigned long nr_lost_chunks;
216f98919ecSYang Jihong 	unsigned long nr_lost_events;
217f98919ecSYang Jihong 
218f98919ecSYang Jihong 	u64 all_runtime;
219f98919ecSYang Jihong 	u64 all_count;
220f98919ecSYang Jihong 	u64 nr_skipped_events[KWORK_TRACE_MAX + 1];
2210f70d8e9SYang Jihong };
2220f70d8e9SYang Jihong 
223daf07d22SYang Jihong struct kwork_work *perf_kwork_add_work(struct perf_kwork *kwork,
224daf07d22SYang Jihong 				       struct kwork_class *class,
225daf07d22SYang Jihong 				       struct kwork_work *key);
226daf07d22SYang Jihong 
227daf07d22SYang Jihong #ifdef HAVE_BPF_SKEL
228daf07d22SYang Jihong 
229daf07d22SYang Jihong int perf_kwork__trace_prepare_bpf(struct perf_kwork *kwork);
230daf07d22SYang Jihong int perf_kwork__report_read_bpf(struct perf_kwork *kwork);
231daf07d22SYang Jihong void perf_kwork__report_cleanup_bpf(void);
232daf07d22SYang Jihong 
233daf07d22SYang Jihong void perf_kwork__trace_start(void);
234daf07d22SYang Jihong void perf_kwork__trace_finish(void);
235daf07d22SYang Jihong 
236daf07d22SYang Jihong #else  /* !HAVE_BPF_SKEL */
237daf07d22SYang Jihong 
238daf07d22SYang Jihong static inline int
perf_kwork__trace_prepare_bpf(struct perf_kwork * kwork __maybe_unused)239daf07d22SYang Jihong perf_kwork__trace_prepare_bpf(struct perf_kwork *kwork __maybe_unused)
240daf07d22SYang Jihong {
241daf07d22SYang Jihong 	return -1;
242daf07d22SYang Jihong }
243daf07d22SYang Jihong 
244daf07d22SYang Jihong static inline int
perf_kwork__report_read_bpf(struct perf_kwork * kwork __maybe_unused)245daf07d22SYang Jihong perf_kwork__report_read_bpf(struct perf_kwork *kwork __maybe_unused)
246daf07d22SYang Jihong {
247daf07d22SYang Jihong 	return -1;
248daf07d22SYang Jihong }
249daf07d22SYang Jihong 
perf_kwork__report_cleanup_bpf(void)250daf07d22SYang Jihong static inline void perf_kwork__report_cleanup_bpf(void) {}
251daf07d22SYang Jihong 
perf_kwork__trace_start(void)252daf07d22SYang Jihong static inline void perf_kwork__trace_start(void) {}
perf_kwork__trace_finish(void)253daf07d22SYang Jihong static inline void perf_kwork__trace_finish(void) {}
254daf07d22SYang Jihong 
255daf07d22SYang Jihong #endif  /* HAVE_BPF_SKEL */
256daf07d22SYang Jihong 
2570f70d8e9SYang Jihong #endif  /* PERF_UTIL_KWORK_H */
258