perf hists browser: Warn about lost events

Just like the old perf top --tui and the --stdio version.

But because we have the initial menu to choose which event to show in a
session with multiple events we can see how many chunks were lost in
each of the event types, clarifying which events are being affected the
most.

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-47yyqbubmjzch2chezmb21m6@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
Arnaldo Carvalho de Melo
2011-10-29 12:15:04 -02:00
parent 1ca4ff41a3
commit 7b27509fc6
7 changed files with 112 additions and 29 deletions

View File

@@ -176,16 +176,29 @@ void ui_browser__handle_resize(struct ui_browser *browser)
ui_browser__refresh(browser);
}
int ui_browser__warning(struct ui_browser *browser, const char *format, ...)
int ui_browser__warning(struct ui_browser *browser, int timeout,
const char *format, ...)
{
va_list args;
int key;
char *text;
int key = 0, err;
va_start(args, format);
while ((key = __ui__warning("Warning!", format, args)) == K_RESIZE)
ui_browser__handle_resize(browser);
err = vasprintf(&text, format, args);
va_end(args);
if (err < 0) {
va_start(args, format);
ui_helpline__vpush(format, args);
va_end(args);
} else {
while ((key == ui__question_window("Warning!", text,
"Press any key...",
timeout)) == K_RESIZE)
ui_browser__handle_resize(browser);
free(text);
}
return key;
}

View File

@@ -45,7 +45,8 @@ int ui_browser__run(struct ui_browser *browser, int delay_secs);
void ui_browser__update_nr_entries(struct ui_browser *browser, u32 nr_entries);
void ui_browser__handle_resize(struct ui_browser *browser);
int ui_browser__warning(struct ui_browser *browser, const char *format, ...);
int ui_browser__warning(struct ui_browser *browser, int timeout,
const char *format, ...);
int ui_browser__help_window(struct ui_browser *browser, const char *text);
bool ui_browser__dialog_yesno(struct ui_browser *browser, const char *text);

View File

@@ -295,6 +295,15 @@ static void hist_browser__set_folding(struct hist_browser *self, bool unfold)
ui_browser__reset_index(&self->b);
}
static void ui_browser__warn_lost_events(struct ui_browser *browser)
{
ui_browser__warning(browser, 4,
"Events are being lost, check IO/CPU overload!\n\n"
"You may want to run 'perf' using a RT scheduler policy:\n\n"
" perf top -r 80\n\n"
"Or reduce the sampling frequency.");
}
static int hist_browser__run(struct hist_browser *self, const char *ev_name,
void(*timer)(void *arg), void *arg, int delay_secs)
{
@@ -318,8 +327,15 @@ static int hist_browser__run(struct hist_browser *self, const char *ev_name,
case K_TIMER:
timer(arg);
ui_browser__update_nr_entries(&self->b, self->hists->nr_entries);
hists__browser_title(self->hists, title, sizeof(title),
ev_name);
if (self->hists->stats.nr_lost_warned !=
self->hists->stats.nr_events[PERF_RECORD_LOST]) {
self->hists->stats.nr_lost_warned =
self->hists->stats.nr_events[PERF_RECORD_LOST];
ui_browser__warn_lost_events(&self->b);
}
hists__browser_title(self->hists, title, sizeof(title), ev_name);
ui_browser__show_title(&self->b, title);
continue;
case 'D': { /* Debug */
@@ -883,7 +899,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
goto out_free_stack;
case 'a':
if (!browser->has_symbols) {
ui_browser__warning(&browser->b,
ui_browser__warning(&browser->b, delay_secs * 2,
"Annotation is only available for symbolic views, "
"include \"sym\" in --sort to use it.");
continue;
@@ -1061,6 +1077,7 @@ out:
struct perf_evsel_menu {
struct ui_browser b;
struct perf_evsel *selection;
bool lost_events, lost_events_warned;
};
static void perf_evsel_menu__write(struct ui_browser *browser,
@@ -1073,14 +1090,29 @@ static void perf_evsel_menu__write(struct ui_browser *browser,
unsigned long nr_events = evsel->hists.stats.nr_events[PERF_RECORD_SAMPLE];
const char *ev_name = event_name(evsel);
char bf[256], unit;
const char *warn = " ";
size_t printed;
ui_browser__set_color(browser, current_entry ? HE_COLORSET_SELECTED :
HE_COLORSET_NORMAL);
nr_events = convert_unit(nr_events, &unit);
snprintf(bf, sizeof(bf), "%lu%c%s%s", nr_events,
unit, unit == ' ' ? "" : " ", ev_name);
slsmg_write_nstring(bf, browser->width);
printed = snprintf(bf, sizeof(bf), "%lu%c%s%s", nr_events,
unit, unit == ' ' ? "" : " ", ev_name);
slsmg_printf("%s", bf);
nr_events = evsel->hists.stats.nr_events[PERF_RECORD_LOST];
if (nr_events != 0) {
menu->lost_events = true;
if (!current_entry)
ui_browser__set_color(browser, HE_COLORSET_TOP);
nr_events = convert_unit(nr_events, &unit);
snprintf(bf, sizeof(bf), ": %ld%c%schunks LOST!", nr_events,
unit, unit == ' ' ? "" : " ");
warn = bf;
}
slsmg_write_nstring(warn, browser->width - printed);
if (current_entry)
menu->selection = evsel;
@@ -1105,6 +1137,11 @@ static int perf_evsel_menu__run(struct perf_evsel_menu *menu,
switch (key) {
case K_TIMER:
timer(arg);
if (!menu->lost_events_warned && menu->lost_events) {
ui_browser__warn_lost_events(&menu->b);
menu->lost_events_warned = true;
}
continue;
case K_RIGHT:
case K_ENTER: