aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2010-05-23 05:09:19 -0400
committerIngo Molnar <mingo@elte.hu>2010-05-23 05:09:19 -0400
commitc392c4c6dccf7c64c113b473c7eceedf25eddd51 (patch)
tree0fe27295bd81e5da4d6d8520a17c1711774c1246
parent841bca1393d315d79077f272c2918423e36dc364 (diff)
parent46e3e055ce69a00d735e458445ab1d24718ff751 (diff)
Merge branch 'perf' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux-2.6 into perf/core
-rw-r--r--tools/perf/builtin-annotate.c61
-rw-r--r--tools/perf/util/hist.c13
-rw-r--r--tools/perf/util/hist.h10
-rw-r--r--tools/perf/util/newt.c61
-rw-r--r--tools/perf/util/util.h15
5 files changed, 116 insertions, 44 deletions
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index 77bcc9b130f5..08278eda31a5 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -277,7 +277,7 @@ static void hist_entry__print_hits(struct hist_entry *self)
277 printf("%*s: %Lu\n", BITS_PER_LONG / 2, "h->sum", h->sum); 277 printf("%*s: %Lu\n", BITS_PER_LONG / 2, "h->sum", h->sum);
278} 278}
279 279
280static void annotate_sym(struct hist_entry *he) 280static int hist_entry__tty_annotate(struct hist_entry *he)
281{ 281{
282 struct map *map = he->ms.map; 282 struct map *map = he->ms.map;
283 struct dso *dso = map->dso; 283 struct dso *dso = map->dso;
@@ -288,7 +288,7 @@ static void annotate_sym(struct hist_entry *he)
288 struct objdump_line *pos, *n; 288 struct objdump_line *pos, *n;
289 289
290 if (hist_entry__annotate(he, &head) < 0) 290 if (hist_entry__annotate(he, &head) < 0)
291 return; 291 return -1;
292 292
293 if (full_paths) 293 if (full_paths)
294 d_filename = filename; 294 d_filename = filename;
@@ -317,30 +317,59 @@ static void annotate_sym(struct hist_entry *he)
317 317
318 if (print_line) 318 if (print_line)
319 free_source_line(he, len); 319 free_source_line(he, len);
320
321 return 0;
320} 322}
321 323
322static void hists__find_annotations(struct hists *self) 324static void hists__find_annotations(struct hists *self)
323{ 325{
324 struct rb_node *nd; 326 struct rb_node *first = rb_first(&self->entries), *nd = first;
327 int key = KEY_RIGHT;
325 328
326 for (nd = rb_first(&self->entries); nd; nd = rb_next(nd)) { 329 while (nd) {
327 struct hist_entry *he = rb_entry(nd, struct hist_entry, rb_node); 330 struct hist_entry *he = rb_entry(nd, struct hist_entry, rb_node);
328 struct sym_priv *priv; 331 struct sym_priv *priv;
329 332
330 if (he->ms.sym == NULL) 333 if (he->ms.sym == NULL || he->ms.map->dso->annotate_warned)
331 continue; 334 goto find_next;
332 335
333 priv = symbol__priv(he->ms.sym); 336 priv = symbol__priv(he->ms.sym);
334 if (priv->hist == NULL) 337 if (priv->hist == NULL) {
338find_next:
339 if (key == KEY_LEFT)
340 nd = rb_prev(nd);
341 else
342 nd = rb_next(nd);
335 continue; 343 continue;
344 }
336 345
337 annotate_sym(he); 346 if (use_browser) {
338 /* 347 key = hist_entry__tui_annotate(he);
339 * Since we have a hist_entry per IP for the same symbol, free 348 if (is_exit_key(key))
340 * he->ms.sym->hist to signal we already processed this symbol. 349 break;
341 */ 350 switch (key) {
342 free(priv->hist); 351 case KEY_RIGHT:
343 priv->hist = NULL; 352 case '\t':
353 nd = rb_next(nd);
354 break;
355 case KEY_LEFT:
356 if (nd == first)
357 continue;
358 nd = rb_prev(nd);
359 default:
360 break;
361 }
362 } else {
363 hist_entry__tty_annotate(he);
364 nd = rb_next(nd);
365 /*
366 * Since we have a hist_entry per IP for the same
367 * symbol, free he->ms.sym->hist to signal we already
368 * processed this symbol.
369 */
370 free(priv->hist);
371 priv->hist = NULL;
372 }
344 } 373 }
345} 374}
346 375
@@ -416,6 +445,8 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __used)
416{ 445{
417 argc = parse_options(argc, argv, options, annotate_usage, 0); 446 argc = parse_options(argc, argv, options, annotate_usage, 0);
418 447
448 setup_browser();
449
419 symbol_conf.priv_size = sizeof(struct sym_priv); 450 symbol_conf.priv_size = sizeof(struct sym_priv);
420 symbol_conf.try_vmlinux_path = true; 451 symbol_conf.try_vmlinux_path = true;
421 452
@@ -435,8 +466,6 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __used)
435 sym_hist_filter = argv[0]; 466 sym_hist_filter = argv[0];
436 } 467 }
437 468
438 setup_pager();
439
440 if (field_sep && *field_sep == '.') { 469 if (field_sep && *field_sep == '.') {
441 pr_err("'.' is the only non valid --field-separator argument\n"); 470 pr_err("'.' is the only non valid --field-separator argument\n");
442 return -1; 471 return -1;
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index 009ad76b0879..682a6d88862c 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -992,14 +992,14 @@ int hist_entry__annotate(struct hist_entry *self, struct list_head *head)
992 char *filename = dso__build_id_filename(dso, NULL, 0); 992 char *filename = dso__build_id_filename(dso, NULL, 0);
993 char command[PATH_MAX * 2]; 993 char command[PATH_MAX * 2];
994 FILE *file; 994 FILE *file;
995 int err = -1; 995 int err = 0;
996 u64 len; 996 u64 len;
997 997
998 if (filename == NULL) { 998 if (filename == NULL) {
999 if (dso->has_build_id) { 999 if (dso->has_build_id) {
1000 pr_err("Can't annotate %s: not enough memory\n", 1000 pr_err("Can't annotate %s: not enough memory\n",
1001 sym->name); 1001 sym->name);
1002 return -1; 1002 return -ENOMEM;
1003 } 1003 }
1004 /* 1004 /*
1005 * If we don't have build-ids, well, lets hope that this 1005 * If we don't have build-ids, well, lets hope that this
@@ -1009,14 +1009,12 @@ int hist_entry__annotate(struct hist_entry *self, struct list_head *head)
1009 } 1009 }
1010 1010
1011 if (dso->origin == DSO__ORIG_KERNEL) { 1011 if (dso->origin == DSO__ORIG_KERNEL) {
1012 if (dso->annotate_warned) { 1012 if (dso->annotate_warned)
1013 err = 0;
1014 goto out_free_filename; 1013 goto out_free_filename;
1015 } 1014 err = -ENOENT;
1016 dso->annotate_warned = 1; 1015 dso->annotate_warned = 1;
1017 pr_err("Can't annotate %s: No vmlinux file was found in the " 1016 pr_err("Can't annotate %s: No vmlinux file was found in the "
1018 "path:\n", sym->name); 1017 "path\n", sym->name);
1019 vmlinux_path__fprintf(stderr);
1020 goto out_free_filename; 1018 goto out_free_filename;
1021 } 1019 }
1022 1020
@@ -1046,7 +1044,6 @@ int hist_entry__annotate(struct hist_entry *self, struct list_head *head)
1046 break; 1044 break;
1047 1045
1048 pclose(file); 1046 pclose(file);
1049 err = 0;
1050out_free_filename: 1047out_free_filename:
1051 if (dso->has_build_id) 1048 if (dso->has_build_id)
1052 free(filename); 1049 free(filename);
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h
index 6f17dcd8412c..2d5203fedb20 100644
--- a/tools/perf/util/hist.h
+++ b/tools/perf/util/hist.h
@@ -102,8 +102,18 @@ static inline int hists__browse(struct hists *self __used,
102{ 102{
103 return 0; 103 return 0;
104} 104}
105static inline int hist_entry__tui_annotate(struct hist_entry *self __used)
106{
107 return 0;
108}
109#define KEY_LEFT -1
110#define KEY_RIGHT -2
105#else 111#else
112#include <newt.h>
106int hists__browse(struct hists *self, const char *helpline, 113int hists__browse(struct hists *self, const char *helpline,
107 const char *input_name); 114 const char *input_name);
115int hist_entry__tui_annotate(struct hist_entry *self);
116#define KEY_LEFT NEWT_KEY_LEFT
117#define KEY_RIGHT NEWT_KEY_RIGHT
108#endif 118#endif
109#endif /* __PERF_HIST_H */ 119#endif /* __PERF_HIST_H */
diff --git a/tools/perf/util/newt.c b/tools/perf/util/newt.c
index 0b45658f7497..ffd04720b754 100644
--- a/tools/perf/util/newt.c
+++ b/tools/perf/util/newt.c
@@ -235,6 +235,15 @@ static bool dialog_yesno(const char *msg)
235 return newtWinChoice(NULL, yes, no, (char *)msg) == 1; 235 return newtWinChoice(NULL, yes, no, (char *)msg) == 1;
236} 236}
237 237
238static void ui__error_window(const char *fmt, ...)
239{
240 va_list ap;
241
242 va_start(ap, fmt);
243 newtWinMessagev((char *)"Error", (char *)"Ok", (char *)fmt, ap);
244 va_end(ap);
245}
246
238#define HE_COLORSET_TOP 50 247#define HE_COLORSET_TOP 50
239#define HE_COLORSET_MEDIUM 51 248#define HE_COLORSET_MEDIUM 51
240#define HE_COLORSET_NORMAL 52 249#define HE_COLORSET_NORMAL 52
@@ -386,6 +395,8 @@ static int ui_browser__run(struct ui_browser *self, const char *title,
386 newtFormAddHotKey(self->form, ' '); 395 newtFormAddHotKey(self->form, ' ');
387 newtFormAddHotKey(self->form, NEWT_KEY_HOME); 396 newtFormAddHotKey(self->form, NEWT_KEY_HOME);
388 newtFormAddHotKey(self->form, NEWT_KEY_END); 397 newtFormAddHotKey(self->form, NEWT_KEY_END);
398 newtFormAddHotKey(self->form, NEWT_KEY_TAB);
399 newtFormAddHotKey(self->form, NEWT_KEY_RIGHT);
389 400
390 if (ui_browser__refresh_entries(self) < 0) 401 if (ui_browser__refresh_entries(self) < 0)
391 return -1; 402 return -1;
@@ -398,6 +409,8 @@ static int ui_browser__run(struct ui_browser *self, const char *title,
398 409
399 if (es->reason != NEWT_EXIT_HOTKEY) 410 if (es->reason != NEWT_EXIT_HOTKEY)
400 break; 411 break;
412 if (is_exit_key(es->u.key))
413 return es->u.key;
401 switch (es->u.key) { 414 switch (es->u.key) {
402 case NEWT_KEY_DOWN: 415 case NEWT_KEY_DOWN:
403 if (self->index == self->nr_entries - 1) 416 if (self->index == self->nr_entries - 1)
@@ -471,12 +484,10 @@ static int ui_browser__run(struct ui_browser *self, const char *title,
471 } 484 }
472 } 485 }
473 break; 486 break;
474 case NEWT_KEY_ESCAPE: 487 case NEWT_KEY_RIGHT:
475 case NEWT_KEY_LEFT: 488 case NEWT_KEY_LEFT:
476 case CTRL('c'): 489 case NEWT_KEY_TAB:
477 case 'Q': 490 return es->u.key;
478 case 'q':
479 return 0;
480 default: 491 default:
481 continue; 492 continue;
482 } 493 }
@@ -668,18 +679,24 @@ static size_t hist_entry__append_browser(struct hist_entry *self,
668 return ret; 679 return ret;
669} 680}
670 681
671static void hist_entry__annotate_browser(struct hist_entry *self) 682int hist_entry__tui_annotate(struct hist_entry *self)
672{ 683{
673 struct ui_browser browser; 684 struct ui_browser browser;
674 struct newtExitStruct es; 685 struct newtExitStruct es;
675 struct objdump_line *pos, *n; 686 struct objdump_line *pos, *n;
676 LIST_HEAD(head); 687 LIST_HEAD(head);
688 int ret;
677 689
678 if (self->ms.sym == NULL) 690 if (self->ms.sym == NULL)
679 return; 691 return -1;
680 692
681 if (hist_entry__annotate(self, &head) < 0) 693 if (self->ms.map->dso->annotate_warned)
682 return; 694 return -1;
695
696 if (hist_entry__annotate(self, &head) < 0) {
697 ui__error_window(browser__last_msg);
698 return -1;
699 }
683 700
684 ui_helpline__push("Press <- or ESC to exit"); 701 ui_helpline__push("Press <- or ESC to exit");
685 702
@@ -694,7 +711,7 @@ static void hist_entry__annotate_browser(struct hist_entry *self)
694 } 711 }
695 712
696 browser.width += 18; /* Percentage */ 713 browser.width += 18; /* Percentage */
697 ui_browser__run(&browser, self->ms.sym->name, &es); 714 ret = ui_browser__run(&browser, self->ms.sym->name, &es);
698 newtFormDestroy(browser.form); 715 newtFormDestroy(browser.form);
699 newtPopWindow(); 716 newtPopWindow();
700 list_for_each_entry_safe(pos, n, &head, node) { 717 list_for_each_entry_safe(pos, n, &head, node) {
@@ -702,6 +719,7 @@ static void hist_entry__annotate_browser(struct hist_entry *self)
702 objdump_line__free(pos); 719 objdump_line__free(pos);
703 } 720 }
704 ui_helpline__pop(); 721 ui_helpline__pop();
722 return ret;
705} 723}
706 724
707static const void *newt__symbol_tree_get_current(newtComponent self) 725static const void *newt__symbol_tree_get_current(newtComponent self)
@@ -914,6 +932,9 @@ int hists__browse(struct hists *self, const char *helpline, const char *input_na
914 932
915 switch (toupper(es.u.key)) { 933 switch (toupper(es.u.key)) {
916 case 'A': 934 case 'A':
935 if (browser->selection->map == NULL &&
936 browser->selection->map->dso->annotate_warned)
937 continue;
917 goto do_annotate; 938 goto do_annotate;
918 case 'D': 939 case 'D':
919 goto zoom_dso; 940 goto zoom_dso;
@@ -932,14 +953,14 @@ do_help:
932 continue; 953 continue;
933 default:; 954 default:;
934 } 955 }
935 if (toupper(es.u.key) == 'Q' || 956 if (is_exit_key(es.u.key)) {
936 es.u.key == CTRL('c')) 957 if (es.u.key == NEWT_KEY_ESCAPE) {
937 break; 958 if (dialog_yesno("Do you really want to exit?"))
938 if (es.u.key == NEWT_KEY_ESCAPE) { 959 break;
939 if (dialog_yesno("Do you really want to exit?")) 960 else
961 continue;
962 } else
940 break; 963 break;
941 else
942 continue;
943 } 964 }
944 965
945 if (es.u.key == NEWT_KEY_LEFT) { 966 if (es.u.key == NEWT_KEY_LEFT) {
@@ -957,6 +978,7 @@ do_help:
957 } 978 }
958 979
959 if (browser->selection->sym != NULL && 980 if (browser->selection->sym != NULL &&
981 !browser->selection->map->dso->annotate_warned &&
960 asprintf(&options[nr_options], "Annotate %s", 982 asprintf(&options[nr_options], "Annotate %s",
961 browser->selection->sym->name) > 0) 983 browser->selection->sym->name) > 0)
962 annotate = nr_options++; 984 annotate = nr_options++;
@@ -991,6 +1013,7 @@ do_help:
991 struct hist_entry *he; 1013 struct hist_entry *he;
992do_annotate: 1014do_annotate:
993 if (browser->selection->map->dso->origin == DSO__ORIG_KERNEL) { 1015 if (browser->selection->map->dso->origin == DSO__ORIG_KERNEL) {
1016 browser->selection->map->dso->annotate_warned = 1;
994 ui_helpline__puts("No vmlinux file found, can't " 1017 ui_helpline__puts("No vmlinux file found, can't "
995 "annotate with just a " 1018 "annotate with just a "
996 "kallsyms file"); 1019 "kallsyms file");
@@ -1001,7 +1024,7 @@ do_annotate:
1001 if (he == NULL) 1024 if (he == NULL)
1002 continue; 1025 continue;
1003 1026
1004 hist_entry__annotate_browser(he); 1027 hist_entry__tui_annotate(he);
1005 } else if (choice == zoom_dso) { 1028 } else if (choice == zoom_dso) {
1006zoom_dso: 1029zoom_dso:
1007 if (dso_filter) { 1030 if (dso_filter) {
@@ -1069,7 +1092,7 @@ void setup_browser(void)
1069{ 1092{
1070 struct newtPercentTreeColors *c = &defaultPercentTreeColors; 1093 struct newtPercentTreeColors *c = &defaultPercentTreeColors;
1071 1094
1072 if (!isatty(1) || !use_browser) { 1095 if (!isatty(1) || !use_browser || dump_trace) {
1073 setup_pager(); 1096 setup_pager();
1074 return; 1097 return;
1075 } 1098 }
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h
index 45b9655f3a5c..4e8b6b0c551c 100644
--- a/tools/perf/util/util.h
+++ b/tools/perf/util/util.h
@@ -81,7 +81,7 @@
81#include <inttypes.h> 81#include <inttypes.h>
82#include "../../../include/linux/magic.h" 82#include "../../../include/linux/magic.h"
83#include "types.h" 83#include "types.h"
84 84#include <sys/ttydefaults.h>
85 85
86#ifndef NO_ICONV 86#ifndef NO_ICONV
87#include <iconv.h> 87#include <iconv.h>
@@ -263,6 +263,19 @@ bool strglobmatch(const char *str, const char *pat);
263bool strlazymatch(const char *str, const char *pat); 263bool strlazymatch(const char *str, const char *pat);
264unsigned long convert_unit(unsigned long value, char *unit); 264unsigned long convert_unit(unsigned long value, char *unit);
265 265
266#ifndef ESC
267#define ESC 27
268#endif
269
270static inline bool is_exit_key(int key)
271{
272 char up;
273 if (key == CTRL('c') || key == ESC)
274 return true;
275 up = toupper(key);
276 return up == 'Q';
277}
278
266#define _STR(x) #x 279#define _STR(x) #x
267#define STR(x) _STR(x) 280#define STR(x) _STR(x)
268 281