mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	perf_kwork_add_work is declared in builtin-kwork, whereas much kwork code is in util. To avoid needing to stub perf_kwork_add_work in python.c, add a callback to struct perf_kwork and initialize it in builtin-kwork to perf_kwork_add_work - this is the only struct perf_kwork. This removes the need for the stub in python.c. Signed-off-by: Ian Rogers <irogers@google.com> Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> Cc: Andi Kleen <ak@linux.intel.com> Cc: Athira Rajeev <atrajeev@linux.vnet.ibm.com> Cc: Colin Ian King <colin.i.king@gmail.com> Cc: Dapeng Mi <dapeng1.mi@linux.intel.com> Cc: Howard Chu <howardchu95@gmail.com> Cc: Ilya Leoshkevich <iii@linux.ibm.com> Cc: Ingo Molnar <mingo@redhat.com> Cc: James Clark <james.clark@linaro.org> Cc: Jiri Olsa <jolsa@kernel.org> Cc: Josh Poimboeuf <jpoimboe@redhat.com> Cc: Kan Liang <kan.liang@linux.intel.com> Cc: Mark Rutland <mark.rutland@arm.com> Cc: Michael Petlan <mpetlan@redhat.com> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Thomas Richter <tmricht@linux.ibm.com> Cc: Veronika Molnarova <vmolnaro@redhat.com> Cc: Weilin Wang <weilin.wang@intel.com> Link: https://lore.kernel.org/r/20241119011644.971342-18-irogers@google.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
		
			
				
	
	
		
			317 lines
		
	
	
	
		
			8.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			317 lines
		
	
	
	
		
			8.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
#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 */
 |