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