Commit c392c4c6 authored by Ingo Molnar's avatar Ingo Molnar

Merge branch 'perf' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux-2.6 into perf/core

parents 841bca13 46e3e055
......@@ -277,7 +277,7 @@ static void hist_entry__print_hits(struct hist_entry *self)
printf("%*s: %Lu\n", BITS_PER_LONG / 2, "h->sum", h->sum);
}
static void annotate_sym(struct hist_entry *he)
static int hist_entry__tty_annotate(struct hist_entry *he)
{
struct map *map = he->ms.map;
struct dso *dso = map->dso;
......@@ -288,7 +288,7 @@ static void annotate_sym(struct hist_entry *he)
struct objdump_line *pos, *n;
if (hist_entry__annotate(he, &head) < 0)
return;
return -1;
if (full_paths)
d_filename = filename;
......@@ -317,31 +317,60 @@ static void annotate_sym(struct hist_entry *he)
if (print_line)
free_source_line(he, len);
return 0;
}
static void hists__find_annotations(struct hists *self)
{
struct rb_node *nd;
struct rb_node *first = rb_first(&self->entries), *nd = first;
int key = KEY_RIGHT;
for (nd = rb_first(&self->entries); nd; nd = rb_next(nd)) {
while (nd) {
struct hist_entry *he = rb_entry(nd, struct hist_entry, rb_node);
struct sym_priv *priv;
if (he->ms.sym == NULL)
continue;
if (he->ms.sym == NULL || he->ms.map->dso->annotate_warned)
goto find_next;
priv = symbol__priv(he->ms.sym);
if (priv->hist == NULL)
if (priv->hist == NULL) {
find_next:
if (key == KEY_LEFT)
nd = rb_prev(nd);
else
nd = rb_next(nd);
continue;
}
annotate_sym(he);
if (use_browser) {
key = hist_entry__tui_annotate(he);
if (is_exit_key(key))
break;
switch (key) {
case KEY_RIGHT:
case '\t':
nd = rb_next(nd);
break;
case KEY_LEFT:
if (nd == first)
continue;
nd = rb_prev(nd);
default:
break;
}
} else {
hist_entry__tty_annotate(he);
nd = rb_next(nd);
/*
* Since we have a hist_entry per IP for the same symbol, free
* he->ms.sym->hist to signal we already processed this symbol.
* Since we have a hist_entry per IP for the same
* symbol, free he->ms.sym->hist to signal we already
* processed this symbol.
*/
free(priv->hist);
priv->hist = NULL;
}
}
}
static struct perf_event_ops event_ops = {
......@@ -416,6 +445,8 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __used)
{
argc = parse_options(argc, argv, options, annotate_usage, 0);
setup_browser();
symbol_conf.priv_size = sizeof(struct sym_priv);
symbol_conf.try_vmlinux_path = true;
......@@ -435,8 +466,6 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __used)
sym_hist_filter = argv[0];
}
setup_pager();
if (field_sep && *field_sep == '.') {
pr_err("'.' is the only non valid --field-separator argument\n");
return -1;
......
......@@ -992,14 +992,14 @@ int hist_entry__annotate(struct hist_entry *self, struct list_head *head)
char *filename = dso__build_id_filename(dso, NULL, 0);
char command[PATH_MAX * 2];
FILE *file;
int err = -1;
int err = 0;
u64 len;
if (filename == NULL) {
if (dso->has_build_id) {
pr_err("Can't annotate %s: not enough memory\n",
sym->name);
return -1;
return -ENOMEM;
}
/*
* 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)
}
if (dso->origin == DSO__ORIG_KERNEL) {
if (dso->annotate_warned) {
err = 0;
if (dso->annotate_warned)
goto out_free_filename;
}
err = -ENOENT;
dso->annotate_warned = 1;
pr_err("Can't annotate %s: No vmlinux file was found in the "
"path:\n", sym->name);
vmlinux_path__fprintf(stderr);
"path\n", sym->name);
goto out_free_filename;
}
......@@ -1046,7 +1044,6 @@ int hist_entry__annotate(struct hist_entry *self, struct list_head *head)
break;
pclose(file);
err = 0;
out_free_filename:
if (dso->has_build_id)
free(filename);
......
......@@ -102,8 +102,18 @@ static inline int hists__browse(struct hists *self __used,
{
return 0;
}
static inline int hist_entry__tui_annotate(struct hist_entry *self __used)
{
return 0;
}
#define KEY_LEFT -1
#define KEY_RIGHT -2
#else
#include <newt.h>
int hists__browse(struct hists *self, const char *helpline,
const char *input_name);
int hist_entry__tui_annotate(struct hist_entry *self);
#define KEY_LEFT NEWT_KEY_LEFT
#define KEY_RIGHT NEWT_KEY_RIGHT
#endif
#endif /* __PERF_HIST_H */
......@@ -235,6 +235,15 @@ static bool dialog_yesno(const char *msg)
return newtWinChoice(NULL, yes, no, (char *)msg) == 1;
}
static void ui__error_window(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
newtWinMessagev((char *)"Error", (char *)"Ok", (char *)fmt, ap);
va_end(ap);
}
#define HE_COLORSET_TOP 50
#define HE_COLORSET_MEDIUM 51
#define HE_COLORSET_NORMAL 52
......@@ -386,6 +395,8 @@ static int ui_browser__run(struct ui_browser *self, const char *title,
newtFormAddHotKey(self->form, ' ');
newtFormAddHotKey(self->form, NEWT_KEY_HOME);
newtFormAddHotKey(self->form, NEWT_KEY_END);
newtFormAddHotKey(self->form, NEWT_KEY_TAB);
newtFormAddHotKey(self->form, NEWT_KEY_RIGHT);
if (ui_browser__refresh_entries(self) < 0)
return -1;
......@@ -398,6 +409,8 @@ static int ui_browser__run(struct ui_browser *self, const char *title,
if (es->reason != NEWT_EXIT_HOTKEY)
break;
if (is_exit_key(es->u.key))
return es->u.key;
switch (es->u.key) {
case NEWT_KEY_DOWN:
if (self->index == self->nr_entries - 1)
......@@ -471,12 +484,10 @@ static int ui_browser__run(struct ui_browser *self, const char *title,
}
}
break;
case NEWT_KEY_ESCAPE:
case NEWT_KEY_RIGHT:
case NEWT_KEY_LEFT:
case CTRL('c'):
case 'Q':
case 'q':
return 0;
case NEWT_KEY_TAB:
return es->u.key;
default:
continue;
}
......@@ -668,18 +679,24 @@ static size_t hist_entry__append_browser(struct hist_entry *self,
return ret;
}
static void hist_entry__annotate_browser(struct hist_entry *self)
int hist_entry__tui_annotate(struct hist_entry *self)
{
struct ui_browser browser;
struct newtExitStruct es;
struct objdump_line *pos, *n;
LIST_HEAD(head);
int ret;
if (self->ms.sym == NULL)
return;
return -1;
if (hist_entry__annotate(self, &head) < 0)
return;
if (self->ms.map->dso->annotate_warned)
return -1;
if (hist_entry__annotate(self, &head) < 0) {
ui__error_window(browser__last_msg);
return -1;
}
ui_helpline__push("Press <- or ESC to exit");
......@@ -694,7 +711,7 @@ static void hist_entry__annotate_browser(struct hist_entry *self)
}
browser.width += 18; /* Percentage */
ui_browser__run(&browser, self->ms.sym->name, &es);
ret = ui_browser__run(&browser, self->ms.sym->name, &es);
newtFormDestroy(browser.form);
newtPopWindow();
list_for_each_entry_safe(pos, n, &head, node) {
......@@ -702,6 +719,7 @@ static void hist_entry__annotate_browser(struct hist_entry *self)
objdump_line__free(pos);
}
ui_helpline__pop();
return ret;
}
static 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
switch (toupper(es.u.key)) {
case 'A':
if (browser->selection->map == NULL &&
browser->selection->map->dso->annotate_warned)
continue;
goto do_annotate;
case 'D':
goto zoom_dso;
......@@ -932,14 +953,14 @@ int hists__browse(struct hists *self, const char *helpline, const char *input_na
continue;
default:;
}
if (toupper(es.u.key) == 'Q' ||
es.u.key == CTRL('c'))
break;
if (is_exit_key(es.u.key)) {
if (es.u.key == NEWT_KEY_ESCAPE) {
if (dialog_yesno("Do you really want to exit?"))
break;
else
continue;
} else
break;
}
if (es.u.key == NEWT_KEY_LEFT) {
......@@ -957,6 +978,7 @@ int hists__browse(struct hists *self, const char *helpline, const char *input_na
}
if (browser->selection->sym != NULL &&
!browser->selection->map->dso->annotate_warned &&
asprintf(&options[nr_options], "Annotate %s",
browser->selection->sym->name) > 0)
annotate = nr_options++;
......@@ -991,6 +1013,7 @@ int hists__browse(struct hists *self, const char *helpline, const char *input_na
struct hist_entry *he;
do_annotate:
if (browser->selection->map->dso->origin == DSO__ORIG_KERNEL) {
browser->selection->map->dso->annotate_warned = 1;
ui_helpline__puts("No vmlinux file found, can't "
"annotate with just a "
"kallsyms file");
......@@ -1001,7 +1024,7 @@ int hists__browse(struct hists *self, const char *helpline, const char *input_na
if (he == NULL)
continue;
hist_entry__annotate_browser(he);
hist_entry__tui_annotate(he);
} else if (choice == zoom_dso) {
zoom_dso:
if (dso_filter) {
......@@ -1069,7 +1092,7 @@ void setup_browser(void)
{
struct newtPercentTreeColors *c = &defaultPercentTreeColors;
if (!isatty(1) || !use_browser) {
if (!isatty(1) || !use_browser || dump_trace) {
setup_pager();
return;
}
......
......@@ -81,7 +81,7 @@
#include <inttypes.h>
#include "../../../include/linux/magic.h"
#include "types.h"
#include <sys/ttydefaults.h>
#ifndef NO_ICONV
#include <iconv.h>
......@@ -263,6 +263,19 @@ bool strglobmatch(const char *str, const char *pat);
bool strlazymatch(const char *str, const char *pat);
unsigned long convert_unit(unsigned long value, char *unit);
#ifndef ESC
#define ESC 27
#endif
static inline bool is_exit_key(int key)
{
char up;
if (key == CTRL('c') || key == ESC)
return true;
up = toupper(key);
return up == 'Q';
}
#define _STR(x) #x
#define STR(x) _STR(x)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment