aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf
diff options
context:
space:
mode:
authorSteven Rostedt <srostedt@redhat.com>2009-10-14 15:43:42 -0400
committerIngo Molnar <mingo@elte.hu>2009-10-15 04:42:39 -0400
commitcda48461c7fb8431a99b7960480f5f42cc1a5324 (patch)
tree89afa42fb7136ac1086d1736529f59cfe4ac1ce3 /tools/perf
parent0d1da915c76838c9ee7af7cdefbcb2bae9424161 (diff)
perf tools: Add latency format to trace output
Add the irqs disabled, preemption count, need resched, and other info that is shown in the latency format of ftrace. # perf trace -l perf-16457 2..s2. 53636.260344: kmem_cache_free: call_site=ffffffff811198f perf-16457 2..s2. 53636.264330: kmem_cache_free: call_site=ffffffff811198f perf-16457 2d.s4. 53636.300006: kmem_cache_free: call_site=ffffffff810d889 Signed-off-by: Steven Rostedt <srostedt@redhat.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Arnaldo Carvalho de Melo <acme@redhat.com> LKML-Reference: <20091014194400.076588953@goodmis.org> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'tools/perf')
-rw-r--r--tools/perf/builtin-trace.c2
-rw-r--r--tools/perf/util/trace-event-parse.c120
-rw-r--r--tools/perf/util/trace-event.h11
3 files changed, 114 insertions, 19 deletions
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index ccf867dbab5c..ce8459ac2845 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -144,6 +144,8 @@ static const struct option options[] = {
144 "dump raw trace in ASCII"), 144 "dump raw trace in ASCII"),
145 OPT_BOOLEAN('v', "verbose", &verbose, 145 OPT_BOOLEAN('v', "verbose", &verbose,
146 "be more verbose (show symbol address, etc)"), 146 "be more verbose (show symbol address, etc)"),
147 OPT_BOOLEAN('l', "latency", &latency_format,
148 "show latency attributes (irqs/preemption disabled, etc)"),
147 OPT_END() 149 OPT_END()
148}; 150};
149 151
diff --git a/tools/perf/util/trace-event-parse.c b/tools/perf/util/trace-event-parse.c
index c174765d4056..fde1a434d630 100644
--- a/tools/perf/util/trace-event-parse.c
+++ b/tools/perf/util/trace-event-parse.c
@@ -40,6 +40,8 @@ int header_page_size_size;
40int header_page_data_offset; 40int header_page_data_offset;
41int header_page_data_size; 41int header_page_data_size;
42 42
43int latency_format;
44
43static char *input_buf; 45static char *input_buf;
44static unsigned long long input_buf_ptr; 46static unsigned long long input_buf_ptr;
45static unsigned long long input_buf_siz; 47static unsigned long long input_buf_siz;
@@ -1928,37 +1930,67 @@ static int get_common_info(const char *type, int *offset, int *size)
1928 return 0; 1930 return 0;
1929} 1931}
1930 1932
1931int trace_parse_common_type(void *data) 1933static int __parse_common(void *data, int *size, int *offset,
1934 char *name)
1932{ 1935{
1933 static int type_offset;
1934 static int type_size;
1935 int ret; 1936 int ret;
1936 1937
1937 if (!type_size) { 1938 if (!*size) {
1938 ret = get_common_info("common_type", 1939 ret = get_common_info(name, offset, size);
1939 &type_offset,
1940 &type_size);
1941 if (ret < 0) 1940 if (ret < 0)
1942 return ret; 1941 return ret;
1943 } 1942 }
1944 return read_size(data + type_offset, type_size); 1943 return read_size(data + *offset, *size);
1944}
1945
1946int trace_parse_common_type(void *data)
1947{
1948 static int type_offset;
1949 static int type_size;
1950
1951 return __parse_common(data, &type_size, &type_offset,
1952 (char *)"common_type");
1945} 1953}
1946 1954
1947static int parse_common_pid(void *data) 1955static int parse_common_pid(void *data)
1948{ 1956{
1949 static int pid_offset; 1957 static int pid_offset;
1950 static int pid_size; 1958 static int pid_size;
1959
1960 return __parse_common(data, &pid_size, &pid_offset,
1961 (char *)"common_pid");
1962}
1963
1964static int parse_common_pc(void *data)
1965{
1966 static int pc_offset;
1967 static int pc_size;
1968
1969 return __parse_common(data, &pc_size, &pc_offset,
1970 (char *)"common_preempt_count");
1971}
1972
1973static int parse_common_flags(void *data)
1974{
1975 static int flags_offset;
1976 static int flags_size;
1977
1978 return __parse_common(data, &flags_size, &flags_offset,
1979 (char *)"common_flags");
1980}
1981
1982static int parse_common_lock_depth(void *data)
1983{
1984 static int ld_offset;
1985 static int ld_size;
1951 int ret; 1986 int ret;
1952 1987
1953 if (!pid_size) { 1988 ret = __parse_common(data, &ld_size, &ld_offset,
1954 ret = get_common_info("common_pid", 1989 (char *)"common_lock_depth");
1955 &pid_offset, 1990 if (ret < 0)
1956 &pid_size); 1991 return -1;
1957 if (ret < 0)
1958 return ret;
1959 }
1960 1992
1961 return read_size(data + pid_offset, pid_size); 1993 return ret;
1962} 1994}
1963 1995
1964struct event *trace_find_event(int id) 1996struct event *trace_find_event(int id)
@@ -2525,6 +2557,41 @@ static inline int log10_cpu(int nb)
2525 return 1; 2557 return 1;
2526} 2558}
2527 2559
2560static void print_lat_fmt(void *data, int size __unused)
2561{
2562 unsigned int lat_flags;
2563 unsigned int pc;
2564 int lock_depth;
2565 int hardirq;
2566 int softirq;
2567
2568 lat_flags = parse_common_flags(data);
2569 pc = parse_common_pc(data);
2570 lock_depth = parse_common_lock_depth(data);
2571
2572 hardirq = lat_flags & TRACE_FLAG_HARDIRQ;
2573 softirq = lat_flags & TRACE_FLAG_SOFTIRQ;
2574
2575 printf("%c%c%c",
2576 (lat_flags & TRACE_FLAG_IRQS_OFF) ? 'd' :
2577 (lat_flags & TRACE_FLAG_IRQS_NOSUPPORT) ?
2578 'X' : '.',
2579 (lat_flags & TRACE_FLAG_NEED_RESCHED) ?
2580 'N' : '.',
2581 (hardirq && softirq) ? 'H' :
2582 hardirq ? 'h' : softirq ? 's' : '.');
2583
2584 if (pc)
2585 printf("%x", pc);
2586 else
2587 printf(".");
2588
2589 if (lock_depth < 0)
2590 printf(".");
2591 else
2592 printf("%d", lock_depth);
2593}
2594
2528/* taken from Linux, written by Frederic Weisbecker */ 2595/* taken from Linux, written by Frederic Weisbecker */
2529static void print_graph_cpu(int cpu) 2596static void print_graph_cpu(int cpu)
2530{ 2597{
@@ -2768,6 +2835,11 @@ pretty_print_func_ent(void *data, int size, struct event *event,
2768 2835
2769 printf(" | "); 2836 printf(" | ");
2770 2837
2838 if (latency_format) {
2839 print_lat_fmt(data, size);
2840 printf(" | ");
2841 }
2842
2771 field = find_field(event, "func"); 2843 field = find_field(event, "func");
2772 if (!field) 2844 if (!field)
2773 die("function entry does not have func field"); 2845 die("function entry does not have func field");
@@ -2811,6 +2883,11 @@ pretty_print_func_ret(void *data, int size __unused, struct event *event,
2811 2883
2812 printf(" | "); 2884 printf(" | ");
2813 2885
2886 if (latency_format) {
2887 print_lat_fmt(data, size);
2888 printf(" | ");
2889 }
2890
2814 field = find_field(event, "rettime"); 2891 field = find_field(event, "rettime");
2815 if (!field) 2892 if (!field)
2816 die("can't find rettime in return graph"); 2893 die("can't find rettime in return graph");
@@ -2882,9 +2959,14 @@ void print_event(int cpu, void *data, int size, unsigned long long nsecs,
2882 return pretty_print_func_graph(data, size, event, cpu, 2959 return pretty_print_func_graph(data, size, event, cpu,
2883 pid, comm, secs, usecs); 2960 pid, comm, secs, usecs);
2884 2961
2885 printf("%16s-%-5d [%03d] %5lu.%09Lu: %s: ", 2962 if (latency_format) {
2886 comm, pid, cpu, 2963 printf("%8.8s-%-5d %3d",
2887 secs, nsecs, event->name); 2964 comm, pid, cpu);
2965 print_lat_fmt(data, size);
2966 } else
2967 printf("%16s-%-5d [%03d]", comm, pid, cpu);
2968
2969 printf(" %5lu.%06lu: %s: ", secs, usecs, event->name);
2888 2970
2889 if (event->flags & EVENT_FL_FAILED) { 2971 if (event->flags & EVENT_FL_FAILED) {
2890 printf("EVENT '%s' FAILED TO PARSE\n", 2972 printf("EVENT '%s' FAILED TO PARSE\n",
diff --git a/tools/perf/util/trace-event.h b/tools/perf/util/trace-event.h
index 29821acc8db6..f6637c2fa1fe 100644
--- a/tools/perf/util/trace-event.h
+++ b/tools/perf/util/trace-event.h
@@ -239,6 +239,8 @@ extern int header_page_size_size;
239extern int header_page_data_offset; 239extern int header_page_data_offset;
240extern int header_page_data_size; 240extern int header_page_data_size;
241 241
242extern int latency_format;
243
242int parse_header_page(char *buf, unsigned long size); 244int parse_header_page(char *buf, unsigned long size);
243int trace_parse_common_type(void *data); 245int trace_parse_common_type(void *data);
244struct event *trace_find_event(int id); 246struct event *trace_find_event(int id);
@@ -248,4 +250,13 @@ void *raw_field_ptr(struct event *event, const char *name, void *data);
248 250
249void read_tracing_data(int fd, struct perf_event_attr *pattrs, int nb_events); 251void read_tracing_data(int fd, struct perf_event_attr *pattrs, int nb_events);
250 252
253/* taken from kernel/trace/trace.h */
254enum trace_flag_type {
255 TRACE_FLAG_IRQS_OFF = 0x01,
256 TRACE_FLAG_IRQS_NOSUPPORT = 0x02,
257 TRACE_FLAG_NEED_RESCHED = 0x04,
258 TRACE_FLAG_HARDIRQ = 0x08,
259 TRACE_FLAG_SOFTIRQ = 0x10,
260};
261
251#endif /* __PERF_TRACE_EVENTS_H */ 262#endif /* __PERF_TRACE_EVENTS_H */