lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Sat,  3 Apr 2010 22:40:50 -0300
From:	Arnaldo Carvalho de Melo <acme@...radead.org>
To:	Ingo Molnar <mingo@...e.hu>
Cc:	linux-kernel@...r.kernel.org,
	Arnaldo Carvalho de Melo <acme@...hat.com>,
	Avi Kivity <avi@...hat.com>,
	Frédéric Weisbecker <fweisbec@...il.com>,
	Mike Galbraith <efault@....de>,
	Peter Zijlstra <a.p.zijlstra@...llo.nl>,
	Paul Mackerras <paulus@...ba.org>
Subject: [PATCH 2/2] perf TUI: Add a "Zoom into COMM(PID) thread" and reverse operations

From: Arnaldo Carvalho de Melo <acme@...hat.com>

Now one can press the right arrow key and in addition to being able to
filter by DSO, filter out by thread too, or a combination of both
filters.

With this one can start collecting events for the whole system, then
focus on a subset of the collected data quickly.

Cc: Avi Kivity <avi@...hat.com>
Cc: Frédéric Weisbecker <fweisbec@...il.com>
Cc: Mike Galbraith <efault@....de>
Cc: Peter Zijlstra <a.p.zijlstra@...llo.nl>
Cc: Paul Mackerras <paulus@...ba.org>
LKML-Reference: <new-submission>
Signed-off-by: Arnaldo Carvalho de Melo <acme@...hat.com>
---
 tools/perf/util/newt.c |   82 +++++++++++++++++++++++++++++++++++++++++++-----
 tools/perf/util/sort.h |    9 ++++-
 2 files changed, 81 insertions(+), 10 deletions(-)

diff --git a/tools/perf/util/newt.c b/tools/perf/util/newt.c
index bbf725d..6d6e022 100644
--- a/tools/perf/util/newt.c
+++ b/tools/perf/util/newt.c
@@ -490,6 +490,11 @@ static int hist_browser__populate(struct hist_browser *self, struct rb_root *his
 	return 0;
 }
 
+enum hist_filter {
+	HIST_FILTER__DSO,
+	HIST_FILTER__THREAD,
+};
+
 static u64 hists__filter_by_dso(struct rb_root *hists, struct dso *dso,
 				u64 *session_total)
 {
@@ -502,10 +507,10 @@ static u64 hists__filter_by_dso(struct rb_root *hists, struct dso *dso,
 		struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
 
 		if (dso != NULL && (h->ms.map == NULL || h->ms.map->dso != dso)) {
-			h->filtered = true;
+			h->filtered |= (1 << HIST_FILTER__DSO);
 			continue;
 		}
-		h->filtered = false;
+		h->filtered &= ~(1 << HIST_FILTER__DSO);
 		++nr_hists;
 		*session_total += h->count;
 	}
@@ -513,12 +518,54 @@ static u64 hists__filter_by_dso(struct rb_root *hists, struct dso *dso,
 	return nr_hists;
 }
 
+static u64 hists__filter_by_thread(struct rb_root *hists, const struct thread *thread,
+				   u64 *session_total)
+{
+	struct rb_node *nd;
+	u64 nr_hists = 0;
+
+	*session_total = 0;
+
+	for (nd = rb_first(hists); nd; nd = rb_next(nd)) {
+		struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
+
+		if (thread != NULL && h->thread != thread) {
+			h->filtered |= (1 << HIST_FILTER__THREAD);
+			continue;
+		}
+		h->filtered &= ~(1 << HIST_FILTER__THREAD);
+		++nr_hists;
+		*session_total += h->count;
+	}
+
+	return nr_hists;
+}
+
+static struct thread *hist_browser__selected_thread(struct hist_browser *self)
+{
+	int *indexes;
+
+	if (!symbol_conf.use_callchain)
+		goto out;
+
+	indexes = newtCheckboxTreeFindItem(self->tree, (void *)self->selection);
+	if (indexes) {
+		bool is_hist_entry = indexes[1] == NEWT_ARG_LAST;
+		free(indexes);
+		if (is_hist_entry)
+			goto out;
+	}
+	return NULL;
+out:
+	return *(struct thread **)(self->selection + 1);
+}
+
 int perf_session__browse_hists(struct rb_root *hists, u64 nr_hists,
 			       u64 session_total, const char *helpline,
 			       const char *input_name)
 {
 	struct newtExitStruct es;
-	bool dso_filtered = false;
+	bool dso_filtered = false, thread_filtered = false;
 	int err = -1;
 	struct hist_browser *browser = hist_browser__new();
 
@@ -531,9 +578,10 @@ int perf_session__browse_hists(struct rb_root *hists, u64 nr_hists,
 		goto out;
 
 	while (1) {
+		const struct thread *thread;
 		char *options[16];
 		int nr_options = 0, choice = 0, i,
-		    annotate = -2, zoom_dso = -2;
+		    annotate = -2, zoom_dso = -2, zoom_thread = -2;
 
 		newtFormRun(browser->form, &es);
 		if (es.reason == NEWT_EXIT_HOTKEY) {
@@ -561,6 +609,13 @@ int perf_session__browse_hists(struct rb_root *hists, u64 nr_hists,
 			      browser->selection->map->dso->short_name)) > 0)
 			zoom_dso = nr_options++;
 
+		thread = hist_browser__selected_thread(browser);
+		if (thread != NULL &&
+		    asprintf(&options[nr_options], "Zoom %s %s(%d) thread",
+			     (thread_filtered ? "out of" : "into"),
+			     (thread->comm_set ?  thread->comm : ""), thread->pid) > 0)
+			zoom_thread = nr_options++;
+
 		options[nr_options++] = (char *)"Exit";
 
 		choice = popup_menu(nr_options, options);
@@ -570,6 +625,9 @@ int perf_session__browse_hists(struct rb_root *hists, u64 nr_hists,
 
 		if (choice == nr_options - 1)
 			break;
+
+		if (choice == -1)
+			continue;
 do_annotate:
 		if (choice == annotate) {
 			if (browser->selection->map->dso->origin == DSO__ORIG_KERNEL) {
@@ -581,13 +639,21 @@ do_annotate:
 			}
 			map_symbol__annotate_browser(browser->selection,
 						     input_name);
-		} if (choice == zoom_dso) {
-			hists__filter_by_dso(hists,
-					     dso_filtered ? NULL : browser->selection->map->dso,
-					     &session_total);
+		} else if (choice == zoom_dso) {
+			nr_hists = hists__filter_by_dso(hists,
+							(dso_filtered ? NULL :
+							 browser->selection->map->dso),
+							&session_total);
 			dso_filtered = !dso_filtered;
 			if (hist_browser__populate(browser, hists, nr_hists, session_total) < 0)
 				goto out;
+		} else if (choice == zoom_thread) {
+			nr_hists = hists__filter_by_thread(hists,
+							   (thread_filtered ? NULL : thread),
+							   &session_total);
+			thread_filtered = !thread_filtered;
+			if (hist_browser__populate(browser, hists, nr_hists, session_total) < 0)
+				goto out;
 		}
 	}
 	err = 0;
diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h
index dce79d3..2046ab7 100644
--- a/tools/perf/util/sort.h
+++ b/tools/perf/util/sort.h
@@ -44,11 +44,16 @@ extern enum sort_type sort__first_dimension;
 struct hist_entry {
 	struct rb_node		rb_node;
 	u64			count;
-	struct thread		*thread;
+	/*
+	 * XXX WARNING!
+	 * thread _has_ to come after ms, see
+	 * map_symbol__thread in util/newt.c
+	 */
 	struct map_symbol	ms;
+	struct thread		*thread;
 	u64			ip;
 	char			level;
-	bool			filtered;
+	u8			filtered;
 	struct symbol		*parent;
 	union {
 		unsigned long	  position;
-- 
1.6.2.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ