linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/16] perf: kvm live mode
@ 2013-05-26  0:24 David Ahern
  2013-05-26  0:24 ` [PATCH 01/16] perf evlist: restore methods removed in earlier cleanup David Ahern
                   ` (15 more replies)
  0 siblings, 16 replies; 25+ messages in thread
From: David Ahern @ 2013-05-26  0:24 UTC (permalink / raw)
  To: linux-kernel
  Cc: acme, mingo, fweisbec, peterz, jolsa, namhyung, xiaoguangrong,
	runzhen, David Ahern

This version addresses all of the comments from the last review and
includes an enhancement from Runzhen Wang. I still need to add Ingo's
enhancements -- aliasing 'perf stat kvm' to 'perf kvm stat live', and
adding options to parallel top (--repeat <n>).

patchset can also be obtained from github.com/dsahern/linux,
perf-kvm-live-wip branch.

David Ahern (13):
  perf evlist: restore methods removed in earlier cleanup
  perf evlist: move tracepoint processing code to evlist.c
  perf evlist: add initialzation function for tracepoints
  perf session: export a few functions for event processing
  perf top: move CONSOLE_CLEAR to header file
  perf kvm: handle realloc failures
  perf kvm: split out tracepoints from record args
  perf stats: fix divide by 0 in variance
  perf stats: add max and min stats
  perf kvm: add live mode
  perf kvm: add min and max stats to display
  perf kvm: option to print events that exceed a threshold
  perf kvm: debug for missing vmexit/vmentry event

Runzhen Wang (3):
  perf kvm: reuse some code of perf_kvm__timerfd_create()
  perf kvm: move the prompt_integer() to /util/top.c
  perf kvm: set live mode refresh time dynamically

 tools/perf/builtin-kvm.c  |  723 ++++++++++++++++++++++++++++++++++++++++++---
 tools/perf/builtin-top.c  |   28 --
 tools/perf/util/evlist.c  |  128 ++++++++
 tools/perf/util/evlist.h  |   10 +
 tools/perf/util/header.c  |   44 ---
 tools/perf/util/session.c |   13 +-
 tools/perf/util/session.h |    7 +
 tools/perf/util/stat.c    |    8 +-
 tools/perf/util/stat.h    |    9 +
 tools/perf/util/top.c     |   30 ++
 tools/perf/util/top.h     |    3 +
 11 files changed, 881 insertions(+), 122 deletions(-)

-- 
1.7.10.1


^ permalink raw reply	[flat|nested] 25+ messages in thread

* [PATCH 01/16] perf evlist: restore methods removed in earlier cleanup
  2013-05-26  0:24 [PATCH 00/16] perf: kvm live mode David Ahern
@ 2013-05-26  0:24 ` David Ahern
  2013-05-26  0:24 ` [PATCH 02/16] perf evlist: move tracepoint processing code to evlist.c David Ahern
                   ` (14 subsequent siblings)
  15 siblings, 0 replies; 25+ messages in thread
From: David Ahern @ 2013-05-26  0:24 UTC (permalink / raw)
  To: linux-kernel
  Cc: acme, mingo, fweisbec, peterz, jolsa, namhyung, xiaoguangrong,
	runzhen, David Ahern

e60fc847 removed the perf_evlist__add_tracepoints and helpers, but
they are useful for kvm's upcoming live mode.

Signed-off-by: David Ahern <dsahern@gmail.com>
Cc: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Xiao Guangrong <xiaoguangrong@linux.vnet.ibm.com>
Cc: Runzhen Wang <runzhen@linux.vnet.ibm.com>
---
 tools/perf/util/evlist.c |   54 ++++++++++++++++++++++++++++++++++++++++++++++
 tools/perf/util/evlist.h |    3 +++
 2 files changed, 57 insertions(+)

diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index f7c7278..1cf14eb 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -195,6 +195,60 @@ int __perf_evlist__add_default_attrs(struct perf_evlist *evlist,
 	return perf_evlist__add_attrs(evlist, attrs, nr_attrs);
 }
 
+static int trace_event__id(const char *evname)
+{
+	char *filename, *colon;
+	int err = -1, fd;
+
+	if (asprintf(&filename, "%s/%s/id", tracing_events_path, evname) < 0)
+		return -1;
+
+	colon = strrchr(filename, ':');
+	if (colon != NULL)
+		*colon = '/';
+
+	fd = open(filename, O_RDONLY);
+	if (fd >= 0) {
+		char id[16];
+		if (read(fd, id, sizeof(id)) > 0)
+			err = atoi(id);
+		close(fd);
+	}
+
+	free(filename);
+	return err;
+}
+
+int perf_evlist__add_tracepoints(struct perf_evlist *evlist,
+				 const char * const tracepoints[],
+				 size_t nr_tracepoints)
+{
+	int err;
+	size_t i;
+	struct perf_event_attr *attrs = zalloc(nr_tracepoints * sizeof(*attrs));
+
+	if (attrs == NULL)
+		return -1;
+
+	for (i = 0; i < nr_tracepoints; i++) {
+		err = trace_event__id(tracepoints[i]);
+
+		if (err < 0)
+			goto out_free_attrs;
+
+		attrs[i].type	       = PERF_TYPE_TRACEPOINT;
+		attrs[i].config	       = err;
+		attrs[i].sample_type   = (PERF_SAMPLE_RAW | PERF_SAMPLE_TIME |
+					  PERF_SAMPLE_CPU | PERF_SAMPLE_PERIOD);
+		attrs[i].sample_period = 1;
+	}
+
+	err = perf_evlist__add_attrs(evlist, attrs, nr_tracepoints);
+out_free_attrs:
+	free(attrs);
+	return err;
+}
+
 struct perf_evsel *
 perf_evlist__find_tracepoint_by_id(struct perf_evlist *evlist, int id)
 {
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h
index 0583d36..a5b1880 100644
--- a/tools/perf/util/evlist.h
+++ b/tools/perf/util/evlist.h
@@ -59,6 +59,9 @@ void perf_evlist__add(struct perf_evlist *evlist, struct perf_evsel *entry);
 int perf_evlist__add_default(struct perf_evlist *evlist);
 int __perf_evlist__add_default_attrs(struct perf_evlist *evlist,
 				     struct perf_event_attr *attrs, size_t nr_attrs);
+int perf_evlist__add_tracepoints(struct perf_evlist *evlist,
+				 const char * const tracepoints[],
+				 size_t nr_tracepoints);
 
 #define perf_evlist__add_default_attrs(evlist, array) \
 	__perf_evlist__add_default_attrs(evlist, array, ARRAY_SIZE(array))
-- 
1.7.10.1


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 02/16] perf evlist: move tracepoint processing code to evlist.c
  2013-05-26  0:24 [PATCH 00/16] perf: kvm live mode David Ahern
  2013-05-26  0:24 ` [PATCH 01/16] perf evlist: restore methods removed in earlier cleanup David Ahern
@ 2013-05-26  0:24 ` David Ahern
  2013-05-26  0:24 ` [PATCH 03/16 v2] perf evlist: add initialzation function for tracepoints David Ahern
                   ` (13 subsequent siblings)
  15 siblings, 0 replies; 25+ messages in thread
From: David Ahern @ 2013-05-26  0:24 UTC (permalink / raw)
  To: linux-kernel
  Cc: acme, mingo, fweisbec, peterz, jolsa, namhyung, xiaoguangrong,
	runzhen, David Ahern

Per function names they are more aligned with the evlist code than
the header code. Export perf_evlist__prepare_tracepoint_events
in the process.

Code move only; no functional changes.

Signed-off-by: David Ahern <dsahern@gmail.com>
Cc: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Xiao Guangrong <xiaoguangrong@linux.vnet.ibm.com>
Cc: Runzhen Wang <runzhen@linux.vnet.ibm.com>
---
 tools/perf/util/evlist.c  |   39 +++++++++++++++++++++++++++++++++++++++
 tools/perf/util/evlist.h  |    4 ++++
 tools/perf/util/header.c  |   44 --------------------------------------------
 tools/perf/util/session.c |    1 -
 4 files changed, 43 insertions(+), 45 deletions(-)

diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index 1cf14eb..72b9551 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -195,6 +195,45 @@ int __perf_evlist__add_default_attrs(struct perf_evlist *evlist,
 	return perf_evlist__add_attrs(evlist, attrs, nr_attrs);
 }
 
+static int perf_evsel__prepare_tracepoint_event(struct perf_evsel *evsel,
+						struct pevent *pevent)
+{
+	struct event_format *event;
+	char bf[128];
+
+	/* already prepared */
+	if (evsel->tp_format)
+		return 0;
+
+	event = pevent_find_event(pevent, evsel->attr.config);
+	if (event == NULL)
+		return -1;
+
+	if (!evsel->name) {
+		snprintf(bf, sizeof(bf), "%s:%s", event->system, event->name);
+		evsel->name = strdup(bf);
+		if (evsel->name == NULL)
+			return -1;
+	}
+
+	evsel->tp_format = event;
+	return 0;
+}
+
+int perf_evlist__prepare_tracepoint_events(struct perf_evlist *evlist,
+						  struct pevent *pevent)
+{
+	struct perf_evsel *pos;
+
+	list_for_each_entry(pos, &evlist->entries, node) {
+		if (pos->attr.type == PERF_TYPE_TRACEPOINT &&
+		    perf_evsel__prepare_tracepoint_event(pos, pevent))
+			return -1;
+	}
+
+	return 0;
+}
+
 static int trace_event__id(const char *evname)
 {
 	char *filename, *colon;
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h
index a5b1880..c2cf183 100644
--- a/tools/perf/util/evlist.h
+++ b/tools/perf/util/evlist.h
@@ -5,6 +5,7 @@
 #include <stdio.h>
 #include "../perf.h"
 #include "event.h"
+#include "event-parse.h"
 #include "evsel.h"
 #include "util.h"
 #include <unistd.h>
@@ -59,6 +60,9 @@ void perf_evlist__add(struct perf_evlist *evlist, struct perf_evsel *entry);
 int perf_evlist__add_default(struct perf_evlist *evlist);
 int __perf_evlist__add_default_attrs(struct perf_evlist *evlist,
 				     struct perf_event_attr *attrs, size_t nr_attrs);
+int perf_evlist__prepare_tracepoint_events(struct perf_evlist *evlist,
+					   struct pevent *pevent);
+
 int perf_evlist__add_tracepoints(struct perf_evlist *evlist,
 				 const char * const tracepoints[],
 				 size_t nr_tracepoints);
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index 326068a..0e04f7ae 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -2740,50 +2740,6 @@ static int read_attr(int fd, struct perf_header *ph,
 	return ret <= 0 ? -1 : 0;
 }
 
-static int perf_evsel__prepare_tracepoint_event(struct perf_evsel *evsel,
-						struct pevent *pevent)
-{
-	struct event_format *event;
-	char bf[128];
-
-	/* already prepared */
-	if (evsel->tp_format)
-		return 0;
-
-	if (pevent == NULL) {
-		pr_debug("broken or missing trace data\n");
-		return -1;
-	}
-
-	event = pevent_find_event(pevent, evsel->attr.config);
-	if (event == NULL)
-		return -1;
-
-	if (!evsel->name) {
-		snprintf(bf, sizeof(bf), "%s:%s", event->system, event->name);
-		evsel->name = strdup(bf);
-		if (evsel->name == NULL)
-			return -1;
-	}
-
-	evsel->tp_format = event;
-	return 0;
-}
-
-static int perf_evlist__prepare_tracepoint_events(struct perf_evlist *evlist,
-						  struct pevent *pevent)
-{
-	struct perf_evsel *pos;
-
-	list_for_each_entry(pos, &evlist->entries, node) {
-		if (pos->attr.type == PERF_TYPE_TRACEPOINT &&
-		    perf_evsel__prepare_tracepoint_event(pos, pevent))
-			return -1;
-	}
-
-	return 0;
-}
-
 int perf_session__read_header(struct perf_session *session, int fd)
 {
 	struct perf_header *header = &session->header;
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index cf1fe01..7e2c4c7 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -12,7 +12,6 @@
 #include "sort.h"
 #include "util.h"
 #include "cpumap.h"
-#include "event-parse.h"
 #include "perf_regs.h"
 #include "vdso.h"
 
-- 
1.7.10.1


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 03/16 v2] perf evlist: add initialzation function for tracepoints
  2013-05-26  0:24 [PATCH 00/16] perf: kvm live mode David Ahern
  2013-05-26  0:24 ` [PATCH 01/16] perf evlist: restore methods removed in earlier cleanup David Ahern
  2013-05-26  0:24 ` [PATCH 02/16] perf evlist: move tracepoint processing code to evlist.c David Ahern
@ 2013-05-26  0:24 ` David Ahern
  2013-05-26  0:24 ` [PATCH 04/16 v2] perf session: export a few functions for event processing David Ahern
                   ` (12 subsequent siblings)
  15 siblings, 0 replies; 25+ messages in thread
From: David Ahern @ 2013-05-26  0:24 UTC (permalink / raw)
  To: linux-kernel
  Cc: acme, mingo, fweisbec, peterz, jolsa, namhyung, xiaoguangrong,
	runzhen, David Ahern

Handles initializations typically done as part of processing the file
header and HEADER_TRACING_DATA event.

v2: close fd as noticed by Namhyung.

Signed-off-by: David Ahern <dsahern@gmail.com>
Cc: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Xiao Guangrong <xiaoguangrong@linux.vnet.ibm.com>
Cc: Runzhen Wang <runzhen@linux.vnet.ibm.com>
---
 tools/perf/util/evlist.c |   35 +++++++++++++++++++++++++++++++++++
 tools/perf/util/evlist.h |    3 +++
 2 files changed, 38 insertions(+)

diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index 72b9551..b686411 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -14,6 +14,7 @@
 #include "target.h"
 #include "evlist.h"
 #include "evsel.h"
+#include "trace-event.h"
 #include <unistd.h>
 
 #include "parse-events.h"
@@ -234,6 +235,40 @@ int perf_evlist__prepare_tracepoint_events(struct perf_evlist *evlist,
 	return 0;
 }
 
+int perf_evlist__trace_init(struct perf_evlist *evlist,
+			    struct perf_session *session)
+{
+	struct tracing_data *tdata;
+	char temp_file[] = "/tmp/perf-XXXXXXXX";
+	int fd;
+	int rc = 0;
+
+	fd = mkstemp(temp_file);
+	if (fd < 0) {
+		pr_err("mkstemp failed\n");
+		return -1;
+	}
+	unlink(temp_file);
+
+	tdata = tracing_data_get(&evlist->entries, fd, false);
+	if (!tdata) {
+		rc = -1;
+		goto out;
+	}
+
+	lseek(fd, 0, SEEK_SET);
+	(void) trace_report(fd, &session->pevent, false);
+	tracing_data_put(tdata);
+
+	rc = perf_evlist__prepare_tracepoint_events(evlist, session->pevent);
+
+out:
+	close(fd);
+
+	return rc;
+}
+
+
 static int trace_event__id(const char *evname)
 {
 	char *filename, *colon;
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h
index c2cf183..c579f3d 100644
--- a/tools/perf/util/evlist.h
+++ b/tools/perf/util/evlist.h
@@ -8,6 +8,7 @@
 #include "event-parse.h"
 #include "evsel.h"
 #include "util.h"
+#include "session.h"
 #include <unistd.h>
 
 struct pollfd;
@@ -66,6 +67,8 @@ int perf_evlist__prepare_tracepoint_events(struct perf_evlist *evlist,
 int perf_evlist__add_tracepoints(struct perf_evlist *evlist,
 				 const char * const tracepoints[],
 				 size_t nr_tracepoints);
+int perf_evlist__trace_init(struct perf_evlist *evlist,
+			    struct perf_session *session);
 
 #define perf_evlist__add_default_attrs(evlist, array) \
 	__perf_evlist__add_default_attrs(evlist, array, ARRAY_SIZE(array))
-- 
1.7.10.1


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 04/16 v2] perf session: export a few functions for event processing
  2013-05-26  0:24 [PATCH 00/16] perf: kvm live mode David Ahern
                   ` (2 preceding siblings ...)
  2013-05-26  0:24 ` [PATCH 03/16 v2] perf evlist: add initialzation function for tracepoints David Ahern
@ 2013-05-26  0:24 ` David Ahern
  2013-05-26  0:24 ` [PATCH 05/16] perf top: move CONSOLE_CLEAR to header file David Ahern
                   ` (11 subsequent siblings)
  15 siblings, 0 replies; 25+ messages in thread
From: David Ahern @ 2013-05-26  0:24 UTC (permalink / raw)
  To: linux-kernel
  Cc: acme, mingo, fweisbec, peterz, jolsa, namhyung, xiaoguangrong,
	runzhen, David Ahern

Allows kvm live mode to reuse the event processing and ordered samples
processing used by the perf-report path.

v2: removed flush_sample_queue as noticed by Jiri

Signed-off-by: David Ahern <dsahern@gmail.com>
Cc: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Xiao Guangrong <xiaoguangrong@linux.vnet.ibm.com>
Cc: Runzhen Wang <runzhen@linux.vnet.ibm.com>
---
 tools/perf/util/session.c |   12 ++++++------
 tools/perf/util/session.h |    7 +++++++
 2 files changed, 13 insertions(+), 6 deletions(-)

diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 7e2c4c7..8524540 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -248,7 +248,7 @@ static int process_finished_round(struct perf_tool *tool,
 				  union perf_event *event,
 				  struct perf_session *session);
 
-static void perf_tool__fill_defaults(struct perf_tool *tool)
+void perf_tool__fill_defaults(struct perf_tool *tool)
 {
 	if (tool->sample == NULL)
 		tool->sample = process_event_sample_stub;
@@ -495,7 +495,7 @@ static int perf_session_deliver_event(struct perf_session *session,
 				      u64 file_offset);
 
 static int flush_sample_queue(struct perf_session *s,
-			       struct perf_tool *tool)
+		       struct perf_tool *tool)
 {
 	struct ordered_samples *os = &s->ordered_samples;
 	struct list_head *head = &os->samples;
@@ -948,10 +948,10 @@ static void event_swap(union perf_event *event, bool sample_id_all)
 		swap(event, sample_id_all);
 }
 
-static int perf_session__process_event(struct perf_session *session,
-				       union perf_event *event,
-				       struct perf_tool *tool,
-				       u64 file_offset)
+int perf_session__process_event(struct perf_session *session,
+				union perf_event *event,
+				struct perf_tool *tool,
+				u64 file_offset)
 {
 	struct perf_sample sample;
 	int ret;
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h
index 6b51d47..d875933 100644
--- a/tools/perf/util/session.h
+++ b/tools/perf/util/session.h
@@ -58,6 +58,13 @@ int __perf_session__process_events(struct perf_session *self,
 int perf_session__process_events(struct perf_session *self,
 				 struct perf_tool *tool);
 
+int perf_session__process_event(struct perf_session *session,
+				union perf_event *event,
+				struct perf_tool *tool,
+				u64 file_offset);
+
+void perf_tool__fill_defaults(struct perf_tool *tool);
+
 int perf_session__resolve_callchain(struct perf_session *self, struct perf_evsel *evsel,
 				    struct thread *thread,
 				    struct ip_callchain *chain,
-- 
1.7.10.1


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 05/16] perf top: move CONSOLE_CLEAR to header file
  2013-05-26  0:24 [PATCH 00/16] perf: kvm live mode David Ahern
                   ` (3 preceding siblings ...)
  2013-05-26  0:24 ` [PATCH 04/16 v2] perf session: export a few functions for event processing David Ahern
@ 2013-05-26  0:24 ` David Ahern
  2013-05-26  0:24 ` [PATCH 06/16] perf kvm: handle realloc failures David Ahern
                   ` (10 subsequent siblings)
  15 siblings, 0 replies; 25+ messages in thread
From: David Ahern @ 2013-05-26  0:24 UTC (permalink / raw)
  To: linux-kernel
  Cc: acme, mingo, fweisbec, peterz, jolsa, namhyung, xiaoguangrong,
	runzhen, David Ahern

For use with kvm-live mode.

Signed-off-by: David Ahern <dsahern@gmail.com>
Cc: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Xiao Guangrong <xiaoguangrong@linux.vnet.ibm.com>
Cc: Runzhen Wang <runzhen@linux.vnet.ibm.com>
---
 tools/perf/builtin-top.c |    2 --
 tools/perf/util/top.h    |    2 ++
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index f036af9..495171a 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -237,8 +237,6 @@ out_unlock:
 	pthread_mutex_unlock(&notes->lock);
 }
 
-static const char		CONSOLE_CLEAR[] = "^[[H^[[2J";
-
 static struct hist_entry *perf_evsel__add_hist_entry(struct perf_evsel *evsel,
 						     struct addr_location *al,
 						     struct perf_sample *sample)
diff --git a/tools/perf/util/top.h b/tools/perf/util/top.h
index df46be9..b554ffc 100644
--- a/tools/perf/util/top.h
+++ b/tools/perf/util/top.h
@@ -39,6 +39,8 @@ struct perf_top {
 	float		   min_percent;
 };
 
+#define CONSOLE_CLEAR "^[[H^[[2J"
+
 size_t perf_top__header_snprintf(struct perf_top *top, char *bf, size_t size);
 void perf_top__reset_sample_counters(struct perf_top *top);
 #endif /* __PERF_TOP_H */
-- 
1.7.10.1


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 06/16] perf kvm: handle realloc failures
  2013-05-26  0:24 [PATCH 00/16] perf: kvm live mode David Ahern
                   ` (4 preceding siblings ...)
  2013-05-26  0:24 ` [PATCH 05/16] perf top: move CONSOLE_CLEAR to header file David Ahern
@ 2013-05-26  0:24 ` David Ahern
  2013-05-31 11:49   ` [tip:perf/core] perf kvm: Handle " tip-bot for David Ahern
  2013-05-26  0:24 ` [PATCH 07/16] perf kvm: split out tracepoints from record args David Ahern
                   ` (9 subsequent siblings)
  15 siblings, 1 reply; 25+ messages in thread
From: David Ahern @ 2013-05-26  0:24 UTC (permalink / raw)
  To: linux-kernel
  Cc: acme, mingo, fweisbec, peterz, jolsa, namhyung, xiaoguangrong,
	runzhen, David Ahern

Save previous pointer and free on failure.

Signed-off-by: David Ahern <dsahern@gmail.com>
Cc: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Xiao Guangrong <xiaoguangrong@linux.vnet.ibm.com>
Cc: Runzhen Wang <runzhen@linux.vnet.ibm.com>
---
 tools/perf/builtin-kvm.c |    3 +++
 1 file changed, 3 insertions(+)

diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c
index 533501e..24b78ae 100644
--- a/tools/perf/builtin-kvm.c
+++ b/tools/perf/builtin-kvm.c
@@ -328,6 +328,7 @@ static int kvm_events_hash_fn(u64 key)
 static bool kvm_event_expand(struct kvm_event *event, int vcpu_id)
 {
 	int old_max_vcpu = event->max_vcpu;
+	void *prev;
 
 	if (vcpu_id < event->max_vcpu)
 		return true;
@@ -335,9 +336,11 @@ static bool kvm_event_expand(struct kvm_event *event, int vcpu_id)
 	while (event->max_vcpu <= vcpu_id)
 		event->max_vcpu += DEFAULT_VCPU_NUM;
 
+	prev = event->vcpu;
 	event->vcpu = realloc(event->vcpu,
 			      event->max_vcpu * sizeof(*event->vcpu));
 	if (!event->vcpu) {
+		free(prev);
 		pr_err("Not enough memory\n");
 		return false;
 	}
-- 
1.7.10.1


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 07/16] perf kvm: split out tracepoints from record args
  2013-05-26  0:24 [PATCH 00/16] perf: kvm live mode David Ahern
                   ` (5 preceding siblings ...)
  2013-05-26  0:24 ` [PATCH 06/16] perf kvm: handle realloc failures David Ahern
@ 2013-05-26  0:24 ` David Ahern
  2013-05-26  0:24 ` [PATCH 08/16] perf stats: fix divide by 0 in variance David Ahern
                   ` (8 subsequent siblings)
  15 siblings, 0 replies; 25+ messages in thread
From: David Ahern @ 2013-05-26  0:24 UTC (permalink / raw)
  To: linux-kernel
  Cc: acme, mingo, fweisbec, peterz, jolsa, namhyung, xiaoguangrong,
	runzhen, David Ahern

Needed by kvm live command. Make record_args a local while we are
messing with the args.

Signed-off-by: David Ahern <dsahern@gmail.com>
Cc: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Xiao Guangrong <xiaoguangrong@linux.vnet.ibm.com>
Cc: Runzhen Wang <runzhen@linux.vnet.ibm.com>
---
 tools/perf/builtin-kvm.c |   30 +++++++++++++++++++-----------
 1 file changed, 19 insertions(+), 11 deletions(-)

diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c
index 24b78ae..7d14a3a 100644
--- a/tools/perf/builtin-kvm.c
+++ b/tools/perf/builtin-kvm.c
@@ -801,16 +801,11 @@ exit:
 	return ret;
 }
 
-static const char * const record_args[] = {
-	"record",
-	"-R",
-	"-f",
-	"-m", "1024",
-	"-c", "1",
-	"-e", "kvm:kvm_entry",
-	"-e", "kvm:kvm_exit",
-	"-e", "kvm:kvm_mmio",
-	"-e", "kvm:kvm_pio",
+static const char * const kvm_events_tp[] = {
+	"kvm:kvm_entry",
+	"kvm:kvm_exit",
+	"kvm:kvm_mmio",
+	"kvm:kvm_pio",
 };
 
 #define STRDUP_FAIL_EXIT(s)		\
@@ -826,8 +821,16 @@ kvm_events_record(struct perf_kvm_stat *kvm, int argc, const char **argv)
 {
 	unsigned int rec_argc, i, j;
 	const char **rec_argv;
+	const char * const record_args[] = {
+		"record",
+		"-R",
+		"-f",
+		"-m", "1024",
+		"-c", "1",
+	};
 
-	rec_argc = ARRAY_SIZE(record_args) + argc + 2;
+	rec_argc = ARRAY_SIZE(record_args) + argc + 2 +
+		   2 * ARRAY_SIZE(kvm_events_tp);
 	rec_argv = calloc(rec_argc + 1, sizeof(char *));
 
 	if (rec_argv == NULL)
@@ -836,6 +839,11 @@ kvm_events_record(struct perf_kvm_stat *kvm, int argc, const char **argv)
 	for (i = 0; i < ARRAY_SIZE(record_args); i++)
 		rec_argv[i] = STRDUP_FAIL_EXIT(record_args[i]);
 
+	for (j = 0; j < ARRAY_SIZE(kvm_events_tp); j++) {
+		rec_argv[i++] = "-e";
+		rec_argv[i++] = STRDUP_FAIL_EXIT(kvm_events_tp[j]);
+	}
+
 	rec_argv[i++] = STRDUP_FAIL_EXIT("-o");
 	rec_argv[i++] = STRDUP_FAIL_EXIT(kvm->file_name);
 
-- 
1.7.10.1


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 08/16] perf stats: fix divide by 0 in variance
  2013-05-26  0:24 [PATCH 00/16] perf: kvm live mode David Ahern
                   ` (6 preceding siblings ...)
  2013-05-26  0:24 ` [PATCH 07/16] perf kvm: split out tracepoints from record args David Ahern
@ 2013-05-26  0:24 ` David Ahern
  2013-05-31 11:51   ` [tip:perf/core] perf stats: Fix " tip-bot for David Ahern
  2013-05-26  0:24 ` [PATCH 09/16] perf stats: add max and min stats David Ahern
                   ` (7 subsequent siblings)
  15 siblings, 1 reply; 25+ messages in thread
From: David Ahern @ 2013-05-26  0:24 UTC (permalink / raw)
  To: linux-kernel
  Cc: acme, mingo, fweisbec, peterz, jolsa, namhyung, xiaoguangrong,
	runzhen, David Ahern

Number of samples needs to be greater 1 to have a variance.
Fixes nan% in perf-kvm-live output.

Signed-off-by: David Ahern <dsahern@gmail.com>
Cc: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Xiao Guangrong <xiaoguangrong@linux.vnet.ibm.com>
Cc: Runzhen Wang <runzhen@linux.vnet.ibm.com>
---
 tools/perf/util/stat.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c
index 2374212..7c59c28 100644
--- a/tools/perf/util/stat.c
+++ b/tools/perf/util/stat.c
@@ -37,7 +37,7 @@ double stddev_stats(struct stats *stats)
 {
 	double variance, variance_mean;
 
-	if (!stats->n)
+	if (stats->n < 2)
 		return 0.0;
 
 	variance = stats->M2 / (stats->n - 1);
-- 
1.7.10.1


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 09/16] perf stats: add max and min stats
  2013-05-26  0:24 [PATCH 00/16] perf: kvm live mode David Ahern
                   ` (7 preceding siblings ...)
  2013-05-26  0:24 ` [PATCH 08/16] perf stats: fix divide by 0 in variance David Ahern
@ 2013-05-26  0:24 ` David Ahern
  2013-05-26  0:24 ` [PATCH 10/16 v2] perf kvm: add live mode David Ahern
                   ` (6 subsequent siblings)
  15 siblings, 0 replies; 25+ messages in thread
From: David Ahern @ 2013-05-26  0:24 UTC (permalink / raw)
  To: linux-kernel
  Cc: acme, mingo, fweisbec, peterz, jolsa, namhyung, xiaoguangrong,
	runzhen, David Ahern

Need an initialization function to set min to -1 to
differentiate from an actual min of 0.

Signed-off-by: David Ahern <dsahern@gmail.com>
Cc: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Xiao Guangrong <xiaoguangrong@linux.vnet.ibm.com>
Cc: Runzhen Wang <runzhen@linux.vnet.ibm.com>
---
 tools/perf/util/stat.c |    6 ++++++
 tools/perf/util/stat.h |    9 +++++++++
 2 files changed, 15 insertions(+)

diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c
index 7c59c28..6506b3d 100644
--- a/tools/perf/util/stat.c
+++ b/tools/perf/util/stat.c
@@ -10,6 +10,12 @@ void update_stats(struct stats *stats, u64 val)
 	delta = val - stats->mean;
 	stats->mean += delta / stats->n;
 	stats->M2 += delta*(val - stats->mean);
+
+	if (val > stats->max)
+		stats->max = val;
+
+	if (val < stats->min)
+		stats->min = val;
 }
 
 double avg_stats(struct stats *stats)
diff --git a/tools/perf/util/stat.h b/tools/perf/util/stat.h
index 588367c..ae8ccd7 100644
--- a/tools/perf/util/stat.h
+++ b/tools/perf/util/stat.h
@@ -6,6 +6,7 @@
 struct stats
 {
 	double n, mean, M2;
+	u64 max, min;
 };
 
 void update_stats(struct stats *stats, u64 val);
@@ -13,4 +14,12 @@ double avg_stats(struct stats *stats);
 double stddev_stats(struct stats *stats);
 double rel_stddev_stats(double stddev, double avg);
 
+static inline void init_stats(struct stats *stats)
+{
+	stats->n    = 0.0;
+	stats->mean = 0.0;
+	stats->M2   = 0.0;
+	stats->min  = (u64) -1;
+	stats->max  = 0;
+}
 #endif
-- 
1.7.10.1


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 10/16 v2] perf kvm: add live mode
  2013-05-26  0:24 [PATCH 00/16] perf: kvm live mode David Ahern
                   ` (8 preceding siblings ...)
  2013-05-26  0:24 ` [PATCH 09/16] perf stats: add max and min stats David Ahern
@ 2013-05-26  0:24 ` David Ahern
  2013-05-26  0:24 ` [PATCH 11/16] perf kvm: add min and max stats to display David Ahern
                   ` (5 subsequent siblings)
  15 siblings, 0 replies; 25+ messages in thread
From: David Ahern @ 2013-05-26  0:24 UTC (permalink / raw)
  To: linux-kernel
  Cc: acme, mingo, fweisbec, peterz, jolsa, namhyung, xiaoguangrong,
	runzhen, David Ahern

perf kvm stat currently requires back to back record and report
commands to see stats. e.g,.

  perf kvm stat record -p $pid -- sleep 1
  perf kvm stat report

This is inconvenvient for on box monitoring of a VM. This patch
introduces a 'live' mode that in effect combines the record plus
report into one command. e.g., to monitor a single VM:

  perf kvm stat live -p $pid

or all VMs:

  perf kvm stat live

Same stats options for the record+report path work with the live mode.
Display rate defaults to 1 second and can be changed using the -d option.

v2:
removed ABSTIME arg from timerfd_settime as mentioned by Namhyung
only call perf_kvm__handle_stdin when poll returns activity.

Signed-off-by: David Ahern <dsahern@gmail.com>
Cc: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Xiao Guangrong <xiaoguangrong@linux.vnet.ibm.com>
Cc: Runzhen Wang <runzhen@linux.vnet.ibm.com>
---
 tools/perf/builtin-kvm.c |  603 ++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 577 insertions(+), 26 deletions(-)

diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c
index 7d14a3a..15fdf54 100644
--- a/tools/perf/builtin-kvm.c
+++ b/tools/perf/builtin-kvm.c
@@ -2,6 +2,7 @@
 #include "perf.h"
 
 #include "util/evsel.h"
+#include "util/evlist.h"
 #include "util/util.h"
 #include "util/cache.h"
 #include "util/symbol.h"
@@ -15,9 +16,12 @@
 #include <lk/debugfs.h>
 #include "util/tool.h"
 #include "util/stat.h"
+#include "util/top.h"
 
 #include <sys/prctl.h>
+#include <sys/timerfd.h>
 
+#include <termios.h>
 #include <semaphore.h>
 #include <pthread.h>
 #include <math.h>
@@ -82,6 +86,8 @@ struct exit_reasons_table {
 
 struct perf_kvm_stat {
 	struct perf_tool    tool;
+	struct perf_record_opts opts;
+	struct perf_evlist  *evlist;
 	struct perf_session *session;
 
 	const char *file_name;
@@ -96,10 +102,16 @@ struct perf_kvm_stat {
 	struct kvm_events_ops *events_ops;
 	key_cmp_fun compare;
 	struct list_head kvm_events_cache[EVENTS_CACHE_SIZE];
+
 	u64 total_time;
 	u64 total_count;
+	u64 lost_events;
 
 	struct rb_root result;
+
+	int timerfd;
+	unsigned int display_time;
+	bool live;
 };
 
 
@@ -320,6 +332,23 @@ static void init_kvm_event_record(struct perf_kvm_stat *kvm)
 		INIT_LIST_HEAD(&kvm->kvm_events_cache[i]);
 }
 
+static void clear_events_cache_stats(struct list_head *kvm_events_cache)
+{
+	struct list_head *head;
+	struct kvm_event *event;
+	unsigned int i;
+
+	for (i = 0; i < EVENTS_CACHE_SIZE; i++) {
+		head = &kvm_events_cache[i];
+		list_for_each_entry(event, head, hash_entry) {
+			/* reset stats for event */
+			memset(&event->total, 0, sizeof(event->total));
+			memset(event->vcpu, 0,
+			       event->max_vcpu * sizeof(*event->vcpu));
+		}
+	}
+}
+
 static int kvm_events_hash_fn(u64 key)
 {
 	return key & (EVENTS_CACHE_SIZE - 1);
@@ -472,7 +501,11 @@ static bool handle_end_event(struct perf_kvm_stat *kvm,
 	vcpu_record->last_event = NULL;
 	vcpu_record->start_time = 0;
 
-	BUG_ON(timestamp < time_begin);
+	/* seems to happen once in a while during live mode */
+	if (timestamp < time_begin) {
+		pr_debug("End time before begin time; skipping event.\n");
+		return true;
+	}
 
 	time_diff = timestamp - time_begin;
 	return update_kvm_event(event, vcpu, time_diff);
@@ -639,24 +672,60 @@ static struct kvm_event *pop_from_result(struct rb_root *result)
 	return container_of(node, struct kvm_event, rb);
 }
 
-static void print_vcpu_info(int vcpu)
+static void print_vcpu_info(struct perf_kvm_stat *kvm)
 {
+	int vcpu = kvm->trace_vcpu;
+
 	pr_info("Analyze events for ");
 
+	if (kvm->live) {
+		if (kvm->opts.target.system_wide)
+			pr_info("all VMs, ");
+		else if (kvm->opts.target.pid)
+			pr_info("pid(s) %s, ", kvm->opts.target.pid);
+		else if (kvm->opts.target.tid)
+			pr_info("tid(s) %s, ", kvm->opts.target.tid);
+		else if (kvm->opts.target.cpu_list)
+			pr_info("host cpu(s) %s, ", kvm->opts.target.cpu_list);
+		else
+			pr_info("dazed and confused on what is monitored, ");
+	}
+
 	if (vcpu == -1)
 		pr_info("all VCPUs:\n\n");
 	else
 		pr_info("VCPU %d:\n\n", vcpu);
 }
 
+static void show_timeofday(void)
+{
+	char date[64];
+	struct timeval tv;
+	struct tm ltime;
+
+	gettimeofday(&tv, NULL);
+	if (localtime_r(&tv.tv_sec, &ltime)) {
+		strftime(date, sizeof(date), "%H:%M:%S", &ltime);
+		pr_info("%s.%06ld", date, tv.tv_usec);
+	} else
+		pr_info("00:00:00.000000");
+
+	return;
+}
+
 static void print_result(struct perf_kvm_stat *kvm)
 {
 	char decode[20];
 	struct kvm_event *event;
 	int vcpu = kvm->trace_vcpu;
 
+	if (kvm->live) {
+		puts(CONSOLE_CLEAR);
+		show_timeofday();
+	}
+
 	pr_info("\n\n");
-	print_vcpu_info(vcpu);
+	print_vcpu_info(kvm);
 	pr_info("%20s ", kvm->events_ops->name);
 	pr_info("%10s ", "Samples");
 	pr_info("%9s ", "Samples%");
@@ -683,6 +752,20 @@ static void print_result(struct perf_kvm_stat *kvm)
 
 	pr_info("\nTotal Samples:%" PRIu64 ", Total events handled time:%.2fus.\n\n",
 		kvm->total_count, kvm->total_time / 1e3);
+
+	if (kvm->lost_events)
+		pr_info("\nLost events: %" PRIu64 "\n\n", kvm->lost_events);
+}
+
+static int process_lost_event(struct perf_tool *tool,
+			      union perf_event *event __maybe_unused,
+			      struct perf_sample *sample __maybe_unused,
+			      struct machine *machine __maybe_unused)
+{
+	struct perf_kvm_stat *kvm = container_of(tool, struct perf_kvm_stat, tool);
+
+	kvm->lost_events++;
+	return 0;
 }
 
 static int process_sample_event(struct perf_tool *tool,
@@ -707,10 +790,20 @@ static int process_sample_event(struct perf_tool *tool,
 	return 0;
 }
 
-static int get_cpu_isa(struct perf_session *session)
+static int cpu_isa_config(struct perf_kvm_stat *kvm)
 {
-	char *cpuid = session->header.env.cpuid;
-	int isa;
+	char buf[64], *cpuid;
+	int err, isa;
+
+	if (kvm->live) {
+		err = get_cpuid(buf, sizeof(buf));
+		if (err != 0) {
+			pr_err("Failed to look up CPU type (Intel or AMD)\n");
+			return err;
+		}
+		cpuid = buf;
+	} else
+		cpuid = kvm->session->header.env.cpuid;
 
 	if (strstr(cpuid, "Intel"))
 		isa = 1;
@@ -718,10 +811,339 @@ static int get_cpu_isa(struct perf_session *session)
 		isa = 0;
 	else {
 		pr_err("CPU %s is not supported.\n", cpuid);
-		isa = -ENOTSUP;
+		return -ENOTSUP;
+	}
+
+	if (isa == 1) {
+		kvm->exit_reasons = vmx_exit_reasons;
+		kvm->exit_reasons_size = ARRAY_SIZE(vmx_exit_reasons);
+		kvm->exit_reasons_isa = "VMX";
+	}
+
+	return 0;
+}
+
+static bool verify_vcpu(int vcpu)
+{
+	int nr_cpus;
+
+	if (vcpu != -1 && vcpu < 0) {
+		pr_err("Invalid vcpu:%d.\n", vcpu);
+		return false;
+	}
+
+	nr_cpus = sysconf(_SC_NPROCESSORS_ONLN);
+	if ((nr_cpus > 0) && (vcpu > nr_cpus - 1)) {
+		pr_err("Invalid vcpu:%d.\n", vcpu);
+		return false;
+	}
+
+	return true;
+}
+
+#define PERF_KVM__MAX_EVENTS_PER_MMAP  1000
+
+static s64 perf_kvm__mmap_read_idx(struct perf_kvm_stat *kvm, int idx)
+{
+	union perf_event *event;
+	s64 n = 0;
+	int err;
+
+	while ((event = perf_evlist__mmap_read(kvm->evlist, idx)) != NULL) {
+		err = perf_session__process_event(kvm->session, event,
+						  &kvm->tool, 0);
+		if (err) {
+			pr_err("Failed to process event\n");
+			return err;
+		}
+		n++;
+
+		/* limit events per mmap handled all at once */
+		if (n == PERF_KVM__MAX_EVENTS_PER_MMAP)
+			break;
+	}
+
+	return n;
+}
+
+static int perf_kvm__mmap_read(struct perf_kvm_stat *kvm)
+{
+	int i, err, throttled = 0;
+	s64 n, ntotal = 0;
+
+	for (i = 0; i < kvm->evlist->nr_mmaps; i++) {
+		n = perf_kvm__mmap_read_idx(kvm, i);
+		if (n < 0)
+			return -1;
+		ntotal += n;
+		if (n == PERF_KVM__MAX_EVENTS_PER_MMAP)
+			throttled = 1;
+	}
+
+	/* flush queue after each round in which we processed events */
+	if (ntotal) {
+		err = kvm->tool.finished_round(&kvm->tool, NULL, kvm->session);
+		if (err) {
+			if (kvm->lost_events)
+				pr_info("\nLost events: %" PRIu64 "\n\n",
+					kvm->lost_events);
+			return err;
+		}
+	}
+
+	return throttled;
+}
+
+static volatile int done;
+
+static void sig_handler(int sig __maybe_unused)
+{
+	done = 1;
+}
+
+static int perf_kvm__timerfd_create(struct perf_kvm_stat *kvm)
+{
+	struct itimerspec new_value;
+	int rc = -1;
+
+	kvm->timerfd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK);
+	if (kvm->timerfd < 0) {
+		pr_err("timerfd_create failed\n");
+		goto out;
+	}
+
+	new_value.it_value.tv_sec = kvm->display_time;
+	new_value.it_value.tv_nsec = 0;
+	new_value.it_interval.tv_sec = kvm->display_time;
+	new_value.it_interval.tv_nsec = 0;
+
+	if (timerfd_settime(kvm->timerfd, 0, &new_value, NULL) != 0) {
+		pr_err("timerfd_settime failed: %d\n", errno);
+		close(kvm->timerfd);
+		goto out;
+	}
+
+	rc = 0;
+out:
+	return rc;
+}
+
+static int perf_kvm__handle_timerfd(struct perf_kvm_stat *kvm)
+{
+	uint64_t c;
+	int rc;
+
+	rc = read(kvm->timerfd, &c, sizeof(uint64_t));
+	if (rc < 0) {
+		if (errno == EAGAIN)
+			return 0;
+
+		pr_err("Failed to read timer fd: %d\n", errno);
+		return -1;
+	}
+
+	if (rc != sizeof(uint64_t)) {
+		pr_err("Error reading timer fd - invalid size returned\n");
+		return -1;
+	}
+
+	if (c != 1)
+		pr_debug("Missed timer beats: %" PRIu64 "\n", c-1);
+
+	/* update display */
+	sort_result(kvm);
+	print_result(kvm);
+
+	/* reset counts */
+	clear_events_cache_stats(kvm->kvm_events_cache);
+	kvm->total_count = 0;
+	kvm->total_time = 0;
+	kvm->lost_events = 0;
+
+	return 0;
+}
+
+static int fd_set_nonblock(int fd)
+{
+	long arg = 0;
+
+	arg = fcntl(fd, F_GETFL);
+	if (arg < 0) {
+		pr_err("Failed to get current flags for fd %d\n", fd);
+		return -1;
+	}
+
+	if (fcntl(fd, F_SETFL, arg | O_NONBLOCK) < 0) {
+		pr_err("Failed to set non-block option on fd %d\n", fd);
+		return -1;
+	}
+
+	return 0;
+}
+
+static
+int perf_kvm__handle_stdin(struct termios *tc_now, struct termios *tc_save)
+{
+	int c;
+
+	tcsetattr(0, TCSANOW, tc_now);
+	c = getc(stdin);
+	tcsetattr(0, TCSAFLUSH, tc_save);
+
+	if (c == 'q')
+		return 1;
+
+	return 0;
+}
+
+static int kvm_events_live_report(struct perf_kvm_stat *kvm)
+{
+	struct pollfd *pollfds = NULL;
+	int nr_fds, nr_stdin, ret, err = -EINVAL;
+	struct termios tc, save;
+
+	/* live flag must be set first */
+	kvm->live = true;
+
+	ret = cpu_isa_config(kvm);
+	if (ret < 0)
+		return ret;
+
+	if (!verify_vcpu(kvm->trace_vcpu) ||
+	    !select_key(kvm) ||
+	    !register_kvm_events_ops(kvm)) {
+		goto out;
+	}
+
+	init_kvm_event_record(kvm);
+
+	tcgetattr(0, &save);
+	tc = save;
+	tc.c_lflag &= ~(ICANON | ECHO);
+	tc.c_cc[VMIN] = 0;
+	tc.c_cc[VTIME] = 0;
+
+	signal(SIGINT, sig_handler);
+	signal(SIGTERM, sig_handler);
+
+	/* copy pollfds -- need to add timerfd and stdin */
+	nr_fds = kvm->evlist->nr_fds;
+	pollfds = zalloc(sizeof(struct pollfd) * (nr_fds + 2));
+	if (!pollfds) {
+		err = -ENOMEM;
+		goto out;
+	}
+	memcpy(pollfds, kvm->evlist->pollfd,
+		sizeof(struct pollfd) * kvm->evlist->nr_fds);
+
+	/* add timer fd */
+	if (perf_kvm__timerfd_create(kvm) < 0) {
+		err = -1;
+		goto out;
+	}
+
+	pollfds[nr_fds].fd = kvm->timerfd;
+	pollfds[nr_fds].events = POLLIN;
+	nr_fds++;
+
+	pollfds[nr_fds].fd = fileno(stdin);
+	pollfds[nr_fds].events = POLLIN;
+	nr_stdin = nr_fds;
+	nr_fds++;
+	if (fd_set_nonblock(fileno(stdin)) != 0)
+		goto out;
+
+	/* everything is good - enable the events and process */
+	perf_evlist__enable(kvm->evlist);
+
+	while (!done) {
+		int rc;
+
+		rc = perf_kvm__mmap_read(kvm);
+		if (rc < 0)
+			break;
+
+		err = perf_kvm__handle_timerfd(kvm);
+		if (err)
+			goto out;
+
+		if (pollfds[nr_stdin].revents & POLLIN)
+			done = perf_kvm__handle_stdin(&tc, &save);
+
+		if (!rc && !done)
+			err = poll(pollfds, nr_fds, 100);
+	}
+
+	perf_evlist__disable(kvm->evlist);
+
+	if (err == 0) {
+		sort_result(kvm);
+		print_result(kvm);
 	}
 
-	return isa;
+out:
+	if (kvm->timerfd >= 0)
+		close(kvm->timerfd);
+
+	if (pollfds)
+		free(pollfds);
+
+	return err;
+}
+
+static int perf_kvm__open_counters(struct perf_kvm_stat *kvm)
+{
+	struct perf_evsel *pos;
+	struct perf_evlist *evlist = kvm->evlist;
+	char msg[512];
+
+	perf_evlist__config(evlist, &kvm->opts);
+
+	/*
+	 * Note: exclude_{guest,host} do not apply here.
+	 *       This command processes KVM tracepoints from host only
+	 */
+	list_for_each_entry(pos, &evlist->entries, node) {
+		struct perf_event_attr *attr = &pos->attr;
+
+		attr->sample_type |= PERF_SAMPLE_TID;
+		attr->sample_type |= PERF_SAMPLE_TIME;
+		attr->sample_type |= PERF_SAMPLE_CPU;
+		attr->sample_type |= PERF_SAMPLE_RAW;
+
+		attr->sample_period = 1;
+
+		attr->watermark = 0;
+		attr->wakeup_events = 1000;
+
+		/* will enable all once we are ready */
+		attr->disabled = 1;
+
+try_again:
+		if (perf_evsel__open(pos, evlist->cpus, evlist->threads) < 0) {
+			if (perf_evsel__fallback(pos, errno, msg, sizeof(msg))) {
+				if (verbose)
+					ui__warning("%s\n", msg);
+				goto try_again;
+			}
+
+			perf_evsel__open_strerror(pos, &kvm->opts.target,
+						  errno, msg, sizeof(msg));
+			ui__error("%s\n", msg);
+			goto out_err;
+		}
+	}
+
+	if (perf_evlist__mmap(evlist, kvm->opts.mmap_pages, false) < 0) {
+		ui__error("Failed to mmap with %d (%s)\n",
+			  errno, strerror(errno));
+		goto out_err;
+	}
+
+	return 0;
+
+out_err:
+	return -1;
 }
 
 static int read_events(struct perf_kvm_stat *kvm)
@@ -749,30 +1171,13 @@ static int read_events(struct perf_kvm_stat *kvm)
 	 * Do not use 'isa' recorded in kvm_exit tracepoint since it is not
 	 * traced in the old kernel.
 	 */
-	ret = get_cpu_isa(kvm->session);
-
+	ret = cpu_isa_config(kvm);
 	if (ret < 0)
 		return ret;
 
-	if (ret == 1) {
-		kvm->exit_reasons = vmx_exit_reasons;
-		kvm->exit_reasons_size = ARRAY_SIZE(vmx_exit_reasons);
-		kvm->exit_reasons_isa = "VMX";
-	}
-
 	return perf_session__process_events(kvm->session, &kvm->tool);
 }
 
-static bool verify_vcpu(int vcpu)
-{
-	if (vcpu != -1 && vcpu < 0) {
-		pr_err("Invalid vcpu:%d.\n", vcpu);
-		return false;
-	}
-
-	return true;
-}
-
 static int kvm_events_report_vcpu(struct perf_kvm_stat *kvm)
 {
 	int ret = -EINVAL;
@@ -886,6 +1291,148 @@ kvm_events_report(struct perf_kvm_stat *kvm, int argc, const char **argv)
 	return kvm_events_report_vcpu(kvm);
 }
 
+static int kvm_events_live(struct perf_kvm_stat *kvm,
+			   int argc, const char **argv)
+{
+	char errbuf[BUFSIZ];
+	int err;
+	const struct option live_options[] = {
+		OPT_STRING('p', "pid", &kvm->opts.target.pid, "pid",
+			"record events on existing process id"),
+		OPT_STRING('t', "tid", &kvm->opts.target.tid, "tid",
+			"record events on existing thread id"),
+		OPT_STRING('C', "cpu", &kvm->opts.target.cpu_list, "cpu",
+			"list of host cpus to monitor"),
+		OPT_UINTEGER('m', "mmap-pages", &kvm->opts.mmap_pages,
+			"number of mmap data pages"),
+		OPT_INCR('v', "verbose", &verbose,
+			"be more verbose (show counter open errors, etc)"),
+		OPT_BOOLEAN('a', "all-cpus", &kvm->opts.target.system_wide,
+			"system-wide collection from all CPUs"),
+		OPT_UINTEGER('d', "display", &kvm->display_time,
+			"time in seconds between display updates"),
+		OPT_STRING(0, "event", &kvm->report_event, "report event",
+			"event for reporting: vmexit, mmio, ioport"),
+		OPT_INTEGER(0, "vcpu", &kvm->trace_vcpu,
+			"vcpu id to report"),
+		OPT_STRING('k', "key", &kvm->sort_key, "sort-key",
+			"key for sorting: sample(sort by samples number)"
+			" time (sort by avg time)"),
+		OPT_END()
+	};
+	const char * const live_usage[] = {
+		"perf kvm stat live [<options>]",
+		NULL
+	};
+
+
+	/* event handling */
+	kvm->tool.sample = process_sample_event;
+	kvm->tool.comm   = perf_event__process_comm;
+	kvm->tool.exit   = perf_event__process_exit;
+	kvm->tool.fork   = perf_event__process_fork;
+	kvm->tool.lost   = process_lost_event;
+	kvm->tool.ordered_samples = true;
+	perf_tool__fill_defaults(&kvm->tool);
+
+	/* set defaults */
+	kvm->display_time = 1;
+	kvm->opts.user_interval = 1;
+	kvm->opts.mmap_pages = 512;
+	kvm->opts.target.uses_mmap = true;
+	kvm->opts.target.uid_str = NULL;
+	kvm->opts.target.uid = UINT_MAX;
+
+	symbol__init();
+	disable_buildid_cache();
+
+	use_browser = 0;
+	setup_browser(false);
+
+	if (argc) {
+		argc = parse_options(argc, argv, live_options,
+				     live_usage, 0);
+		if (argc)
+			usage_with_options(live_usage, live_options);
+	}
+
+	/*
+	 * target related setups
+	 */
+	err = perf_target__validate(&kvm->opts.target);
+	if (err) {
+		perf_target__strerror(&kvm->opts.target, err, errbuf, BUFSIZ);
+		ui__warning("%s", errbuf);
+	}
+
+	if (perf_target__none(&kvm->opts.target))
+		kvm->opts.target.system_wide = true;
+
+
+	/*
+	 * generate the event list
+	 */
+	kvm->evlist = perf_evlist__new();
+	if (kvm->evlist == NULL)
+		return -ENOMEM;
+
+	err = perf_evlist__add_tracepoints(kvm->evlist,
+					   kvm_events_tp,
+					   ARRAY_SIZE(kvm_events_tp));
+	if (err != 0)
+		goto out;
+
+	symbol_conf.nr_events = kvm->evlist->nr_entries;
+
+	if (perf_evlist__create_maps(kvm->evlist, &kvm->opts.target) < 0)
+		usage_with_options(live_usage, live_options);
+
+	/*
+	 * perf session
+	 */
+	kvm->session = perf_session__new(NULL, O_WRONLY, false, false, &kvm->tool);
+	if (kvm->session == NULL) {
+		err = -ENOMEM;
+		goto out;
+	}
+	kvm->session->evlist = kvm->evlist;
+	perf_session__set_id_hdr_size(kvm->session);
+
+	/*
+	 * need to get pevent initialized
+	 */
+	err = perf_evlist__trace_init(kvm->evlist, kvm->session);
+	if (err != 0)
+		goto out;
+
+	if (perf_target__has_task(&kvm->opts.target))
+		perf_event__synthesize_thread_map(&kvm->tool,
+						  kvm->evlist->threads,
+						  perf_event__process,
+						  &kvm->session->machines.host);
+	else
+		perf_event__synthesize_threads(&kvm->tool, perf_event__process,
+					       &kvm->session->machines.host);
+
+
+	err = perf_kvm__open_counters(kvm);
+	if (err)
+		goto out;
+
+	err = kvm_events_live_report(kvm);
+
+out:
+	exit_browser(0);
+
+	if (kvm->session)
+		perf_session__delete(kvm->session);
+	kvm->session = NULL;
+	perf_evlist__delete_maps(kvm->evlist);
+	perf_evlist__delete(kvm->evlist);
+
+	return err;
+}
+
 static void print_kvm_stat_usage(void)
 {
 	printf("Usage: perf kvm stat <command>\n\n");
@@ -893,6 +1440,7 @@ static void print_kvm_stat_usage(void)
 	printf("# Available commands:\n");
 	printf("\trecord: record kvm events\n");
 	printf("\treport: report statistical data of kvm events\n");
+	printf("\tlive:   live reporting of statistical data of kvm events\n");
 
 	printf("\nOtherwise, it is the alias of 'perf stat':\n");
 }
@@ -922,6 +1470,9 @@ static int kvm_cmd_stat(const char *file_name, int argc, const char **argv)
 	if (!strncmp(argv[1], "rep", 3))
 		return kvm_events_report(&kvm, argc - 1 , argv + 1);
 
+	if (!strncmp(argv[1], "live", 4))
+		return kvm_events_live(&kvm, argc - 1 , argv + 1);
+
 perf_stat:
 	return cmd_stat(argc, argv, NULL);
 }
-- 
1.7.10.1


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 11/16] perf kvm: add min and max stats to display
  2013-05-26  0:24 [PATCH 00/16] perf: kvm live mode David Ahern
                   ` (9 preceding siblings ...)
  2013-05-26  0:24 ` [PATCH 10/16 v2] perf kvm: add live mode David Ahern
@ 2013-05-26  0:24 ` David Ahern
  2013-05-26  0:24 ` [PATCH 12/16] perf kvm: option to print events that exceed a threshold David Ahern
                   ` (4 subsequent siblings)
  15 siblings, 0 replies; 25+ messages in thread
From: David Ahern @ 2013-05-26  0:24 UTC (permalink / raw)
  To: linux-kernel
  Cc: acme, mingo, fweisbec, peterz, jolsa, namhyung, xiaoguangrong,
	runzhen, David Ahern

Signed-off-by: David Ahern <dsahern@gmail.com>
Cc: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Xiao Guangrong <xiaoguangrong@linux.vnet.ibm.com>
Cc: Runzhen Wang <runzhen@linux.vnet.ibm.com>
---
 tools/perf/builtin-kvm.c |   21 ++++++++++++++++++---
 1 file changed, 18 insertions(+), 3 deletions(-)

diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c
index 15fdf54..9336737 100644
--- a/tools/perf/builtin-kvm.c
+++ b/tools/perf/builtin-kvm.c
@@ -337,14 +337,19 @@ static void clear_events_cache_stats(struct list_head *kvm_events_cache)
 	struct list_head *head;
 	struct kvm_event *event;
 	unsigned int i;
+	int j;
 
 	for (i = 0; i < EVENTS_CACHE_SIZE; i++) {
 		head = &kvm_events_cache[i];
 		list_for_each_entry(event, head, hash_entry) {
 			/* reset stats for event */
-			memset(&event->total, 0, sizeof(event->total));
-			memset(event->vcpu, 0,
-			       event->max_vcpu * sizeof(*event->vcpu));
+			event->total.time = 0;
+			init_stats(&event->total.stats);
+
+			for (j = 0; j < event->max_vcpu; ++j) {
+				event->vcpu[j].time = 0;
+				init_stats(&event->vcpu[j].stats);
+			}
 		}
 	}
 }
@@ -718,6 +723,7 @@ static void print_result(struct perf_kvm_stat *kvm)
 	char decode[20];
 	struct kvm_event *event;
 	int vcpu = kvm->trace_vcpu;
+	struct kvm_event_stats *kvm_stats;
 
 	if (kvm->live) {
 		puts(CONSOLE_CLEAR);
@@ -731,6 +737,8 @@ static void print_result(struct perf_kvm_stat *kvm)
 	pr_info("%9s ", "Samples%");
 
 	pr_info("%9s ", "Time%");
+	pr_info("%10s ", "Min Time");
+	pr_info("%10s ", "Max Time");
 	pr_info("%16s ", "Avg time");
 	pr_info("\n\n");
 
@@ -740,11 +748,18 @@ static void print_result(struct perf_kvm_stat *kvm)
 		ecount = get_event_count(event, vcpu);
 		etime = get_event_time(event, vcpu);
 
+		if (vcpu == -1)
+			kvm_stats = &event->total;
+		else
+			kvm_stats = &event->vcpu[vcpu];
+
 		kvm->events_ops->decode_key(kvm, &event->key, decode);
 		pr_info("%20s ", decode);
 		pr_info("%10llu ", (unsigned long long)ecount);
 		pr_info("%8.2f%% ", (double)ecount / kvm->total_count * 100);
 		pr_info("%8.2f%% ", (double)etime / kvm->total_time * 100);
+		pr_info("%8" PRIu64 "us ", kvm_stats->stats.min / 1000);
+		pr_info("%8" PRIu64 "us ", kvm_stats->stats.max / 1000);
 		pr_info("%9.2fus ( +-%7.2f%% )", (double)etime / ecount/1e3,
 			kvm_event_rel_stddev(vcpu, event));
 		pr_info("\n");
-- 
1.7.10.1


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 12/16] perf kvm: option to print events that exceed a threshold
  2013-05-26  0:24 [PATCH 00/16] perf: kvm live mode David Ahern
                   ` (10 preceding siblings ...)
  2013-05-26  0:24 ` [PATCH 11/16] perf kvm: add min and max stats to display David Ahern
@ 2013-05-26  0:24 ` David Ahern
  2013-05-26  0:24 ` [PATCH 13/16] perf kvm: debug for missing vmexit/vmentry event David Ahern
                   ` (3 subsequent siblings)
  15 siblings, 0 replies; 25+ messages in thread
From: David Ahern @ 2013-05-26  0:24 UTC (permalink / raw)
  To: linux-kernel
  Cc: acme, mingo, fweisbec, peterz, jolsa, namhyung, xiaoguangrong,
	runzhen, David Ahern

This is useful to spot high latency blips.

Signed-off-by: David Ahern <dsahern@gmail.com>
Cc: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Xiao Guangrong <xiaoguangrong@linux.vnet.ibm.com>
Cc: Runzhen Wang <runzhen@linux.vnet.ibm.com>
---
 tools/perf/builtin-kvm.c |   24 ++++++++++++++++++++----
 1 file changed, 20 insertions(+), 4 deletions(-)

diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c
index 9336737..c2fede6 100644
--- a/tools/perf/builtin-kvm.c
+++ b/tools/perf/builtin-kvm.c
@@ -106,6 +106,7 @@ struct perf_kvm_stat {
 	u64 total_time;
 	u64 total_count;
 	u64 lost_events;
+	u64 threshold;
 
 	struct rb_root result;
 
@@ -470,7 +471,7 @@ static bool update_kvm_event(struct kvm_event *event, int vcpu_id,
 static bool handle_end_event(struct perf_kvm_stat *kvm,
 			     struct vcpu_event_record *vcpu_record,
 			     struct event_key *key,
-			     u64 timestamp)
+			     struct perf_sample *sample)
 {
 	struct kvm_event *event;
 	u64 time_begin, time_diff;
@@ -507,12 +508,24 @@ static bool handle_end_event(struct perf_kvm_stat *kvm,
 	vcpu_record->start_time = 0;
 
 	/* seems to happen once in a while during live mode */
-	if (timestamp < time_begin) {
+	if (sample->time < time_begin) {
 		pr_debug("End time before begin time; skipping event.\n");
 		return true;
 	}
 
-	time_diff = timestamp - time_begin;
+	time_diff = sample->time - time_begin;
+
+	if (kvm->threshold && time_diff > kvm->threshold) {
+		char decode[32];
+
+		kvm->events_ops->decode_key(kvm, &event->key, decode);
+		if (strcmp(decode, "HLT")) {
+			pr_info("%" PRIu64 " VM %d, vcpu %d: %s event took %" PRIu64 "usec\n",
+				 sample->time, sample->pid, vcpu_record->vcpu_id,
+				 decode, time_diff/1000);
+		}
+	}
+
 	return update_kvm_event(event, vcpu, time_diff);
 }
 
@@ -559,7 +572,7 @@ static bool handle_kvm_event(struct perf_kvm_stat *kvm,
 		return handle_begin_event(kvm, vcpu_record, &key, sample->time);
 
 	if (kvm->events_ops->is_end_event(evsel, sample, &key))
-		return handle_end_event(kvm, vcpu_record, &key, sample->time);
+		return handle_end_event(kvm, vcpu_record, &key, sample);
 
 	return true;
 }
@@ -1333,6 +1346,8 @@ static int kvm_events_live(struct perf_kvm_stat *kvm,
 		OPT_STRING('k', "key", &kvm->sort_key, "sort-key",
 			"key for sorting: sample(sort by samples number)"
 			" time (sort by avg time)"),
+		OPT_U64('T', "threshold", &kvm->threshold,
+		    "show events that take longer than threshold usecs"),
 		OPT_END()
 	};
 	const char * const live_usage[] = {
@@ -1363,6 +1378,7 @@ static int kvm_events_live(struct perf_kvm_stat *kvm,
 
 	use_browser = 0;
 	setup_browser(false);
+	kvm->threshold *= 1000;   /* convert usec to nsec */
 
 	if (argc) {
 		argc = parse_options(argc, argv, live_options,
-- 
1.7.10.1


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 13/16] perf kvm: debug for missing vmexit/vmentry event
  2013-05-26  0:24 [PATCH 00/16] perf: kvm live mode David Ahern
                   ` (11 preceding siblings ...)
  2013-05-26  0:24 ` [PATCH 12/16] perf kvm: option to print events that exceed a threshold David Ahern
@ 2013-05-26  0:24 ` David Ahern
  2013-05-26  0:24 ` [PATCH 14/16] perf kvm: reuse some code of perf_kvm__timerfd_create() David Ahern
                   ` (2 subsequent siblings)
  15 siblings, 0 replies; 25+ messages in thread
From: David Ahern @ 2013-05-26  0:24 UTC (permalink / raw)
  To: linux-kernel
  Cc: acme, mingo, fweisbec, peterz, jolsa, namhyung, xiaoguangrong,
	runzhen, David Ahern

Expected to have missing events for each vcpu when perf is
started. After that should not have missing events.

Signed-off-by: David Ahern <dsahern@gmail.com>
Cc: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Xiao Guangrong <xiaoguangrong@linux.vnet.ibm.com>
Cc: Runzhen Wang <runzhen@linux.vnet.ibm.com>
---
 tools/perf/builtin-kvm.c |   15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c
index c2fede6..76cfe59 100644
--- a/tools/perf/builtin-kvm.c
+++ b/tools/perf/builtin-kvm.c
@@ -568,11 +568,22 @@ static bool handle_kvm_event(struct perf_kvm_stat *kvm,
 	    (kvm->trace_vcpu != vcpu_record->vcpu_id))
 		return true;
 
-	if (kvm->events_ops->is_begin_event(evsel, sample, &key))
+	if (kvm->events_ops->is_begin_event(evsel, sample, &key)) {
+		if (vcpu_record->start_time) {
+			pr_debug("consecutive begin events (%s) for pid %d, vcpu %d\n",
+				 evsel->name, sample->pid, vcpu_record->vcpu_id);
+		}
 		return handle_begin_event(kvm, vcpu_record, &key, sample->time);
+	}
+
 
-	if (kvm->events_ops->is_end_event(evsel, sample, &key))
+	if (kvm->events_ops->is_end_event(evsel, sample, &key)) {
+		if (vcpu_record->start_time == 0) {
+			pr_debug("consecutive end events (%s) for pid %d, vcpu %d\n",
+				 evsel->name, sample->pid, vcpu_record->vcpu_id);
+		}
 		return handle_end_event(kvm, vcpu_record, &key, sample);
+	}
 
 	return true;
 }
-- 
1.7.10.1


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 14/16] perf kvm: reuse some code of perf_kvm__timerfd_create()
  2013-05-26  0:24 [PATCH 00/16] perf: kvm live mode David Ahern
                   ` (12 preceding siblings ...)
  2013-05-26  0:24 ` [PATCH 13/16] perf kvm: debug for missing vmexit/vmentry event David Ahern
@ 2013-05-26  0:24 ` David Ahern
  2013-09-12 13:08   ` Ingo Molnar
  2013-05-26  0:24 ` [PATCH 15/16] perf kvm: move the prompt_integer() to /util/top.c David Ahern
  2013-05-26  0:24 ` [PATCH 16/16] perf kvm: set live mode refresh time dynamically David Ahern
  15 siblings, 1 reply; 25+ messages in thread
From: David Ahern @ 2013-05-26  0:24 UTC (permalink / raw)
  To: linux-kernel
  Cc: acme, mingo, fweisbec, peterz, jolsa, namhyung, xiaoguangrong,
	runzhen, Runzhen Wang, David Ahern

From: Runzhen Wang <icycoder@gmail.com>

Create a new function perf_kvm__timerfd_set() to reuse some code
in perf_kvm__timerfd_create()

Signed-off-by: Runzhen Wang <runzhen@linux.vnet.ibm.com>
Signed-off-by: David Ahern <dsahern@gmail.com>
Cc: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Xiao Guangrong <xiaoguangrong@linux.vnet.ibm.com>
---
 tools/perf/builtin-kvm.c |   25 +++++++++++++------------
 1 file changed, 13 insertions(+), 12 deletions(-)

diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c
index 76cfe59..7392538 100644
--- a/tools/perf/builtin-kvm.c
+++ b/tools/perf/builtin-kvm.c
@@ -940,16 +940,9 @@ static void sig_handler(int sig __maybe_unused)
 	done = 1;
 }
 
-static int perf_kvm__timerfd_create(struct perf_kvm_stat *kvm)
+static int perf_kvm__timerfd_set(struct perf_kvm_stat *kvm)
 {
 	struct itimerspec new_value;
-	int rc = -1;
-
-	kvm->timerfd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK);
-	if (kvm->timerfd < 0) {
-		pr_err("timerfd_create failed\n");
-		goto out;
-	}
 
 	new_value.it_value.tv_sec = kvm->display_time;
 	new_value.it_value.tv_nsec = 0;
@@ -959,12 +952,20 @@ static int perf_kvm__timerfd_create(struct perf_kvm_stat *kvm)
 	if (timerfd_settime(kvm->timerfd, 0, &new_value, NULL) != 0) {
 		pr_err("timerfd_settime failed: %d\n", errno);
 		close(kvm->timerfd);
-		goto out;
+		return -1;
 	}
 
-	rc = 0;
-out:
-	return rc;
+	return 0;
+}
+
+static int perf_kvm__timerfd_create(struct perf_kvm_stat *kvm)
+{
+	kvm->timerfd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK);
+	if (kvm->timerfd < 0) {
+		pr_err("timerfd_create failed\n");
+		return -1;
+	}
+	return perf_kvm__timerfd_set(kvm);
 }
 
 static int perf_kvm__handle_timerfd(struct perf_kvm_stat *kvm)
-- 
1.7.10.1


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 15/16] perf kvm: move the prompt_integer() to /util/top.c
  2013-05-26  0:24 [PATCH 00/16] perf: kvm live mode David Ahern
                   ` (13 preceding siblings ...)
  2013-05-26  0:24 ` [PATCH 14/16] perf kvm: reuse some code of perf_kvm__timerfd_create() David Ahern
@ 2013-05-26  0:24 ` David Ahern
  2013-05-26  0:24 ` [PATCH 16/16] perf kvm: set live mode refresh time dynamically David Ahern
  15 siblings, 0 replies; 25+ messages in thread
From: David Ahern @ 2013-05-26  0:24 UTC (permalink / raw)
  To: linux-kernel
  Cc: acme, mingo, fweisbec, peterz, jolsa, namhyung, xiaoguangrong,
	runzhen, David Ahern

As David suggested, this patch has no functional changes
just a code move.

move prompt_integer() from tools/perf/builtin-top.c  into
tools/perf/util/top.c

Signed-off-by: Runzhen Wang <runzhen@linux.vnet.ibm.com>
Signed-off-by: David Ahern <dsahern@gmail.com>
Cc: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Xiao Guangrong <xiaoguangrong@linux.vnet.ibm.com>
---
 tools/perf/builtin-top.c |   26 --------------------------
 tools/perf/util/top.c    |   26 ++++++++++++++++++++++++++
 tools/perf/util/top.h    |    1 +
 3 files changed, 27 insertions(+), 26 deletions(-)

diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index 495171a..cb7c308 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -298,32 +298,6 @@ static void perf_top__print_sym_table(struct perf_top *top)
 		       top->min_percent, stdout);
 }
 
-static void prompt_integer(int *target, const char *msg)
-{
-	char *buf = malloc(0), *p;
-	size_t dummy = 0;
-	int tmp;
-
-	fprintf(stdout, "\n%s: ", msg);
-	if (getline(&buf, &dummy, stdin) < 0)
-		return;
-
-	p = strchr(buf, '\n');
-	if (p)
-		*p = 0;
-
-	p = buf;
-	while(*p) {
-		if (!isdigit(*p))
-			goto out_free;
-		p++;
-	}
-	tmp = strtoul(buf, NULL, 10);
-	*target = tmp;
-out_free:
-	free(buf);
-}
-
 static void prompt_percent(int *target, const char *msg)
 {
 	int tmp = 0;
diff --git a/tools/perf/util/top.c b/tools/perf/util/top.c
index f857b51..1a2eaec 100644
--- a/tools/perf/util/top.c
+++ b/tools/perf/util/top.c
@@ -115,3 +115,29 @@ void perf_top__reset_sample_counters(struct perf_top *top)
 	top->exact_samples = top->guest_kernel_samples =
 	top->guest_us_samples = 0;
 }
+
+void prompt_integer(int *target, const char *msg)
+{
+	char *buf = malloc(0), *p;
+	size_t dummy = 0;
+	int tmp;
+
+	fprintf(stdout, "\n%s: ", msg);
+	if (getline(&buf, &dummy, stdin) < 0)
+		return;
+
+	p = strchr(buf, '\n');
+	if (p)
+		*p = 0;
+
+	p = buf;
+	while (*p) {
+		if (!isdigit(*p))
+			goto out_free;
+		p++;
+	}
+	tmp = strtoul(buf, NULL, 10);
+	*target = tmp;
+out_free:
+	free(buf);
+}
diff --git a/tools/perf/util/top.h b/tools/perf/util/top.h
index b554ffc..1538dab 100644
--- a/tools/perf/util/top.h
+++ b/tools/perf/util/top.h
@@ -43,4 +43,5 @@ struct perf_top {
 
 size_t perf_top__header_snprintf(struct perf_top *top, char *bf, size_t size);
 void perf_top__reset_sample_counters(struct perf_top *top);
+void prompt_integer(int *target, const char *msg);
 #endif /* __PERF_TOP_H */
-- 
1.7.10.1


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 16/16] perf kvm: set live mode refresh time dynamically
  2013-05-26  0:24 [PATCH 00/16] perf: kvm live mode David Ahern
                   ` (14 preceding siblings ...)
  2013-05-26  0:24 ` [PATCH 15/16] perf kvm: move the prompt_integer() to /util/top.c David Ahern
@ 2013-05-26  0:24 ` David Ahern
  15 siblings, 0 replies; 25+ messages in thread
From: David Ahern @ 2013-05-26  0:24 UTC (permalink / raw)
  To: linux-kernel
  Cc: acme, mingo, fweisbec, peterz, jolsa, namhyung, xiaoguangrong,
	runzhen, David Ahern

David's patch (https://lkml.org/lkml/2013/5/9/125 ) add a live mode for
perf kvm stat, but his patch can't set the refresh frequency
dynamically.

This patch accepts user's input and changes the value of
kvm->display_time variable.

For example, when the live mode is running, you press any key, it will
prints:

Mapped keys:
     [d]     set refresh frequency
     [q]     quit

Enter selection, or unmapped key to continue:
Enter refresh frequency(seconds): 2

Then, the live mode will refresh the screen every 2 seconds.

Signed-off-by: Runzhen Wang <runzhen@linux.vnet.ibm.com>
Signed-off-by: David Ahern <dsahern@gmail.com>
Cc: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Xiao Guangrong <xiaoguangrong@linux.vnet.ibm.com>
---
 tools/perf/builtin-kvm.c |   42 ++++++++++++++++++++++++++++++++++++++----
 tools/perf/util/top.c    |    4 ++++
 2 files changed, 42 insertions(+), 4 deletions(-)

diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c
index 7392538..3e3f6e2 100644
--- a/tools/perf/builtin-kvm.c
+++ b/tools/perf/builtin-kvm.c
@@ -111,7 +111,7 @@ struct perf_kvm_stat {
 	struct rb_root result;
 
 	int timerfd;
-	unsigned int display_time;
+	int display_time;
 	bool live;
 };
 
@@ -1021,17 +1021,51 @@ static int fd_set_nonblock(int fd)
 	return 0;
 }
 
+static void perf_kvm_live__print_mapped_keys(void)
+{
+	fprintf(stdout, "\nMapped keys:\n");
+	fprintf(stdout, "\t[d]     set refresh frequency\n");
+	fprintf(stdout, "\t[q]     quit\n");
+}
+
 static
-int perf_kvm__handle_stdin(struct termios *tc_now, struct termios *tc_save)
+int perf_kvm__handle_stdin(struct perf_kvm_stat *kvm,
+			   struct termios *tc_now,
+			   struct termios *tc_save)
 {
 	int c;
+	struct pollfd stdin_poll = { .fd = 0, .events = POLLIN};
 
 	tcsetattr(0, TCSANOW, tc_now);
 	c = getc(stdin);
 	tcsetattr(0, TCSAFLUSH, tc_save);
 
+	if (c == -1)
+		return 0;
 	if (c == 'q')
 		return 1;
+	perf_kvm_live__print_mapped_keys();
+	fprintf(stdout, "\nEnter selection, or unmapped key to continue: ");
+	fflush(stdout);
+
+	tcsetattr(0, TCSANOW, tc_now);
+	poll(&stdin_poll, 1, -1);
+	c = getc(stdin);
+	tcsetattr(0, TCSAFLUSH, tc_save);
+
+	switch (c) {
+	case 'q':
+		return 1;
+	case 'd':
+		prompt_integer(&kvm->display_time,
+			       "Enter refresh frequency(seconds)");
+		if (kvm->display_time < 1)
+			kvm->display_time = 1;
+		if (perf_kvm__timerfd_set(kvm) < 0)
+			return 1;
+	default:
+		break;
+	}
 
 	return 0;
 }
@@ -1108,7 +1142,7 @@ static int kvm_events_live_report(struct perf_kvm_stat *kvm)
 			goto out;
 
 		if (pollfds[nr_stdin].revents & POLLIN)
-			done = perf_kvm__handle_stdin(&tc, &save);
+			done = perf_kvm__handle_stdin(kvm, &tc, &save);
 
 		if (!rc && !done)
 			err = poll(pollfds, nr_fds, 100);
@@ -1349,7 +1383,7 @@ static int kvm_events_live(struct perf_kvm_stat *kvm,
 			"be more verbose (show counter open errors, etc)"),
 		OPT_BOOLEAN('a', "all-cpus", &kvm->opts.target.system_wide,
 			"system-wide collection from all CPUs"),
-		OPT_UINTEGER('d', "display", &kvm->display_time,
+		OPT_INTEGER('d', "display", &kvm->display_time,
 			"time in seconds between display updates"),
 		OPT_STRING(0, "event", &kvm->report_event, "report event",
 			"event for reporting: vmexit, mmio, ioport"),
diff --git a/tools/perf/util/top.c b/tools/perf/util/top.c
index 1a2eaec..10bff6d 100644
--- a/tools/perf/util/top.c
+++ b/tools/perf/util/top.c
@@ -121,8 +121,12 @@ void prompt_integer(int *target, const char *msg)
 	char *buf = malloc(0), *p;
 	size_t dummy = 0;
 	int tmp;
+	struct pollfd stdin_poll = { .fd = 0, .events = POLLIN};
 
 	fprintf(stdout, "\n%s: ", msg);
+	fflush(stdout);
+	poll(&stdin_poll, 1, -1);
+
 	if (getline(&buf, &dummy, stdin) < 0)
 		return;
 
-- 
1.7.10.1


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [tip:perf/core] perf kvm: Handle realloc failures
  2013-05-26  0:24 ` [PATCH 06/16] perf kvm: handle realloc failures David Ahern
@ 2013-05-31 11:49   ` tip-bot for David Ahern
  0 siblings, 0 replies; 25+ messages in thread
From: tip-bot for David Ahern @ 2013-05-31 11:49 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: acme, linux-kernel, hpa, mingo, peterz, namhyung, runzhen, jolsa,
	fweisbec, xiaoguangrong, dsahern, tglx

Commit-ID:  6ca5f3081f903e2b25e58a061ddad486f846561e
Gitweb:     http://git.kernel.org/tip/6ca5f3081f903e2b25e58a061ddad486f846561e
Author:     David Ahern <dsahern@gmail.com>
AuthorDate: Sat, 25 May 2013 18:24:46 -0600
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Tue, 28 May 2013 16:24:04 +0300

perf kvm: Handle realloc failures

Save previous pointer and free on failure.

Signed-off-by: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Runzhen Wang <runzhen@linux.vnet.ibm.com>
Cc: Xiao Guangrong <xiaoguangrong@linux.vnet.ibm.com>
Link: http://lkml.kernel.org/r/1369527896-3650-7-git-send-email-dsahern@gmail.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/builtin-kvm.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c
index 533501e..24b78ae 100644
--- a/tools/perf/builtin-kvm.c
+++ b/tools/perf/builtin-kvm.c
@@ -328,6 +328,7 @@ static int kvm_events_hash_fn(u64 key)
 static bool kvm_event_expand(struct kvm_event *event, int vcpu_id)
 {
 	int old_max_vcpu = event->max_vcpu;
+	void *prev;
 
 	if (vcpu_id < event->max_vcpu)
 		return true;
@@ -335,9 +336,11 @@ static bool kvm_event_expand(struct kvm_event *event, int vcpu_id)
 	while (event->max_vcpu <= vcpu_id)
 		event->max_vcpu += DEFAULT_VCPU_NUM;
 
+	prev = event->vcpu;
 	event->vcpu = realloc(event->vcpu,
 			      event->max_vcpu * sizeof(*event->vcpu));
 	if (!event->vcpu) {
+		free(prev);
 		pr_err("Not enough memory\n");
 		return false;
 	}

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [tip:perf/core] perf stats: Fix divide by 0 in variance
  2013-05-26  0:24 ` [PATCH 08/16] perf stats: fix divide by 0 in variance David Ahern
@ 2013-05-31 11:51   ` tip-bot for David Ahern
  0 siblings, 0 replies; 25+ messages in thread
From: tip-bot for David Ahern @ 2013-05-31 11:51 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: acme, linux-kernel, hpa, mingo, peterz, namhyung, runzhen, jolsa,
	fweisbec, xiaoguangrong, dsahern, tglx

Commit-ID:  45528f7c699a71d2f3096173980aadd43dff6eaa
Gitweb:     http://git.kernel.org/tip/45528f7c699a71d2f3096173980aadd43dff6eaa
Author:     David Ahern <dsahern@gmail.com>
AuthorDate: Sat, 25 May 2013 18:24:48 -0600
Committer:  Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Tue, 28 May 2013 16:24:04 +0300

perf stats: Fix divide by 0 in variance

Number of samples needs to be greater 1 to have a variance.

Fixes nan% in perf-kvm-live output.

Signed-off-by: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Runzhen Wang <runzhen@linux.vnet.ibm.com>
Cc: Xiao Guangrong <xiaoguangrong@linux.vnet.ibm.com>
Link: http://lkml.kernel.org/r/1369527896-3650-9-git-send-email-dsahern@gmail.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/stat.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c
index 2374212..7c59c28 100644
--- a/tools/perf/util/stat.c
+++ b/tools/perf/util/stat.c
@@ -37,7 +37,7 @@ double stddev_stats(struct stats *stats)
 {
 	double variance, variance_mean;
 
-	if (!stats->n)
+	if (stats->n < 2)
 		return 0.0;
 
 	variance = stats->M2 / (stats->n - 1);

^ permalink raw reply related	[flat|nested] 25+ messages in thread

* Re: [PATCH 14/16] perf kvm: reuse some code of perf_kvm__timerfd_create()
  2013-05-26  0:24 ` [PATCH 14/16] perf kvm: reuse some code of perf_kvm__timerfd_create() David Ahern
@ 2013-09-12 13:08   ` Ingo Molnar
  2013-09-12 13:34     ` David Ahern
  0 siblings, 1 reply; 25+ messages in thread
From: Ingo Molnar @ 2013-09-12 13:08 UTC (permalink / raw)
  To: David Ahern
  Cc: linux-kernel, acme, fweisbec, peterz, jolsa, namhyung,
	xiaoguangrong, runzhen, Runzhen Wang


btw., I tried to build perf on a really old distro that has no timerfd.h, 
and got:

builtin-kvm.c:22:25: error: sys/timerfd.h: No such file or directory
cc1: warnings being treated as errors
builtin-kvm.c: In function ‘perf_kvm__timerfd_create’:
builtin-kvm.c:967: warning: implicit declaration of function ‘timerfd_create’
builtin-kvm.c:967: warning: nested extern declaration of ‘timerfd_create’
builtin-kvm.c:967: error: ‘TFD_NONBLOCK’ undeclared (first use in this function)
builtin-kvm.c:967: error: (Each undeclared identifier is reported only once
builtin-kvm.c:967: error: for each function it appears in.)
builtin-kvm.c:978: warning: implicit declaration of function ‘timerfd_settime’
builtin-kvm.c:978: warning: nested extern declaration of ‘timerfd_settime’
make: *** [builtin-kvm.o] Error 1
make: *** Waiting for unfinished jobs....

The quick patch below made it build - but it's incomplete, I have not 
filled in the config/* details to generate HAVE_TIMERFD, I only made 
builtin-kvm.o build.

Thanks,

	Ingo

diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c
index 935d522..5cae8f2 100644
--- a/tools/perf/builtin-kvm.c
+++ b/tools/perf/builtin-kvm.c
@@ -19,7 +19,22 @@
 #include "util/top.h"
 
 #include <sys/prctl.h>
-#include <sys/timerfd.h>
+#ifdef HAVE_TIMERFD
+# include <sys/timerfd.h>
+#else
+# define TFD_NONBLOCK -1
+static int timerfd_create(clockid_t __clock_id __maybe_unused, int __flags __maybe_unused)
+{
+	return -1;
+}
+static int timerfd_settime(int __ufd __maybe_unused, int __flags __maybe_unused,
+			const struct itimerspec *__utmr __maybe_unused,
+			struct itimerspec *__otmr __maybe_unused)
+{
+	return -1;
+}
+
+#endif
 
 #include <termios.h>
 #include <semaphore.h>


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* Re: [PATCH 14/16] perf kvm: reuse some code of perf_kvm__timerfd_create()
  2013-09-12 13:08   ` Ingo Molnar
@ 2013-09-12 13:34     ` David Ahern
  2013-09-12 13:40       ` Ingo Molnar
  0 siblings, 1 reply; 25+ messages in thread
From: David Ahern @ 2013-09-12 13:34 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: linux-kernel, acme, fweisbec, peterz, jolsa, namhyung,
	xiaoguangrong, runzhen, Runzhen Wang

On 9/12/13 6:08 AM, Ingo Molnar wrote:
>
> btw., I tried to build perf on a really old distro that has no timerfd.h,
> and got:

Right. I hit that last week or so with RHEL5 as a build server.

timerfd was introduced before perf so any system with perf capability 
will also have timerfd. So the problem is strictly building perf on an 
older system. Are you using a tarball created by one of the 'make 
perf-*' options? Is the expectation that the resulting perf binary will 
be used for both record and report paths?

I could compile out the feature if timerfd is not available or add a 
compat layer in perf (e.g., if not defined, define it).

David

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH 14/16] perf kvm: reuse some code of perf_kvm__timerfd_create()
  2013-09-12 13:34     ` David Ahern
@ 2013-09-12 13:40       ` Ingo Molnar
  2013-10-29 13:23         ` Ingo Molnar
  0 siblings, 1 reply; 25+ messages in thread
From: Ingo Molnar @ 2013-09-12 13:40 UTC (permalink / raw)
  To: David Ahern
  Cc: linux-kernel, acme, fweisbec, peterz, jolsa, namhyung,
	xiaoguangrong, runzhen, Runzhen Wang


* David Ahern <dsahern@gmail.com> wrote:

> On 9/12/13 6:08 AM, Ingo Molnar wrote:
> >
> >btw., I tried to build perf on a really old distro that has no timerfd.h,
> >and got:
> 
> Right. I hit that last week or so with RHEL5 as a build server.
> 
> timerfd was introduced before perf so any system with perf capability 
> will also have timerfd. So the problem is strictly building perf on an 
> older system. [...]

I'm booting new kernels on an old system and I'm building it there.

So it's new kernel, new perf source and binary, old userspace.

Thanks,

	Ingo

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH 14/16] perf kvm: reuse some code of perf_kvm__timerfd_create()
  2013-09-12 13:40       ` Ingo Molnar
@ 2013-10-29 13:23         ` Ingo Molnar
  2013-10-29 13:53           ` David Ahern
  0 siblings, 1 reply; 25+ messages in thread
From: Ingo Molnar @ 2013-10-29 13:23 UTC (permalink / raw)
  To: David Ahern
  Cc: linux-kernel, acme, fweisbec, peterz, jolsa, namhyung,
	xiaoguangrong, runzhen, Runzhen Wang


* Ingo Molnar <mingo@kernel.org> wrote:

> * David Ahern <dsahern@gmail.com> wrote:
> 
> > On 9/12/13 6:08 AM, Ingo Molnar wrote:
> > >
> > >btw., I tried to build perf on a really old distro that has no timerfd.h,
> > >and got:
> > 
> > Right. I hit that last week or so with RHEL5 as a build server.
> > 
> > timerfd was introduced before perf so any system with perf capability 
> > will also have timerfd. So the problem is strictly building perf on an 
> > older system. [...]
> 
> I'm booting new kernels on an old system and I'm building it there.
> 
> So it's new kernel, new perf source and binary, old userspace.

Btw., this build failure is still there today:

  CC       builtin-kvm.o
builtin-kvm.c:23:25: error: sys/timerfd.h: No such file or directorycc1: warnings being treated as errors
builtin-kvm.c: In function ‘perf_kvm__timerfd_create’:
builtin-kvm.c:975: warning: implicit declaration of function ‘timerfd_create’
builtin-kvm.c:975: warning: nested extern declaration of ‘timerfd_create’
builtin-kvm.c:975: error: ‘TFD_NONBLOCK’ undeclared (first use in this function)
builtin-kvm.c:975: error: (Each undeclared identifier is reported only once
builtin-kvm.c:975: error: for each function it appears in.)
builtin-kvm.c:986: warning: implicit declaration of function ‘timerfd_settime’
builtin-kvm.c:986: warning: nested extern declaration of ‘timerfd_settime’
make[1]: *** [builtin-kvm.o] Error 1
make[1]: *** Waiting for unfinished jobs....
make: *** [all] Error 2

So it would be nice to at least make it build somehow.

Thanks,

	Ingo

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH 14/16] perf kvm: reuse some code of perf_kvm__timerfd_create()
  2013-10-29 13:23         ` Ingo Molnar
@ 2013-10-29 13:53           ` David Ahern
  2013-10-29 13:58             ` Ingo Molnar
  0 siblings, 1 reply; 25+ messages in thread
From: David Ahern @ 2013-10-29 13:53 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: linux-kernel, acme, fweisbec, peterz, jolsa, namhyung,
	xiaoguangrong, runzhen, Runzhen Wang

On 10/29/13 7:23 AM, Ingo Molnar wrote:
>
> * Ingo Molnar <mingo@kernel.org> wrote:
>
>> * David Ahern <dsahern@gmail.com> wrote:
>>
>>> On 9/12/13 6:08 AM, Ingo Molnar wrote:
>>>>
>>>> btw., I tried to build perf on a really old distro that has no timerfd.h,
>>>> and got:
>>>
>>> Right. I hit that last week or so with RHEL5 as a build server.
>>>
>>> timerfd was introduced before perf so any system with perf capability
>>> will also have timerfd. So the problem is strictly building perf on an
>>> older system. [...]
>>
>> I'm booting new kernels on an old system and I'm building it there.
>>
>> So it's new kernel, new perf source and binary, old userspace.
>
> Btw., this build failure is still there today:

Right, I put together a patch on Sept 14th and got distracted. I'll 
rebase to top of tree, update per the new feature tests and send it out 
today.

David


^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH 14/16] perf kvm: reuse some code of perf_kvm__timerfd_create()
  2013-10-29 13:53           ` David Ahern
@ 2013-10-29 13:58             ` Ingo Molnar
  0 siblings, 0 replies; 25+ messages in thread
From: Ingo Molnar @ 2013-10-29 13:58 UTC (permalink / raw)
  To: David Ahern
  Cc: linux-kernel, acme, fweisbec, peterz, jolsa, namhyung,
	xiaoguangrong, runzhen, Runzhen Wang


* David Ahern <dsahern@gmail.com> wrote:

> >Btw., this build failure is still there today:
> 
> Right, I put together a patch on Sept 14th and got distracted. 
> I'll rebase to top of tree, update per the new feature tests and 
> send it out today.

Yeah, it would be fine against the new feature tests, I don't think 
building on such an old distro is an outright regression.

Thanks,

	Ingo

^ permalink raw reply	[flat|nested] 25+ messages in thread

end of thread, other threads:[~2013-10-29 13:59 UTC | newest]

Thread overview: 25+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-05-26  0:24 [PATCH 00/16] perf: kvm live mode David Ahern
2013-05-26  0:24 ` [PATCH 01/16] perf evlist: restore methods removed in earlier cleanup David Ahern
2013-05-26  0:24 ` [PATCH 02/16] perf evlist: move tracepoint processing code to evlist.c David Ahern
2013-05-26  0:24 ` [PATCH 03/16 v2] perf evlist: add initialzation function for tracepoints David Ahern
2013-05-26  0:24 ` [PATCH 04/16 v2] perf session: export a few functions for event processing David Ahern
2013-05-26  0:24 ` [PATCH 05/16] perf top: move CONSOLE_CLEAR to header file David Ahern
2013-05-26  0:24 ` [PATCH 06/16] perf kvm: handle realloc failures David Ahern
2013-05-31 11:49   ` [tip:perf/core] perf kvm: Handle " tip-bot for David Ahern
2013-05-26  0:24 ` [PATCH 07/16] perf kvm: split out tracepoints from record args David Ahern
2013-05-26  0:24 ` [PATCH 08/16] perf stats: fix divide by 0 in variance David Ahern
2013-05-31 11:51   ` [tip:perf/core] perf stats: Fix " tip-bot for David Ahern
2013-05-26  0:24 ` [PATCH 09/16] perf stats: add max and min stats David Ahern
2013-05-26  0:24 ` [PATCH 10/16 v2] perf kvm: add live mode David Ahern
2013-05-26  0:24 ` [PATCH 11/16] perf kvm: add min and max stats to display David Ahern
2013-05-26  0:24 ` [PATCH 12/16] perf kvm: option to print events that exceed a threshold David Ahern
2013-05-26  0:24 ` [PATCH 13/16] perf kvm: debug for missing vmexit/vmentry event David Ahern
2013-05-26  0:24 ` [PATCH 14/16] perf kvm: reuse some code of perf_kvm__timerfd_create() David Ahern
2013-09-12 13:08   ` Ingo Molnar
2013-09-12 13:34     ` David Ahern
2013-09-12 13:40       ` Ingo Molnar
2013-10-29 13:23         ` Ingo Molnar
2013-10-29 13:53           ` David Ahern
2013-10-29 13:58             ` Ingo Molnar
2013-05-26  0:24 ` [PATCH 15/16] perf kvm: move the prompt_integer() to /util/top.c David Ahern
2013-05-26  0:24 ` [PATCH 16/16] perf kvm: set live mode refresh time dynamically David Ahern

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).