| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317 |
- #ifndef PERF_UTIL_KWORK_H
- #define PERF_UTIL_KWORK_H
- #include "perf.h"
- #include "util/tool.h"
- #include "util/time-utils.h"
- #include <linux/bitmap.h>
- #include <linux/list.h>
- #include <linux/rbtree.h>
- #include <linux/types.h>
- struct perf_sample;
- struct perf_session;
- enum kwork_class_type {
- KWORK_CLASS_IRQ,
- KWORK_CLASS_SOFTIRQ,
- KWORK_CLASS_WORKQUEUE,
- KWORK_CLASS_SCHED,
- KWORK_CLASS_MAX,
- };
- enum kwork_report_type {
- KWORK_REPORT_RUNTIME,
- KWORK_REPORT_LATENCY,
- KWORK_REPORT_TIMEHIST,
- KWORK_REPORT_TOP,
- };
- enum kwork_trace_type {
- KWORK_TRACE_RAISE,
- KWORK_TRACE_ENTRY,
- KWORK_TRACE_EXIT,
- KWORK_TRACE_MAX,
- };
- /*
- * data structure:
- *
- * +==================+ +============+ +======================+
- * | class | | work | | atom |
- * +==================+ +============+ +======================+
- * +------------+ | +-----+ | | +------+ | | +-------+ +-----+ |
- * | perf_kwork | +-> | irq | --------|+-> | eth0 | --+-> | raise | - | ... | --+ +-----------+
- * +-----+------+ || +-----+ ||| +------+ ||| +-------+ +-----+ | | | |
- * | || ||| ||| | +-> | atom_page |
- * | || ||| ||| +-------+ +-----+ | | |
- * | class_list ||| |+-> | entry | - | ... | ----> | |
- * | || ||| ||| +-------+ +-----+ | | |
- * | || ||| ||| | +-> | |
- * | || ||| ||| +-------+ +-----+ | | | |
- * | || ||| |+-> | exit | - | ... | --+ +-----+-----+
- * | || ||| | | +-------+ +-----+ | |
- * | || ||| | | | |
- * | || ||| +-----+ | | | |
- * | || |+-> | ... | | | | |
- * | || | | +-----+ | | | |
- * | || | | | | | |
- * | || +---------+ | | +-----+ | | +-------+ +-----+ | |
- * | +-> | softirq | -------> | RCU | ---+-> | raise | - | ... | --+ +-----+-----+
- * | || +---------+ | | +-----+ ||| +-------+ +-----+ | | | |
- * | || | | ||| | +-> | atom_page |
- * | || | | ||| +-------+ +-----+ | | |
- * | || | | |+-> | entry | - | ... | ----> | |
- * | || | | ||| +-------+ +-----+ | | |
- * | || | | ||| | +-> | |
- * | || | | ||| +-------+ +-----+ | | | |
- * | || | | |+-> | exit | - | ... | --+ +-----+-----+
- * | || | | | | +-------+ +-----+ | |
- * | || | | | | | |
- * | || +-----------+ | | +-----+ | | | |
- * | +-> | workqueue | -----> | ... | | | | |
- * | | +-----------+ | | +-----+ | | | |
- * | +==================+ +============+ +======================+ |
- * | |
- * +----> atom_page_list ---------------------------------------------------------+
- *
- */
- struct kwork_atom {
- struct list_head list;
- u64 time;
- struct kwork_atom *prev;
- void *page_addr;
- unsigned long bit_inpage;
- };
- #define NR_ATOM_PER_PAGE 128
- struct kwork_atom_page {
- struct list_head list;
- struct kwork_atom atoms[NR_ATOM_PER_PAGE];
- DECLARE_BITMAP(bitmap, NR_ATOM_PER_PAGE);
- };
- struct perf_kwork;
- struct kwork_class;
- struct kwork_work {
- /*
- * class field
- */
- struct rb_node node;
- struct kwork_class *class;
- /*
- * work field
- */
- u64 id;
- int cpu;
- char *name;
- /*
- * atom field
- */
- u64 nr_atoms;
- struct list_head atom_list[KWORK_TRACE_MAX];
- /*
- * runtime report
- */
- u64 max_runtime;
- u64 max_runtime_start;
- u64 max_runtime_end;
- u64 total_runtime;
- /*
- * latency report
- */
- u64 max_latency;
- u64 max_latency_start;
- u64 max_latency_end;
- u64 total_latency;
- /*
- * top report
- */
- u32 cpu_usage;
- u32 tgid;
- bool is_kthread;
- };
- struct kwork_class {
- struct list_head list;
- const char *name;
- enum kwork_class_type type;
- unsigned int nr_tracepoints;
- const struct evsel_str_handler *tp_handlers;
- struct rb_root_cached work_root;
- int (*class_init)(struct kwork_class *class,
- struct perf_session *session);
- void (*work_init)(struct perf_kwork *kwork,
- struct kwork_class *class,
- struct kwork_work *work,
- enum kwork_trace_type src_type,
- struct evsel *evsel,
- struct perf_sample *sample,
- struct machine *machine);
- void (*work_name)(struct kwork_work *work,
- char *buf, int len);
- };
- struct trace_kwork_handler {
- int (*raise_event)(struct perf_kwork *kwork,
- struct kwork_class *class, struct evsel *evsel,
- struct perf_sample *sample, struct machine *machine);
- int (*entry_event)(struct perf_kwork *kwork,
- struct kwork_class *class, struct evsel *evsel,
- struct perf_sample *sample, struct machine *machine);
- int (*exit_event)(struct perf_kwork *kwork,
- struct kwork_class *class, struct evsel *evsel,
- struct perf_sample *sample, struct machine *machine);
- int (*sched_switch_event)(struct perf_kwork *kwork,
- struct kwork_class *class, struct evsel *evsel,
- struct perf_sample *sample, struct machine *machine);
- };
- struct __top_cpus_runtime {
- u64 load;
- u64 idle;
- u64 irq;
- u64 softirq;
- u64 total;
- };
- struct kwork_top_stat {
- DECLARE_BITMAP(all_cpus_bitmap, MAX_NR_CPUS);
- struct __top_cpus_runtime *cpus_runtime;
- };
- struct perf_kwork {
- /*
- * metadata
- */
- struct perf_tool tool;
- struct list_head class_list;
- struct list_head atom_page_list;
- struct list_head sort_list, cmp_id;
- struct rb_root_cached sorted_work_root;
- const struct trace_kwork_handler *tp_handler;
- /*
- * profile filters
- */
- const char *profile_name;
- const char *cpu_list;
- DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS);
- const char *time_str;
- struct perf_time_interval ptime;
- /*
- * options for command
- */
- bool force;
- const char *event_list_str;
- enum kwork_report_type report;
- /*
- * options for subcommand
- */
- bool summary;
- const char *sort_order;
- bool show_callchain;
- unsigned int max_stack;
- bool use_bpf;
- /*
- * statistics
- */
- u64 timestart;
- u64 timeend;
- unsigned long nr_events;
- unsigned long nr_lost_chunks;
- unsigned long nr_lost_events;
- u64 all_runtime;
- u64 all_count;
- u64 nr_skipped_events[KWORK_TRACE_MAX + 1];
- /*
- * perf kwork top data
- */
- struct kwork_top_stat top_stat;
- /* Add work callback. */
- struct kwork_work *(*add_work)(struct perf_kwork *kwork,
- struct kwork_class *class,
- struct kwork_work *key);
- };
- #ifdef HAVE_BPF_SKEL
- int perf_kwork__trace_prepare_bpf(struct perf_kwork *kwork);
- int perf_kwork__report_read_bpf(struct perf_kwork *kwork);
- void perf_kwork__report_cleanup_bpf(void);
- void perf_kwork__trace_start(void);
- void perf_kwork__trace_finish(void);
- int perf_kwork__top_prepare_bpf(struct perf_kwork *kwork);
- int perf_kwork__top_read_bpf(struct perf_kwork *kwork);
- void perf_kwork__top_cleanup_bpf(void);
- void perf_kwork__top_start(void);
- void perf_kwork__top_finish(void);
- #else /* !HAVE_BPF_SKEL */
- static inline int
- perf_kwork__trace_prepare_bpf(struct perf_kwork *kwork __maybe_unused)
- {
- return -1;
- }
- static inline int
- perf_kwork__report_read_bpf(struct perf_kwork *kwork __maybe_unused)
- {
- return -1;
- }
- static inline void perf_kwork__report_cleanup_bpf(void) {}
- static inline void perf_kwork__trace_start(void) {}
- static inline void perf_kwork__trace_finish(void) {}
- static inline int
- perf_kwork__top_prepare_bpf(struct perf_kwork *kwork __maybe_unused)
- {
- return -1;
- }
- static inline int
- perf_kwork__top_read_bpf(struct perf_kwork *kwork __maybe_unused)
- {
- return -1;
- }
- static inline void perf_kwork__top_cleanup_bpf(void) {}
- static inline void perf_kwork__top_start(void) {}
- static inline void perf_kwork__top_finish(void) {}
- #endif /* HAVE_BPF_SKEL */
- #endif /* PERF_UTIL_KWORK_H */
|