diff options
author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2011-09-01 13:27:58 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2011-09-29 15:41:38 -0400 |
commit | dcc101d1d02eb80ab0349c5410f8728412c35636 (patch) | |
tree | 9f91b0f6da160c767bee572296e59a46017c25e7 /tools | |
parent | eb489008312c848dce8ff76282b8e65c530c2e26 (diff) |
perf top: Improve lost events warning
Now it warns everytime that new events are lost.
And the TUI also warns now.
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-w1n168yrvrppnq6887s4u0wx@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools')
-rw-r--r-- | tools/perf/builtin-top.c | 34 | ||||
-rw-r--r-- | tools/perf/util/top.h | 3 | ||||
-rw-r--r-- | tools/perf/util/ui/browsers/top.c | 24 |
3 files changed, 44 insertions, 17 deletions
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index a43433f08300..23c4f71c407a 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c | |||
@@ -250,7 +250,7 @@ static void __list_insert_active_sym(struct sym_entry *syme) | |||
250 | list_add(&syme->node, &top.active_symbols); | 250 | list_add(&syme->node, &top.active_symbols); |
251 | } | 251 | } |
252 | 252 | ||
253 | static void print_sym_table(struct perf_session *session) | 253 | static void print_sym_table(void) |
254 | { | 254 | { |
255 | char bf[160]; | 255 | char bf[160]; |
256 | int printed = 0; | 256 | int printed = 0; |
@@ -270,10 +270,11 @@ static void print_sym_table(struct perf_session *session) | |||
270 | 270 | ||
271 | printf("%-*.*s\n", win_width, win_width, graph_dotted_line); | 271 | printf("%-*.*s\n", win_width, win_width, graph_dotted_line); |
272 | 272 | ||
273 | if (session->hists.stats.total_lost != 0) { | 273 | if (top.total_lost_warned != top.session->hists.stats.total_lost) { |
274 | top.total_lost_warned = top.session->hists.stats.total_lost; | ||
274 | color_fprintf(stdout, PERF_COLOR_RED, "WARNING:"); | 275 | color_fprintf(stdout, PERF_COLOR_RED, "WARNING:"); |
275 | printf(" LOST %" PRIu64 " events, Check IO/CPU overload\n", | 276 | printf(" LOST %" PRIu64 " events, Check IO/CPU overload\n", |
276 | session->hists.stats.total_lost); | 277 | top.total_lost_warned); |
277 | } | 278 | } |
278 | 279 | ||
279 | if (top.sym_filter_entry) { | 280 | if (top.sym_filter_entry) { |
@@ -474,7 +475,7 @@ static int key_mapped(int c) | |||
474 | return 0; | 475 | return 0; |
475 | } | 476 | } |
476 | 477 | ||
477 | static void handle_keypress(struct perf_session *session, int c) | 478 | static void handle_keypress(int c) |
478 | { | 479 | { |
479 | if (!key_mapped(c)) { | 480 | if (!key_mapped(c)) { |
480 | struct pollfd stdin_poll = { .fd = 0, .events = POLLIN }; | 481 | struct pollfd stdin_poll = { .fd = 0, .events = POLLIN }; |
@@ -550,7 +551,7 @@ static void handle_keypress(struct perf_session *session, int c) | |||
550 | case 'Q': | 551 | case 'Q': |
551 | printf("exiting.\n"); | 552 | printf("exiting.\n"); |
552 | if (dump_symtab) | 553 | if (dump_symtab) |
553 | perf_session__fprintf_dsos(session, stderr); | 554 | perf_session__fprintf_dsos(top.session, stderr); |
554 | exit(0); | 555 | exit(0); |
555 | case 's': | 556 | case 's': |
556 | prompt_symbol(&top.sym_filter_entry, "Enter details symbol"); | 557 | prompt_symbol(&top.sym_filter_entry, "Enter details symbol"); |
@@ -602,7 +603,6 @@ static void *display_thread(void *arg __used) | |||
602 | struct pollfd stdin_poll = { .fd = 0, .events = POLLIN }; | 603 | struct pollfd stdin_poll = { .fd = 0, .events = POLLIN }; |
603 | struct termios tc, save; | 604 | struct termios tc, save; |
604 | int delay_msecs, c; | 605 | int delay_msecs, c; |
605 | struct perf_session *session = (struct perf_session *) arg; | ||
606 | 606 | ||
607 | tcgetattr(0, &save); | 607 | tcgetattr(0, &save); |
608 | tc = save; | 608 | tc = save; |
@@ -617,13 +617,13 @@ repeat: | |||
617 | getc(stdin); | 617 | getc(stdin); |
618 | 618 | ||
619 | do { | 619 | do { |
620 | print_sym_table(session); | 620 | print_sym_table(); |
621 | } while (!poll(&stdin_poll, 1, delay_msecs) == 1); | 621 | } while (!poll(&stdin_poll, 1, delay_msecs) == 1); |
622 | 622 | ||
623 | c = getc(stdin); | 623 | c = getc(stdin); |
624 | tcsetattr(0, TCSAFLUSH, &save); | 624 | tcsetattr(0, TCSAFLUSH, &save); |
625 | 625 | ||
626 | handle_keypress(session, c); | 626 | handle_keypress(c); |
627 | goto repeat; | 627 | goto repeat; |
628 | 628 | ||
629 | return NULL; | 629 | return NULL; |
@@ -935,27 +935,27 @@ static int __cmd_top(void) | |||
935 | * FIXME: perf_session__new should allow passing a O_MMAP, so that all this | 935 | * FIXME: perf_session__new should allow passing a O_MMAP, so that all this |
936 | * mmap reading, etc is encapsulated in it. Use O_WRONLY for now. | 936 | * mmap reading, etc is encapsulated in it. Use O_WRONLY for now. |
937 | */ | 937 | */ |
938 | struct perf_session *session = perf_session__new(NULL, O_WRONLY, false, false, NULL); | 938 | top.session = perf_session__new(NULL, O_WRONLY, false, false, NULL); |
939 | if (session == NULL) | 939 | if (top.session == NULL) |
940 | return -ENOMEM; | 940 | return -ENOMEM; |
941 | 941 | ||
942 | if (top.target_tid != -1) | 942 | if (top.target_tid != -1) |
943 | perf_event__synthesize_thread_map(top.evlist->threads, | 943 | perf_event__synthesize_thread_map(top.evlist->threads, |
944 | perf_event__process, session); | 944 | perf_event__process, top.session); |
945 | else | 945 | else |
946 | perf_event__synthesize_threads(perf_event__process, session); | 946 | perf_event__synthesize_threads(perf_event__process, top.session); |
947 | 947 | ||
948 | start_counters(top.evlist); | 948 | start_counters(top.evlist); |
949 | session->evlist = top.evlist; | 949 | top.session->evlist = top.evlist; |
950 | perf_session__update_sample_type(session); | 950 | perf_session__update_sample_type(top.session); |
951 | 951 | ||
952 | /* Wait for a minimal set of events before starting the snapshot */ | 952 | /* Wait for a minimal set of events before starting the snapshot */ |
953 | poll(top.evlist->pollfd, top.evlist->nr_fds, 100); | 953 | poll(top.evlist->pollfd, top.evlist->nr_fds, 100); |
954 | 954 | ||
955 | perf_session__mmap_read(session); | 955 | perf_session__mmap_read(top.session); |
956 | 956 | ||
957 | if (pthread_create(&thread, NULL, (use_browser > 0 ? display_thread_tui : | 957 | if (pthread_create(&thread, NULL, (use_browser > 0 ? display_thread_tui : |
958 | display_thread), session)) { | 958 | display_thread), NULL)) { |
959 | printf("Could not create display thread.\n"); | 959 | printf("Could not create display thread.\n"); |
960 | exit(-1); | 960 | exit(-1); |
961 | } | 961 | } |
@@ -973,7 +973,7 @@ static int __cmd_top(void) | |||
973 | while (1) { | 973 | while (1) { |
974 | u64 hits = top.samples; | 974 | u64 hits = top.samples; |
975 | 975 | ||
976 | perf_session__mmap_read(session); | 976 | perf_session__mmap_read(top.session); |
977 | 977 | ||
978 | if (hits == top.samples) | 978 | if (hits == top.samples) |
979 | ret = poll(top.evlist->pollfd, top.evlist->nr_fds, 100); | 979 | ret = poll(top.evlist->pollfd, top.evlist->nr_fds, 100); |
diff --git a/tools/perf/util/top.h b/tools/perf/util/top.h index bfbf95bcc603..b07b0410463c 100644 --- a/tools/perf/util/top.h +++ b/tools/perf/util/top.h | |||
@@ -10,6 +10,7 @@ | |||
10 | 10 | ||
11 | struct perf_evlist; | 11 | struct perf_evlist; |
12 | struct perf_evsel; | 12 | struct perf_evsel; |
13 | struct perf_session; | ||
13 | 14 | ||
14 | struct sym_entry { | 15 | struct sym_entry { |
15 | struct rb_node rb_node; | 16 | struct rb_node rb_node; |
@@ -38,6 +39,7 @@ struct perf_top { | |||
38 | u64 kernel_samples, us_samples; | 39 | u64 kernel_samples, us_samples; |
39 | u64 exact_samples; | 40 | u64 exact_samples; |
40 | u64 guest_us_samples, guest_kernel_samples; | 41 | u64 guest_us_samples, guest_kernel_samples; |
42 | u64 total_lost_warned; | ||
41 | int print_entries, count_filter, delay_secs; | 43 | int print_entries, count_filter, delay_secs; |
42 | int display_weighted, freq, rb_entries; | 44 | int display_weighted, freq, rb_entries; |
43 | pid_t target_pid, target_tid; | 45 | pid_t target_pid, target_tid; |
@@ -45,6 +47,7 @@ struct perf_top { | |||
45 | const char *cpu_list; | 47 | const char *cpu_list; |
46 | struct sym_entry *sym_filter_entry; | 48 | struct sym_entry *sym_filter_entry; |
47 | struct perf_evsel *sym_evsel; | 49 | struct perf_evsel *sym_evsel; |
50 | struct perf_session *session; | ||
48 | }; | 51 | }; |
49 | 52 | ||
50 | size_t perf_top__header_snprintf(struct perf_top *top, char *bf, size_t size); | 53 | size_t perf_top__header_snprintf(struct perf_top *top, char *bf, size_t size); |
diff --git a/tools/perf/util/ui/browsers/top.c b/tools/perf/util/ui/browsers/top.c index 9d938106510f..9b6b43b32ac8 100644 --- a/tools/perf/util/ui/browsers/top.c +++ b/tools/perf/util/ui/browsers/top.c | |||
@@ -11,10 +11,12 @@ | |||
11 | #include "../helpline.h" | 11 | #include "../helpline.h" |
12 | #include "../libslang.h" | 12 | #include "../libslang.h" |
13 | #include "../util.h" | 13 | #include "../util.h" |
14 | #include "../ui.h" | ||
14 | #include "../../evlist.h" | 15 | #include "../../evlist.h" |
15 | #include "../../hist.h" | 16 | #include "../../hist.h" |
16 | #include "../../sort.h" | 17 | #include "../../sort.h" |
17 | #include "../../symbol.h" | 18 | #include "../../symbol.h" |
19 | #include "../../session.h" | ||
18 | #include "../../top.h" | 20 | #include "../../top.h" |
19 | 21 | ||
20 | struct perf_top_browser { | 22 | struct perf_top_browser { |
@@ -143,6 +145,25 @@ do_annotation: | |||
143 | symbol__tui_annotate(sym, syme->map, 0, top->delay_secs * 1000); | 145 | symbol__tui_annotate(sym, syme->map, 0, top->delay_secs * 1000); |
144 | } | 146 | } |
145 | 147 | ||
148 | static void perf_top_browser__warn_lost(struct perf_top_browser *browser) | ||
149 | { | ||
150 | struct perf_top *top = browser->b.priv; | ||
151 | char msg[128]; | ||
152 | int len; | ||
153 | |||
154 | top->total_lost_warned = top->session->hists.stats.total_lost; | ||
155 | pthread_mutex_lock(&ui__lock); | ||
156 | ui_browser__set_color(&browser->b, HE_COLORSET_TOP); | ||
157 | len = snprintf(msg, sizeof(msg), | ||
158 | " WARNING: LOST %" PRIu64 " events, Check IO/CPU overload", | ||
159 | top->total_lost_warned); | ||
160 | if (len > browser->b.width) | ||
161 | len = browser->b.width; | ||
162 | SLsmg_gotorc(0, browser->b.width - len); | ||
163 | slsmg_write_nstring(msg, len); | ||
164 | pthread_mutex_unlock(&ui__lock); | ||
165 | } | ||
166 | |||
146 | static int perf_top_browser__run(struct perf_top_browser *browser) | 167 | static int perf_top_browser__run(struct perf_top_browser *browser) |
147 | { | 168 | { |
148 | int key; | 169 | int key; |
@@ -174,6 +195,9 @@ static int perf_top_browser__run(struct perf_top_browser *browser) | |||
174 | ui_browser__set_color(&browser->b, NEWT_COLORSET_ROOT); | 195 | ui_browser__set_color(&browser->b, NEWT_COLORSET_ROOT); |
175 | SLsmg_gotorc(0, 0); | 196 | SLsmg_gotorc(0, 0); |
176 | slsmg_write_nstring(title, browser->b.width); | 197 | slsmg_write_nstring(title, browser->b.width); |
198 | |||
199 | if (top->total_lost_warned != top->session->hists.stats.total_lost) | ||
200 | perf_top_browser__warn_lost(browser); | ||
177 | break; | 201 | break; |
178 | case 'a': | 202 | case 'a': |
179 | case NEWT_KEY_RIGHT: | 203 | case NEWT_KEY_RIGHT: |