Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit dcc101d1 authored by Arnaldo Carvalho de Melo's avatar Arnaldo Carvalho de Melo
Browse files

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: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent eb489008
Loading
Loading
Loading
Loading
+17 −17
Original line number Original line Diff line number Diff line
@@ -250,7 +250,7 @@ static void __list_insert_active_sym(struct sym_entry *syme)
	list_add(&syme->node, &top.active_symbols);
	list_add(&syme->node, &top.active_symbols);
}
}


static void print_sym_table(struct perf_session *session)
static void print_sym_table(void)
{
{
	char bf[160];
	char bf[160];
	int printed = 0;
	int printed = 0;
@@ -270,10 +270,11 @@ static void print_sym_table(struct perf_session *session)


	printf("%-*.*s\n", win_width, win_width, graph_dotted_line);
	printf("%-*.*s\n", win_width, win_width, graph_dotted_line);


	if (session->hists.stats.total_lost != 0) {
	if (top.total_lost_warned != top.session->hists.stats.total_lost) {
		top.total_lost_warned = top.session->hists.stats.total_lost;
		color_fprintf(stdout, PERF_COLOR_RED, "WARNING:");
		color_fprintf(stdout, PERF_COLOR_RED, "WARNING:");
		printf(" LOST %" PRIu64 " events, Check IO/CPU overload\n",
		printf(" LOST %" PRIu64 " events, Check IO/CPU overload\n",
		       session->hists.stats.total_lost);
		       top.total_lost_warned);
	}
	}


	if (top.sym_filter_entry) {
	if (top.sym_filter_entry) {
@@ -474,7 +475,7 @@ static int key_mapped(int c)
	return 0;
	return 0;
}
}


static void handle_keypress(struct perf_session *session, int c)
static void handle_keypress(int c)
{
{
	if (!key_mapped(c)) {
	if (!key_mapped(c)) {
		struct pollfd stdin_poll = { .fd = 0, .events = POLLIN };
		struct pollfd stdin_poll = { .fd = 0, .events = POLLIN };
@@ -550,7 +551,7 @@ static void handle_keypress(struct perf_session *session, int c)
		case 'Q':
		case 'Q':
			printf("exiting.\n");
			printf("exiting.\n");
			if (dump_symtab)
			if (dump_symtab)
				perf_session__fprintf_dsos(session, stderr);
				perf_session__fprintf_dsos(top.session, stderr);
			exit(0);
			exit(0);
		case 's':
		case 's':
			prompt_symbol(&top.sym_filter_entry, "Enter details symbol");
			prompt_symbol(&top.sym_filter_entry, "Enter details symbol");
@@ -602,7 +603,6 @@ static void *display_thread(void *arg __used)
	struct pollfd stdin_poll = { .fd = 0, .events = POLLIN };
	struct pollfd stdin_poll = { .fd = 0, .events = POLLIN };
	struct termios tc, save;
	struct termios tc, save;
	int delay_msecs, c;
	int delay_msecs, c;
	struct perf_session *session = (struct perf_session *) arg;


	tcgetattr(0, &save);
	tcgetattr(0, &save);
	tc = save;
	tc = save;
@@ -617,13 +617,13 @@ static void *display_thread(void *arg __used)
	getc(stdin);
	getc(stdin);


	do {
	do {
		print_sym_table(session);
		print_sym_table();
	} while (!poll(&stdin_poll, 1, delay_msecs) == 1);
	} while (!poll(&stdin_poll, 1, delay_msecs) == 1);


	c = getc(stdin);
	c = getc(stdin);
	tcsetattr(0, TCSAFLUSH, &save);
	tcsetattr(0, TCSAFLUSH, &save);


	handle_keypress(session, c);
	handle_keypress(c);
	goto repeat;
	goto repeat;


	return NULL;
	return NULL;
@@ -935,27 +935,27 @@ static int __cmd_top(void)
	 * FIXME: perf_session__new should allow passing a O_MMAP, so that all this
	 * FIXME: perf_session__new should allow passing a O_MMAP, so that all this
	 * mmap reading, etc is encapsulated in it. Use O_WRONLY for now.
	 * mmap reading, etc is encapsulated in it. Use O_WRONLY for now.
	 */
	 */
	struct perf_session *session = perf_session__new(NULL, O_WRONLY, false, false, NULL);
	top.session = perf_session__new(NULL, O_WRONLY, false, false, NULL);
	if (session == NULL)
	if (top.session == NULL)
		return -ENOMEM;
		return -ENOMEM;


	if (top.target_tid != -1)
	if (top.target_tid != -1)
		perf_event__synthesize_thread_map(top.evlist->threads,
		perf_event__synthesize_thread_map(top.evlist->threads,
						  perf_event__process, session);
						  perf_event__process, top.session);
	else
	else
		perf_event__synthesize_threads(perf_event__process, session);
		perf_event__synthesize_threads(perf_event__process, top.session);


	start_counters(top.evlist);
	start_counters(top.evlist);
	session->evlist = top.evlist;
	top.session->evlist = top.evlist;
	perf_session__update_sample_type(session);
	perf_session__update_sample_type(top.session);


	/* Wait for a minimal set of events before starting the snapshot */
	/* Wait for a minimal set of events before starting the snapshot */
	poll(top.evlist->pollfd, top.evlist->nr_fds, 100);
	poll(top.evlist->pollfd, top.evlist->nr_fds, 100);


	perf_session__mmap_read(session);
	perf_session__mmap_read(top.session);


	if (pthread_create(&thread, NULL, (use_browser > 0 ? display_thread_tui :
	if (pthread_create(&thread, NULL, (use_browser > 0 ? display_thread_tui :
							     display_thread), session)) {
							     display_thread), NULL)) {
		printf("Could not create display thread.\n");
		printf("Could not create display thread.\n");
		exit(-1);
		exit(-1);
	}
	}
@@ -973,7 +973,7 @@ static int __cmd_top(void)
	while (1) {
	while (1) {
		u64 hits = top.samples;
		u64 hits = top.samples;


		perf_session__mmap_read(session);
		perf_session__mmap_read(top.session);


		if (hits == top.samples)
		if (hits == top.samples)
			ret = poll(top.evlist->pollfd, top.evlist->nr_fds, 100);
			ret = poll(top.evlist->pollfd, top.evlist->nr_fds, 100);
+3 −0
Original line number Original line Diff line number Diff line
@@ -10,6 +10,7 @@


struct perf_evlist;
struct perf_evlist;
struct perf_evsel;
struct perf_evsel;
struct perf_session;


struct sym_entry {
struct sym_entry {
	struct rb_node		rb_node;
	struct rb_node		rb_node;
@@ -38,6 +39,7 @@ struct perf_top {
	u64		   kernel_samples, us_samples;
	u64		   kernel_samples, us_samples;
	u64		   exact_samples;
	u64		   exact_samples;
	u64		   guest_us_samples, guest_kernel_samples;
	u64		   guest_us_samples, guest_kernel_samples;
	u64		   total_lost_warned;
	int		   print_entries, count_filter, delay_secs;
	int		   print_entries, count_filter, delay_secs;
	int		   display_weighted, freq, rb_entries;
	int		   display_weighted, freq, rb_entries;
	pid_t		   target_pid, target_tid;
	pid_t		   target_pid, target_tid;
@@ -45,6 +47,7 @@ struct perf_top {
	const char	   *cpu_list;
	const char	   *cpu_list;
	struct sym_entry   *sym_filter_entry;
	struct sym_entry   *sym_filter_entry;
	struct perf_evsel  *sym_evsel;
	struct perf_evsel  *sym_evsel;
	struct perf_session *session;
};
};


size_t perf_top__header_snprintf(struct perf_top *top, char *bf, size_t size);
size_t perf_top__header_snprintf(struct perf_top *top, char *bf, size_t size);
+24 −0
Original line number Original line Diff line number Diff line
@@ -11,10 +11,12 @@
#include "../helpline.h"
#include "../helpline.h"
#include "../libslang.h"
#include "../libslang.h"
#include "../util.h"
#include "../util.h"
#include "../ui.h"
#include "../../evlist.h"
#include "../../evlist.h"
#include "../../hist.h"
#include "../../hist.h"
#include "../../sort.h"
#include "../../sort.h"
#include "../../symbol.h"
#include "../../symbol.h"
#include "../../session.h"
#include "../../top.h"
#include "../../top.h"


struct perf_top_browser {
struct perf_top_browser {
@@ -143,6 +145,25 @@ static void perf_top_browser__annotate(struct perf_top_browser *browser)
	symbol__tui_annotate(sym, syme->map, 0, top->delay_secs * 1000);
	symbol__tui_annotate(sym, syme->map, 0, top->delay_secs * 1000);
}
}


static void perf_top_browser__warn_lost(struct perf_top_browser *browser)
{
	struct perf_top *top = browser->b.priv;
	char msg[128];
	int len;

	top->total_lost_warned = top->session->hists.stats.total_lost;
	pthread_mutex_lock(&ui__lock);
	ui_browser__set_color(&browser->b, HE_COLORSET_TOP);
	len = snprintf(msg, sizeof(msg),
		      " WARNING: LOST %" PRIu64 " events, Check IO/CPU overload",
		      top->total_lost_warned);
	if (len > browser->b.width)
		len = browser->b.width;
	SLsmg_gotorc(0, browser->b.width - len);
	slsmg_write_nstring(msg, len);
	pthread_mutex_unlock(&ui__lock);
}

static int perf_top_browser__run(struct perf_top_browser *browser)
static int perf_top_browser__run(struct perf_top_browser *browser)
{
{
	int key;
	int key;
@@ -174,6 +195,9 @@ static int perf_top_browser__run(struct perf_top_browser *browser)
			ui_browser__set_color(&browser->b, NEWT_COLORSET_ROOT);
			ui_browser__set_color(&browser->b, NEWT_COLORSET_ROOT);
			SLsmg_gotorc(0, 0);
			SLsmg_gotorc(0, 0);
			slsmg_write_nstring(title, browser->b.width);
			slsmg_write_nstring(title, browser->b.width);

			if (top->total_lost_warned != top->session->hists.stats.total_lost)
				perf_top_browser__warn_lost(browser);
			break;
			break;
		case 'a':
		case 'a':
		case NEWT_KEY_RIGHT:
		case NEWT_KEY_RIGHT: