You've already forked linux-rockchip
mirror of
https://github.com/armbian/linux-rockchip.git
synced 2026-01-06 11:08:10 -08:00
perf kwork: Implement 'report' subcommand
Implements framework of 'perf kwork report', which is used to report
time properties such as run time and frequency:
Test cases:
# perf kwork
Usage: perf kwork [<options>] {record|report}
-D, --dump-raw-trace dump raw trace in ASCII
-f, --force don't complain, do it
-k, --kwork <kwork> list of kwork to profile (irq, softirq, workqueue, etc)
-v, --verbose be more verbose (show symbol address, etc)
# perf kwork report -h
Usage: perf kwork report [<options>]
-C, --cpu <cpu> list of cpus to profile
-i, --input <file> input file name
-n, --name <name> event name to profile
-s, --sort <key[,key2...]>
sort by key(s): runtime, max, count
-S, --with-summary Show summary with statistics
--time <str> Time span for analysis (start,stop)
# perf kwork report
Kwork Name | Cpu | Total Runtime | Count | Max runtime | Max runtime start | Max runtime end |
--------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------------------
# perf kwork report -S
Kwork Name | Cpu | Total Runtime | Count | Max runtime | Max runtime start | Max runtime end |
--------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------------------------
Total count : 0
Total runtime (msec) : 0.000 (0.000% load average)
Total time span (msec) : 0.000
--------------------------------------------------------------------------------------------------------------------------------
# perf kwork report -C 0,100
Requested CPU 100 too large. Consider raising MAX_NR_CPUS
Invalid cpu bitmap
# perf kwork report -s runtime1
Error: Unknown --sort key: `runtime1'
Usage: perf kwork report [<options>]
-C, --cpu <cpu> list of cpus to profile
-i, --input <file> input file name
-n, --name <name> event name to profile
-s, --sort <key[,key2...]>
sort by key(s): runtime, max, count
-S, --with-summary Show summary with statistics
--time <str> Time span for analysis (start,stop)
# perf kwork report -i perf_no_exist.data
failed to open perf_no_exist.data: No such file or directory
# perf kwork report --time 00FFF,
Invalid time span
Since there are no report supported events, the output is empty.
Briefly describe the data structure:
1. "class" indicates event type. For example, irq and softiq correspond
to different types.
2. "cluster" refers to a specific event corresponding to a type. For
example, RCU and TIMER in softirq correspond to different clusters,
which contains three types of events: raise, entry, and exit.
3. "atom" includes time of each sample and sample of the previous phase.
(For example, exit corresponds to entry, which is used for timehist.)
Committer notes:
- Add {} for multiline if blocks.
- report_print_work() should either return that ret variable that
accounts how many bytes were printed or stop accounting and be void.
Do the former for now to avoid this:
builtin-kwork.c:534:6: error: variable 'ret' set but not used [-Werror,-Wunused-but-set-variable]
int ret = 0;
^
1 error generated.
When building with:
⬢[acme@toolbox perf]$ clang --version
clang version 13.0.0 (https://github.com/llvm/llvm-project e8991caea8690ec2d17b0b7e1c29bf0da6609076)
Also:
- if ((dst_type >= 0) && (dst_type < KWORK_TRACE_MAX)) {
+ if (dst_type < KWORK_TRACE_MAX) {
Several versions of clang and at least this gcc:
3 51.40 alpine:3.9 : FAIL gcc version 8.3.0 (Alpine 8.3.0)
builtin-kwork.c:411:16: error: comparison of unsigned enum expression >= 0 is
always true [-Werror,-Wtautological-compare]
if ((dst_type >= 0) && (dst_type < KWORK_TRACE_MAX)) {
As the first entry in a enum is zero.
Signed-off-by: Yang Jihong <yangjihong1@huawei.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Clarke <pc@us.ibm.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: https://lore.kernel.org/r/20220709015033.38326-7-yangjihong1@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
committed by
Arnaldo Carvalho de Melo
parent
e432947ef5
commit
f98919ec4f
@@ -17,8 +17,11 @@ There are several variants of 'perf kwork':
|
||||
'perf kwork record <command>' to record the kernel work
|
||||
of an arbitrary workload.
|
||||
|
||||
'perf kwork report' to report the per kwork runtime.
|
||||
|
||||
Example usage:
|
||||
perf kwork record -- sleep 1
|
||||
perf kwork report
|
||||
|
||||
OPTIONS
|
||||
-------
|
||||
@@ -38,6 +41,36 @@ OPTIONS
|
||||
--verbose::
|
||||
Be more verbose. (show symbol address, etc)
|
||||
|
||||
OPTIONS for 'perf kwork report'
|
||||
----------------------------
|
||||
|
||||
-C::
|
||||
--cpu::
|
||||
Only show events for the given CPU(s) (comma separated list).
|
||||
|
||||
-i::
|
||||
--input::
|
||||
Input file name. (default: perf.data unless stdin is a fifo)
|
||||
|
||||
-n::
|
||||
--name::
|
||||
Only show events for the given name.
|
||||
|
||||
-s::
|
||||
--sort::
|
||||
Sort by key(s): runtime, max, count
|
||||
|
||||
-S::
|
||||
--with-summary::
|
||||
Show summary with statistics
|
||||
|
||||
--time::
|
||||
Only analyze samples within given time window: <start>,<stop>. Times
|
||||
have the format seconds.microseconds. If start is not given (i.e., time
|
||||
string is ',x.y') then analysis starts at the beginning of the file. If
|
||||
stop time is not given (i.e, time string is 'x.y,') then analysis goes
|
||||
to end of file.
|
||||
|
||||
SEE ALSO
|
||||
--------
|
||||
linkperf:perf-record[1]
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -19,6 +19,105 @@ enum kwork_class_type {
|
||||
KWORK_CLASS_MAX,
|
||||
};
|
||||
|
||||
enum kwork_report_type {
|
||||
KWORK_REPORT_RUNTIME,
|
||||
};
|
||||
|
||||
enum kwork_trace_type {
|
||||
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 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;
|
||||
};
|
||||
|
||||
struct kwork_class {
|
||||
struct list_head list;
|
||||
const char *name;
|
||||
@@ -26,19 +125,81 @@ struct kwork_class {
|
||||
|
||||
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 kwork_class *class,
|
||||
struct kwork_work *work,
|
||||
struct evsel *evsel,
|
||||
struct perf_sample *sample,
|
||||
struct machine *machine);
|
||||
|
||||
void (*work_name)(struct kwork_work *work,
|
||||
char *buf, int len);
|
||||
};
|
||||
|
||||
struct perf_kwork;
|
||||
struct trace_kwork_handler {
|
||||
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);
|
||||
};
|
||||
|
||||
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;
|
||||
|
||||
/*
|
||||
* 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];
|
||||
};
|
||||
|
||||
#endif /* PERF_UTIL_KWORK_H */
|
||||
|
||||
Reference in New Issue
Block a user