linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/17] perf tools: Factor ordered samples queue
@ 2014-06-12 22:08 Jiri Olsa
  2014-06-12 22:08 ` [PATCH 01/17] perf tools: Always force PERF_RECORD_FINISHED_ROUND event Jiri Olsa
                   ` (16 more replies)
  0 siblings, 17 replies; 28+ messages in thread
From: Jiri Olsa @ 2014-06-12 22:08 UTC (permalink / raw)
  To: linux-kernel
  Cc: Arnaldo Carvalho de Melo, Corey Ashford, David Ahern,
	Frederic Weisbecker, Ingo Molnar, Jean Pihet, Namhyung Kim,
	Paul Mackerras, Peter Zijlstra, Jiri Olsa

hi,
this patchset factors session's ordered samples queue,
and allows to limit the size of this queue.

The report command queues events till any of following
conditions is reached:
  - PERF_RECORD_FINISHED_ROUND event is processed
  - end of the file is reached

Any of above conditions will force the queue to flush some
events while keeping all allocated memory for next events.

If PERF_RECORD_FINISHED_ROUND is missing the queue will
allocate memory for every single event in the perf.data.
This could lead to enormous memory consuption and speed
degradation of report command for huge perf.data files.

With the quue allocation limit of 100 MB, I've got around
15% speedup on reporting of ~10GB perf.data file.

current code:
 Performance counter stats for './perf.old report --stdio -i perf-test.data' (3 runs):

   621,685,704,665      cycles                    ( +-  0.52% )
   873,397,467,969      instructions              ( +-  0.00% )

     286.133268732 seconds time elapsed           ( +-  1.13% )

with patches:
 Performance counter stats for './perf report --stdio -i perf-test.data' (3 runs):

   603,933,987,185      cycles                    ( +-  0.45% )
   869,139,445,070      instructions              ( +-  0.00% )

     245.337510637 seconds time elapsed           ( +-  0.49% )


The speed up seems to be mainly in less cycles spent in servicing
page faults:

current code:
     4.44%     0.01%  perf.old  [kernel.kallsyms]   [k] page_fault                                   

with patches:
     1.45%     0.00%      perf  [kernel.kallsyms]   [k] page_fault                                   

current code (faults event):
         6,643,807      faults                    ( +-  0.36% )

with patches (faults event):
         2,214,756      faults                    ( +-  3.03% )


Also now we have one of our big memory spender under control
and the ordered events queue code is put in separated object
with clear interface ready to be used by another command
like script.

Also reachable in here:
  git://git.kernel.org/pub/scm/linux/kernel/git/jolsa/perf.git
  perf/core_ordered_events

thanks,
jirka


Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jean Pihet <jean.pihet@linaro.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
Jiri Olsa (17):
      perf tools: Always force PERF_RECORD_FINISHED_ROUND event
      perf tools: Fix accounting of ordered samples queue
      perf tools: Rename ordered_samples to ordered_events
      perf tools: Rename ordered_events_queue members
      perf tools: Add ordered_events_(get|put) interface
      perf tools: Factor ordered_events_flush to be more generic
      perf tools: Limit ordered events queue size
      perf tools: Flush ordered events in case of allocation failure
      perf tools: Make perf_session_deliver_event global
      perf tools: Create ordered-events object
      pefr tools: Add ordered_events_queue_init function
      perf tools: Add ordered_events_queue_free function
      perf tools: Add perf_config_u64 function
      perf tools: Add report.queue-size config file option
      perf tools: Add debug prints for ordered events queue
      perf tools: Limit the ordered events queue by default to 100MB
      perf tools: Allow out of order messages in forced flush

 tools/perf/Makefile.perf         |   2 +
 tools/perf/builtin-annotate.c    |   2 +-
 tools/perf/builtin-diff.c        |   2 +-
 tools/perf/builtin-inject.c      |   2 +-
 tools/perf/builtin-kmem.c        |   2 +-
 tools/perf/builtin-kvm.c         |   8 +--
 tools/perf/builtin-lock.c        |   2 +-
 tools/perf/builtin-mem.c         |   2 +-
 tools/perf/builtin-record.c      |   7 +-
 tools/perf/builtin-report.c      |  19 ++++-
 tools/perf/builtin-sched.c       |   2 +-
 tools/perf/builtin-script.c      |   2 +-
 tools/perf/builtin-timechart.c   |   2 +-
 tools/perf/builtin-trace.c       |   2 +-
 tools/perf/util/cache.h          |   1 +
 tools/perf/util/config.c         |  22 ++++++
 tools/perf/util/ordered-events.c | 272 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 tools/perf/util/ordered-events.h |  55 +++++++++++++++
 tools/perf/util/session.c        | 217 ++++++++++----------------------------------------------
 tools/perf/util/session.h        |  40 +++++------
 tools/perf/util/tool.h           |   2 +-
 21 files changed, 443 insertions(+), 222 deletions(-)
 create mode 100644 tools/perf/util/ordered-events.c
 create mode 100644 tools/perf/util/ordered-events.h

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

* [PATCH 01/17] perf tools: Always force PERF_RECORD_FINISHED_ROUND event
  2014-06-12 22:08 [PATCH 00/17] perf tools: Factor ordered samples queue Jiri Olsa
@ 2014-06-12 22:08 ` Jiri Olsa
  2014-06-13 11:51   ` Namhyung Kim
  2014-06-12 22:08 ` [PATCH 02/17] perf tools: Fix accounting of ordered samples queue Jiri Olsa
                   ` (15 subsequent siblings)
  16 siblings, 1 reply; 28+ messages in thread
From: Jiri Olsa @ 2014-06-12 22:08 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Arnaldo Carvalho de Melo, Corey Ashford, David Ahern,
	Frederic Weisbecker, Ingo Molnar, Jean Pihet, Namhyung Kim,
	Paul Mackerras, Peter Zijlstra

The PERF_RECORD_FINISHED_ROUND governs queue flushing in
reporting, so it needs to be stored for any kind of event.

Forcing the PERF_RECORD_FINISHED_ROUND event to be stored any
time we finish the round and wrote at least one event.

Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jean Pihet <jean.pihet@linaro.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/builtin-record.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index 378b85b..4869050 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -238,6 +238,7 @@ static struct perf_event_header finished_round_event = {
 
 static int record__mmap_read_all(struct record *rec)
 {
+	u64 bytes_written = rec->bytes_written;
 	int i;
 	int rc = 0;
 
@@ -250,7 +251,11 @@ static int record__mmap_read_all(struct record *rec)
 		}
 	}
 
-	if (perf_header__has_feat(&rec->session->header, HEADER_TRACING_DATA))
+	/*
+	 * Mark the round finished in case we wrote
+	 * at least one event.
+	 */
+	if (bytes_written != rec->bytes_written)
 		rc = record__write(rec, &finished_round_event, sizeof(finished_round_event));
 
 out:
-- 
1.8.3.1


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

* [PATCH 02/17] perf tools: Fix accounting of ordered samples queue
  2014-06-12 22:08 [PATCH 00/17] perf tools: Factor ordered samples queue Jiri Olsa
  2014-06-12 22:08 ` [PATCH 01/17] perf tools: Always force PERF_RECORD_FINISHED_ROUND event Jiri Olsa
@ 2014-06-12 22:08 ` Jiri Olsa
  2014-06-12 22:08 ` [PATCH 03/17] perf tools: Rename ordered_samples to ordered_events Jiri Olsa
                   ` (14 subsequent siblings)
  16 siblings, 0 replies; 28+ messages in thread
From: Jiri Olsa @ 2014-06-12 22:08 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Arnaldo Carvalho de Melo, Corey Ashford, David Ahern,
	Frederic Weisbecker, Ingo Molnar, Jean Pihet, Namhyung Kim,
	Paul Mackerras, Peter Zijlstra

Properly account flushed samples within the ordered
samples queue.

Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jean Pihet <jean.pihet@linaro.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/util/session.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 64a186e..aec3dcd 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -511,6 +511,7 @@ static int flush_sample_queue(struct perf_session *s,
 		os->last_flush = iter->timestamp;
 		list_del(&iter->list);
 		list_add(&iter->list, &os->sample_cache);
+		os->nr_samples--;
 
 		if (show_progress)
 			ui_progress__update(&prog, 1);
@@ -523,8 +524,6 @@ static int flush_sample_queue(struct perf_session *s,
 			list_entry(head->prev, struct sample_queue, list);
 	}
 
-	os->nr_samples = 0;
-
 	return 0;
 }
 
-- 
1.8.3.1


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

* [PATCH 03/17] perf tools: Rename ordered_samples to ordered_events
  2014-06-12 22:08 [PATCH 00/17] perf tools: Factor ordered samples queue Jiri Olsa
  2014-06-12 22:08 ` [PATCH 01/17] perf tools: Always force PERF_RECORD_FINISHED_ROUND event Jiri Olsa
  2014-06-12 22:08 ` [PATCH 02/17] perf tools: Fix accounting of ordered samples queue Jiri Olsa
@ 2014-06-12 22:08 ` Jiri Olsa
  2014-06-12 22:08 ` [PATCH 04/17] perf tools: Rename ordered_events_queue members Jiri Olsa
                   ` (13 subsequent siblings)
  16 siblings, 0 replies; 28+ messages in thread
From: Jiri Olsa @ 2014-06-12 22:08 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Arnaldo Carvalho de Melo, Corey Ashford, David Ahern,
	Frederic Weisbecker, Ingo Molnar, Jean Pihet, Namhyung Kim,
	Paul Mackerras, Peter Zijlstra

The time ordering is generic for all kinds of events, so
using generic name 'ordered_events' for related struct.

Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jean Pihet <jean.pihet@linaro.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/builtin-annotate.c  |  2 +-
 tools/perf/builtin-diff.c      |  2 +-
 tools/perf/builtin-inject.c    |  2 +-
 tools/perf/builtin-kmem.c      |  2 +-
 tools/perf/builtin-kvm.c       |  6 ++--
 tools/perf/builtin-lock.c      |  2 +-
 tools/perf/builtin-mem.c       |  2 +-
 tools/perf/builtin-report.c    |  2 +-
 tools/perf/builtin-sched.c     |  2 +-
 tools/perf/builtin-script.c    |  2 +-
 tools/perf/builtin-timechart.c |  2 +-
 tools/perf/builtin-trace.c     |  2 +-
 tools/perf/util/session.c      | 64 +++++++++++++++++++++---------------------
 tools/perf/util/session.h      | 24 ++++++++--------
 tools/perf/util/tool.h         |  2 +-
 15 files changed, 59 insertions(+), 59 deletions(-)

diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index 1ec429f..952b5ec 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -297,7 +297,7 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __maybe_unused)
 			.comm	= perf_event__process_comm,
 			.exit	= perf_event__process_exit,
 			.fork	= perf_event__process_fork,
-			.ordered_samples = true,
+			.ordered_events = true,
 			.ordering_requires_timestamps = true,
 		},
 	};
diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c
index 9a5a035..c10cc44 100644
--- a/tools/perf/builtin-diff.c
+++ b/tools/perf/builtin-diff.c
@@ -360,7 +360,7 @@ static struct perf_tool tool = {
 	.exit	= perf_event__process_exit,
 	.fork	= perf_event__process_fork,
 	.lost	= perf_event__process_lost,
-	.ordered_samples = true,
+	.ordered_events = true,
 	.ordering_requires_timestamps = true,
 };
 
diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c
index 16c7c11..94173dd 100644
--- a/tools/perf/builtin-inject.c
+++ b/tools/perf/builtin-inject.c
@@ -366,7 +366,7 @@ static int __cmd_inject(struct perf_inject *inject)
 	} else if (inject->sched_stat) {
 		struct perf_evsel *evsel;
 
-		inject->tool.ordered_samples = true;
+		inject->tool.ordered_events = true;
 
 		evlist__for_each(session->evlist, evsel) {
 			const char *name = perf_evsel__name(evsel);
diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c
index bef3376..b572111 100644
--- a/tools/perf/builtin-kmem.c
+++ b/tools/perf/builtin-kmem.c
@@ -256,7 +256,7 @@ static int process_sample_event(struct perf_tool *tool __maybe_unused,
 static struct perf_tool perf_kmem = {
 	.sample		 = process_sample_event,
 	.comm		 = perf_event__process_comm,
-	.ordered_samples = true,
+	.ordered_events	 = true,
 };
 
 static double fragmentation(unsigned long n_req, unsigned long n_alloc)
diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c
index 0f1e5a2..b2f0ddb 100644
--- a/tools/perf/builtin-kvm.c
+++ b/tools/perf/builtin-kvm.c
@@ -955,7 +955,7 @@ static int perf_kvm__mmap_read(struct perf_kvm_stat *kvm)
 
 	/* flush queue after each round in which we processed events */
 	if (ntotal) {
-		kvm->session->ordered_samples.next_flush = flush_time;
+		kvm->session->ordered_events.next_flush = flush_time;
 		err = kvm->tool.finished_round(&kvm->tool, NULL, kvm->session);
 		if (err) {
 			if (kvm->lost_events)
@@ -1228,7 +1228,7 @@ static int read_events(struct perf_kvm_stat *kvm)
 	struct perf_tool eops = {
 		.sample			= process_sample_event,
 		.comm			= perf_event__process_comm,
-		.ordered_samples	= true,
+		.ordered_events		= true,
 	};
 	struct perf_data_file file = {
 		.path = kvm->file_name,
@@ -1480,7 +1480,7 @@ static int kvm_events_live(struct perf_kvm_stat *kvm,
 	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;
+	kvm->tool.ordered_events = true;
 	perf_tool__fill_defaults(&kvm->tool);
 
 	/* set defaults */
diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c
index 6148afc..c8122d3 100644
--- a/tools/perf/builtin-lock.c
+++ b/tools/perf/builtin-lock.c
@@ -852,7 +852,7 @@ static int __cmd_report(bool display_info)
 	struct perf_tool eops = {
 		.sample		 = process_sample_event,
 		.comm		 = perf_event__process_comm,
-		.ordered_samples = true,
+		.ordered_events	 = true,
 	};
 	struct perf_data_file file = {
 		.path = input_name,
diff --git a/tools/perf/builtin-mem.c b/tools/perf/builtin-mem.c
index 4a1a6c9..80e57c8 100644
--- a/tools/perf/builtin-mem.c
+++ b/tools/perf/builtin-mem.c
@@ -194,7 +194,7 @@ int cmd_mem(int argc, const char **argv, const char *prefix __maybe_unused)
 			.lost		= perf_event__process_lost,
 			.fork		= perf_event__process_fork,
 			.build_id	= perf_event__process_build_id,
-			.ordered_samples = true,
+			.ordered_events	= true,
 		},
 		.input_name		 = "perf.data",
 	};
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 21d830b..c72cc5a 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -578,7 +578,7 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
 			.attr		 = perf_event__process_attr,
 			.tracing_data	 = perf_event__process_tracing_data,
 			.build_id	 = perf_event__process_build_id,
-			.ordered_samples = true,
+			.ordered_events	 = true,
 			.ordering_requires_timestamps = true,
 		},
 		.max_stack		 = PERF_MAX_STACK_DEPTH,
diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c
index c38d06c..5cb39a3 100644
--- a/tools/perf/builtin-sched.c
+++ b/tools/perf/builtin-sched.c
@@ -1660,7 +1660,7 @@ int cmd_sched(int argc, const char **argv, const char *prefix __maybe_unused)
 			.comm		 = perf_event__process_comm,
 			.lost		 = perf_event__process_lost,
 			.fork		 = perf_sched__process_fork_event,
-			.ordered_samples = true,
+			.ordered_events = true,
 		},
 		.cmp_pid	      = LIST_HEAD_INIT(sched.cmp_pid),
 		.sort_list	      = LIST_HEAD_INIT(sched.sort_list),
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index 9e9c91f..ba4162e 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -1510,7 +1510,7 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
 			.attr		 = process_attr,
 			.tracing_data	 = perf_event__process_tracing_data,
 			.build_id	 = perf_event__process_build_id,
-			.ordered_samples = true,
+			.ordered_events	 = true,
 			.ordering_requires_timestamps = true,
 		},
 	};
diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c
index 74db256..257d9d6 100644
--- a/tools/perf/builtin-timechart.c
+++ b/tools/perf/builtin-timechart.c
@@ -1279,7 +1279,7 @@ int cmd_timechart(int argc, const char **argv,
 			.fork		 = process_fork_event,
 			.exit		 = process_exit_event,
 			.sample		 = process_sample_event,
-			.ordered_samples = true,
+			.ordered_events	 = true,
 		},
 		.proc_num = 15,
 	};
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index f954c26..c1d338e 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -2068,7 +2068,7 @@ static int trace__replay(struct trace *trace)
 	trace->tool.tracing_data = perf_event__process_tracing_data;
 	trace->tool.build_id	  = perf_event__process_build_id;
 
-	trace->tool.ordered_samples = true;
+	trace->tool.ordered_events = true;
 	trace->tool.ordering_requires_timestamps = true;
 
 	/* add tid to output */
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index aec3dcd..315d522 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -76,9 +76,9 @@ struct perf_session *perf_session__new(struct perf_data_file *file,
 		goto out;
 
 	session->repipe = repipe;
-	INIT_LIST_HEAD(&session->ordered_samples.samples);
-	INIT_LIST_HEAD(&session->ordered_samples.sample_cache);
-	INIT_LIST_HEAD(&session->ordered_samples.to_free);
+	INIT_LIST_HEAD(&session->ordered_events.samples);
+	INIT_LIST_HEAD(&session->ordered_events.sample_cache);
+	INIT_LIST_HEAD(&session->ordered_events.to_free);
 	machines__init(&session->machines);
 
 	if (file) {
@@ -105,9 +105,9 @@ struct perf_session *perf_session__new(struct perf_data_file *file,
 	}
 
 	if (tool && tool->ordering_requires_timestamps &&
-	    tool->ordered_samples && !perf_evlist__sample_id_all(session->evlist)) {
+	    tool->ordered_events && !perf_evlist__sample_id_all(session->evlist)) {
 		dump_printf("WARNING: No sample_id_all support, falling back to unordered processing\n");
-		tool->ordered_samples = false;
+		tool->ordered_events = false;
 	}
 
 	return session;
@@ -240,7 +240,7 @@ void perf_tool__fill_defaults(struct perf_tool *tool)
 	if (tool->build_id == NULL)
 		tool->build_id = process_finished_round_stub;
 	if (tool->finished_round == NULL) {
-		if (tool->ordered_samples)
+		if (tool->ordered_events)
 			tool->finished_round = process_finished_round;
 		else
 			tool->finished_round = process_finished_round_stub;
@@ -446,7 +446,7 @@ static perf_event__swap_op perf_event__swap_ops[] = {
 	[PERF_RECORD_HEADER_MAX]	  = NULL,
 };
 
-struct sample_queue {
+struct ordered_event {
 	u64			timestamp;
 	u64			file_offset;
 	union perf_event	*event;
@@ -455,12 +455,12 @@ struct sample_queue {
 
 static void perf_session_free_sample_buffers(struct perf_session *session)
 {
-	struct ordered_samples *os = &session->ordered_samples;
+	struct ordered_events_queue *os = &session->ordered_events;
 
 	while (!list_empty(&os->to_free)) {
-		struct sample_queue *sq;
+		struct ordered_event *sq;
 
-		sq = list_entry(os->to_free.next, struct sample_queue, list);
+		sq = list_entry(os->to_free.next, struct ordered_event, list);
 		list_del(&sq->list);
 		free(sq);
 	}
@@ -472,12 +472,12 @@ static int perf_session_deliver_event(struct perf_session *session,
 				      struct perf_tool *tool,
 				      u64 file_offset);
 
-static int flush_sample_queue(struct perf_session *s,
+static int ordered_events_flush(struct perf_session *s,
 		       struct perf_tool *tool)
 {
-	struct ordered_samples *os = &s->ordered_samples;
+	struct ordered_events_queue *os = &s->ordered_events;
 	struct list_head *head = &os->samples;
-	struct sample_queue *tmp, *iter;
+	struct ordered_event *tmp, *iter;
 	struct perf_sample sample;
 	u64 limit = os->next_flush;
 	u64 last_ts = os->last_sample ? os->last_sample->timestamp : 0ULL;
@@ -485,7 +485,7 @@ static int flush_sample_queue(struct perf_session *s,
 	struct ui_progress prog;
 	int ret;
 
-	if (!tool->ordered_samples || !limit)
+	if (!tool->ordered_events || !limit)
 		return 0;
 
 	if (show_progress)
@@ -521,7 +521,7 @@ static int flush_sample_queue(struct perf_session *s,
 		os->last_sample = NULL;
 	} else if (last_ts <= limit) {
 		os->last_sample =
-			list_entry(head->prev, struct sample_queue, list);
+			list_entry(head->prev, struct ordered_event, list);
 	}
 
 	return 0;
@@ -570,18 +570,18 @@ static int process_finished_round(struct perf_tool *tool,
 				  union perf_event *event __maybe_unused,
 				  struct perf_session *session)
 {
-	int ret = flush_sample_queue(session, tool);
+	int ret = ordered_events_flush(session, tool);
 	if (!ret)
-		session->ordered_samples.next_flush = session->ordered_samples.max_timestamp;
+		session->ordered_events.next_flush = session->ordered_events.max_timestamp;
 
 	return ret;
 }
 
 /* The queue is ordered by time */
-static void __queue_event(struct sample_queue *new, struct perf_session *s)
+static void __queue_event(struct ordered_event *new, struct perf_session *s)
 {
-	struct ordered_samples *os = &s->ordered_samples;
-	struct sample_queue *sample = os->last_sample;
+	struct ordered_events_queue *os = &s->ordered_events;
+	struct ordered_event *sample = os->last_sample;
 	u64 timestamp = new->timestamp;
 	struct list_head *p;
 
@@ -607,7 +607,7 @@ static void __queue_event(struct sample_queue *new, struct perf_session *s)
 				os->max_timestamp = timestamp;
 				return;
 			}
-			sample = list_entry(p, struct sample_queue, list);
+			sample = list_entry(p, struct ordered_event, list);
 		}
 		list_add_tail(&new->list, &sample->list);
 	} else {
@@ -617,32 +617,32 @@ static void __queue_event(struct sample_queue *new, struct perf_session *s)
 				list_add(&new->list, &os->samples);
 				return;
 			}
-			sample = list_entry(p, struct sample_queue, list);
+			sample = list_entry(p, struct ordered_event, list);
 		}
 		list_add(&new->list, &sample->list);
 	}
 }
 
-#define MAX_SAMPLE_BUFFER	(64 * 1024 / sizeof(struct sample_queue))
+#define MAX_SAMPLE_BUFFER	(64 * 1024 / sizeof(struct ordered_event))
 
 int perf_session_queue_event(struct perf_session *s, union perf_event *event,
 				    struct perf_sample *sample, u64 file_offset)
 {
-	struct ordered_samples *os = &s->ordered_samples;
+	struct ordered_events_queue *os = &s->ordered_events;
 	struct list_head *sc = &os->sample_cache;
 	u64 timestamp = sample->time;
-	struct sample_queue *new;
+	struct ordered_event *new;
 
 	if (!timestamp || timestamp == ~0ULL)
 		return -ETIME;
 
-	if (timestamp < s->ordered_samples.last_flush) {
+	if (timestamp < s->ordered_events.last_flush) {
 		printf("Warning: Timestamp below last timeslice flush\n");
 		return -EINVAL;
 	}
 
 	if (!list_empty(sc)) {
-		new = list_entry(sc->next, struct sample_queue, list);
+		new = list_entry(sc->next, struct ordered_event, list);
 		list_del(&new->list);
 	} else if (os->sample_buffer) {
 		new = os->sample_buffer + os->sample_buffer_idx;
@@ -1062,7 +1062,7 @@ static int perf_session__process_event(struct perf_session *session,
 	if (ret)
 		return ret;
 
-	if (tool->ordered_samples) {
+	if (tool->ordered_events) {
 		ret = perf_session_queue_event(session, event, &sample,
 					       file_offset);
 		if (ret != -ETIME)
@@ -1221,8 +1221,8 @@ more:
 		goto more;
 done:
 	/* do the final flush for ordered samples */
-	session->ordered_samples.next_flush = ULLONG_MAX;
-	err = flush_sample_queue(session, tool);
+	session->ordered_events.next_flush = ULLONG_MAX;
+	err = ordered_events_flush(session, tool);
 out_err:
 	free(buf);
 	perf_session__warn_about_errors(session, tool);
@@ -1357,8 +1357,8 @@ more:
 
 out:
 	/* do the final flush for ordered samples */
-	session->ordered_samples.next_flush = ULLONG_MAX;
-	err = flush_sample_queue(session, tool);
+	session->ordered_events.next_flush = ULLONG_MAX;
+	err = ordered_events_flush(session, tool);
 out_err:
 	ui_progress__finish();
 	perf_session__warn_about_errors(session, tool);
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h
index 3140f8a..91902ea 100644
--- a/tools/perf/util/session.h
+++ b/tools/perf/util/session.h
@@ -12,32 +12,32 @@
 #include <linux/rbtree.h>
 #include <linux/perf_event.h>
 
-struct sample_queue;
+struct ordered_event;
 struct ip_callchain;
 struct thread;
 
-struct ordered_samples {
+struct ordered_events_queue {
 	u64			last_flush;
 	u64			next_flush;
 	u64			max_timestamp;
 	struct list_head	samples;
 	struct list_head	sample_cache;
 	struct list_head	to_free;
-	struct sample_queue	*sample_buffer;
-	struct sample_queue	*last_sample;
+	struct ordered_event	*sample_buffer;
+	struct ordered_event	*last_sample;
 	int			sample_buffer_idx;
 	unsigned int		nr_samples;
 };
 
 struct perf_session {
-	struct perf_header	header;
-	struct machines		machines;
-	struct perf_evlist	*evlist;
-	struct trace_event	tevent;
-	struct events_stats	stats;
-	bool			repipe;
-	struct ordered_samples	ordered_samples;
-	struct perf_data_file	*file;
+	struct perf_header		header;
+	struct machines			machines;
+	struct perf_evlist		*evlist;
+	struct trace_event		tevent;
+	struct events_stats		stats;
+	bool				repipe;
+	struct ordered_events_queue	ordered_events;
+	struct perf_data_file		*file;
 };
 
 #define PRINT_IP_OPT_IP		(1<<0)
diff --git a/tools/perf/util/tool.h b/tools/perf/util/tool.h
index 4385816..f116369 100644
--- a/tools/perf/util/tool.h
+++ b/tools/perf/util/tool.h
@@ -40,7 +40,7 @@ struct perf_tool {
 	event_op2	tracing_data;
 	event_op2	finished_round,
 			build_id;
-	bool		ordered_samples;
+	bool		ordered_events;
 	bool		ordering_requires_timestamps;
 };
 
-- 
1.8.3.1


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

* [PATCH 04/17] perf tools: Rename ordered_events_queue members
  2014-06-12 22:08 [PATCH 00/17] perf tools: Factor ordered samples queue Jiri Olsa
                   ` (2 preceding siblings ...)
  2014-06-12 22:08 ` [PATCH 03/17] perf tools: Rename ordered_samples to ordered_events Jiri Olsa
@ 2014-06-12 22:08 ` Jiri Olsa
  2014-06-12 22:08 ` [PATCH 05/17] perf tools: Add ordered_events_(get|put) interface Jiri Olsa
                   ` (12 subsequent siblings)
  16 siblings, 0 replies; 28+ messages in thread
From: Jiri Olsa @ 2014-06-12 22:08 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Arnaldo Carvalho de Melo, Corey Ashford, David Ahern,
	Frederic Weisbecker, Ingo Molnar, Jean Pihet, Namhyung Kim,
	Paul Mackerras, Peter Zijlstra

Rename 'struct ordered_events_queue' members to better
fit the ordered events pattern.

Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jean Pihet <jean.pihet@linaro.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/util/session.c | 108 +++++++++++++++++++++++-----------------------
 tools/perf/util/session.h |  12 +++---
 2 files changed, 59 insertions(+), 61 deletions(-)

diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 315d522..fc4da58 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -76,8 +76,8 @@ struct perf_session *perf_session__new(struct perf_data_file *file,
 		goto out;
 
 	session->repipe = repipe;
-	INIT_LIST_HEAD(&session->ordered_events.samples);
-	INIT_LIST_HEAD(&session->ordered_events.sample_cache);
+	INIT_LIST_HEAD(&session->ordered_events.events);
+	INIT_LIST_HEAD(&session->ordered_events.cache);
 	INIT_LIST_HEAD(&session->ordered_events.to_free);
 	machines__init(&session->machines);
 
@@ -455,12 +455,12 @@ struct ordered_event {
 
 static void perf_session_free_sample_buffers(struct perf_session *session)
 {
-	struct ordered_events_queue *os = &session->ordered_events;
+	struct ordered_events_queue *q = &session->ordered_events;
 
-	while (!list_empty(&os->to_free)) {
+	while (!list_empty(&q->to_free)) {
 		struct ordered_event *sq;
 
-		sq = list_entry(os->to_free.next, struct ordered_event, list);
+		sq = list_entry(q->to_free.next, struct ordered_event, list);
 		list_del(&sq->list);
 		free(sq);
 	}
@@ -475,12 +475,12 @@ static int perf_session_deliver_event(struct perf_session *session,
 static int ordered_events_flush(struct perf_session *s,
 		       struct perf_tool *tool)
 {
-	struct ordered_events_queue *os = &s->ordered_events;
-	struct list_head *head = &os->samples;
+	struct ordered_events_queue *q = &s->ordered_events;
+	struct list_head *head = &q->events;
 	struct ordered_event *tmp, *iter;
 	struct perf_sample sample;
-	u64 limit = os->next_flush;
-	u64 last_ts = os->last_sample ? os->last_sample->timestamp : 0ULL;
+	u64 limit = q->next_flush;
+	u64 last_ts = q->last ? q->last->timestamp : 0ULL;
 	bool show_progress = limit == ULLONG_MAX;
 	struct ui_progress prog;
 	int ret;
@@ -489,7 +489,7 @@ static int ordered_events_flush(struct perf_session *s,
 		return 0;
 
 	if (show_progress)
-		ui_progress__init(&prog, os->nr_samples, "Processing time ordered events...");
+		ui_progress__init(&prog, q->nr_events, "Processing time ordered events...");
 
 	list_for_each_entry_safe(iter, tmp, head, list) {
 		if (session_done())
@@ -508,21 +508,19 @@ static int ordered_events_flush(struct perf_session *s,
 				return ret;
 		}
 
-		os->last_flush = iter->timestamp;
+		q->last_flush = iter->timestamp;
 		list_del(&iter->list);
-		list_add(&iter->list, &os->sample_cache);
-		os->nr_samples--;
+		list_add(&iter->list, &q->cache);
+		q->nr_events--;
 
 		if (show_progress)
 			ui_progress__update(&prog, 1);
 	}
 
-	if (list_empty(head)) {
-		os->last_sample = NULL;
-	} else if (last_ts <= limit) {
-		os->last_sample =
-			list_entry(head->prev, struct ordered_event, list);
-	}
+	if (list_empty(head))
+		q->last = NULL;
+	else if (last_ts <= limit)
+		q->last = list_entry(head->prev, struct ordered_event, list);
 
 	return 0;
 }
@@ -580,46 +578,46 @@ static int process_finished_round(struct perf_tool *tool,
 /* The queue is ordered by time */
 static void __queue_event(struct ordered_event *new, struct perf_session *s)
 {
-	struct ordered_events_queue *os = &s->ordered_events;
-	struct ordered_event *sample = os->last_sample;
+	struct ordered_events_queue *q = &s->ordered_events;
+	struct ordered_event *last = q->last;
 	u64 timestamp = new->timestamp;
 	struct list_head *p;
 
-	++os->nr_samples;
-	os->last_sample = new;
+	++q->nr_events;
+	q->last = new;
 
-	if (!sample) {
-		list_add(&new->list, &os->samples);
-		os->max_timestamp = timestamp;
+	if (!last) {
+		list_add(&new->list, &q->events);
+		q->max_timestamp = timestamp;
 		return;
 	}
 
 	/*
-	 * last_sample might point to some random place in the list as it's
-	 * the last queued event. We expect that the new event is close to
+	 * last event might point to some random place in the list as it's
+	 * the last queued event. We expect that the new event is clqe to
 	 * this.
 	 */
-	if (sample->timestamp <= timestamp) {
-		while (sample->timestamp <= timestamp) {
-			p = sample->list.next;
-			if (p == &os->samples) {
-				list_add_tail(&new->list, &os->samples);
-				os->max_timestamp = timestamp;
+	if (last->timestamp <= timestamp) {
+		while (last->timestamp <= timestamp) {
+			p = last->list.next;
+			if (p == &q->events) {
+				list_add_tail(&new->list, &q->events);
+				q->max_timestamp = timestamp;
 				return;
 			}
-			sample = list_entry(p, struct ordered_event, list);
+			last = list_entry(p, struct ordered_event, list);
 		}
-		list_add_tail(&new->list, &sample->list);
+		list_add_tail(&new->list, &last->list);
 	} else {
-		while (sample->timestamp > timestamp) {
-			p = sample->list.prev;
-			if (p == &os->samples) {
-				list_add(&new->list, &os->samples);
+		while (last->timestamp > timestamp) {
+			p = last->list.prev;
+			if (p == &q->events) {
+				list_add(&new->list, &q->events);
 				return;
 			}
-			sample = list_entry(p, struct ordered_event, list);
+			last = list_entry(p, struct ordered_event, list);
 		}
-		list_add(&new->list, &sample->list);
+		list_add(&new->list, &last->list);
 	}
 }
 
@@ -628,8 +626,8 @@ static void __queue_event(struct ordered_event *new, struct perf_session *s)
 int perf_session_queue_event(struct perf_session *s, union perf_event *event,
 				    struct perf_sample *sample, u64 file_offset)
 {
-	struct ordered_events_queue *os = &s->ordered_events;
-	struct list_head *sc = &os->sample_cache;
+	struct ordered_events_queue *q = &s->ordered_events;
+	struct list_head *cache = &q->cache;
 	u64 timestamp = sample->time;
 	struct ordered_event *new;
 
@@ -641,20 +639,20 @@ int perf_session_queue_event(struct perf_session *s, union perf_event *event,
 		return -EINVAL;
 	}
 
-	if (!list_empty(sc)) {
-		new = list_entry(sc->next, struct ordered_event, list);
+	if (!list_empty(cache)) {
+		new = list_entry(cache->next, struct ordered_event, list);
 		list_del(&new->list);
-	} else if (os->sample_buffer) {
-		new = os->sample_buffer + os->sample_buffer_idx;
-		if (++os->sample_buffer_idx == MAX_SAMPLE_BUFFER)
-			os->sample_buffer = NULL;
+	} else if (q->buffer) {
+		new = q->buffer + q->buffer_idx;
+		if (++q->buffer_idx == MAX_SAMPLE_BUFFER)
+			q->buffer = NULL;
 	} else {
-		os->sample_buffer = malloc(MAX_SAMPLE_BUFFER * sizeof(*new));
-		if (!os->sample_buffer)
+		q->buffer = malloc(MAX_SAMPLE_BUFFER * sizeof(*new));
+		if (!q->buffer)
 			return -ENOMEM;
-		list_add(&os->sample_buffer->list, &os->to_free);
-		os->sample_buffer_idx = 2;
-		new = os->sample_buffer + 1;
+		list_add(&q->buffer->list, &q->to_free);
+		q->buffer_idx = 2;
+		new = q->buffer + 1;
 	}
 
 	new->timestamp = timestamp;
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h
index 91902ea..76b897f 100644
--- a/tools/perf/util/session.h
+++ b/tools/perf/util/session.h
@@ -20,13 +20,13 @@ struct ordered_events_queue {
 	u64			last_flush;
 	u64			next_flush;
 	u64			max_timestamp;
-	struct list_head	samples;
-	struct list_head	sample_cache;
+	struct list_head	events;
+	struct list_head	cache;
 	struct list_head	to_free;
-	struct ordered_event	*sample_buffer;
-	struct ordered_event	*last_sample;
-	int			sample_buffer_idx;
-	unsigned int		nr_samples;
+	struct ordered_event	*buffer;
+	struct ordered_event	*last;
+	int			buffer_idx;
+	unsigned int		nr_events;
 };
 
 struct perf_session {
-- 
1.8.3.1


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

* [PATCH 05/17] perf tools: Add ordered_events_(get|put) interface
  2014-06-12 22:08 [PATCH 00/17] perf tools: Factor ordered samples queue Jiri Olsa
                   ` (3 preceding siblings ...)
  2014-06-12 22:08 ` [PATCH 04/17] perf tools: Rename ordered_events_queue members Jiri Olsa
@ 2014-06-12 22:08 ` Jiri Olsa
  2014-06-13 12:05   ` Namhyung Kim
  2014-06-12 22:08 ` [PATCH 06/17] perf tools: Factor ordered_events_flush to be more generic Jiri Olsa
                   ` (11 subsequent siblings)
  16 siblings, 1 reply; 28+ messages in thread
From: Jiri Olsa @ 2014-06-12 22:08 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Arnaldo Carvalho de Melo, Corey Ashford, David Ahern,
	Frederic Weisbecker, Ingo Molnar, Jean Pihet, Namhyung Kim,
	Paul Mackerras, Peter Zijlstra

Adding new ordered events interface to get|put event buffer:
  ordered_events_get - allocate event buffer from the cache
  ordered_events_put - return event buffer to the cache

Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jean Pihet <jean.pihet@linaro.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/util/session.c | 172 ++++++++++++++++++++++++++--------------------
 1 file changed, 99 insertions(+), 73 deletions(-)

diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index fc4da58..966132d 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -466,6 +466,99 @@ static void perf_session_free_sample_buffers(struct perf_session *session)
 	}
 }
 
+/* The queue is ordered by time */
+static void queue_event(struct ordered_events_queue *q, struct ordered_event *new)
+{
+	struct ordered_event *last = q->last;
+	u64 timestamp = new->timestamp;
+	struct list_head *p;
+
+	++q->nr_events;
+	q->last = new;
+
+	if (!last) {
+		list_add(&new->list, &q->events);
+		q->max_timestamp = timestamp;
+		return;
+	}
+
+	/*
+	 * last event might point to some random place in the list as it's
+	 * the last queued event. We expect that the new event is clqe to
+	 * this.
+	 */
+	if (last->timestamp <= timestamp) {
+		while (last->timestamp <= timestamp) {
+			p = last->list.next;
+			if (p == &q->events) {
+				list_add_tail(&new->list, &q->events);
+				q->max_timestamp = timestamp;
+				return;
+			}
+			last = list_entry(p, struct ordered_event, list);
+		}
+		list_add_tail(&new->list, &last->list);
+	} else {
+		while (last->timestamp > timestamp) {
+			p = last->list.prev;
+			if (p == &q->events) {
+				list_add(&new->list, &q->events);
+				return;
+			}
+			last = list_entry(p, struct ordered_event, list);
+		}
+		list_add(&new->list, &last->list);
+	}
+}
+
+#define MAX_SAMPLE_BUFFER	(64 * 1024 / sizeof(struct ordered_event))
+static struct ordered_event *alloc_event(struct ordered_events_queue *q)
+{
+	struct list_head *cache = &q->cache;
+	struct ordered_event *new;
+
+	if (!list_empty(cache)) {
+		new = list_entry(cache->next, struct ordered_event, list);
+		list_del(&new->list);
+	} else if (q->buffer) {
+		new = q->buffer + q->buffer_idx;
+		if (++q->buffer_idx == MAX_SAMPLE_BUFFER)
+			q->buffer = NULL;
+	} else {
+		q->buffer = malloc(MAX_SAMPLE_BUFFER * sizeof(*new));
+		if (!q->buffer)
+			return NULL;
+		list_add(&q->buffer->list, &q->to_free);
+		q->buffer_idx = 2;
+		new = q->buffer + 1;
+	}
+
+	return new;
+}
+
+static struct ordered_event*
+ordered_events_get(struct ordered_events_queue *q, u64 timestamp)
+{
+	struct ordered_event *new;
+
+	new = alloc_event(q);
+	if (new) {
+		new->timestamp = timestamp;
+		queue_event(q, new);
+	}
+
+	return new;
+}
+
+static void
+ordered_event_put(struct ordered_events_queue *q, struct ordered_event *iter)
+{
+	list_del(&iter->list);
+	list_add(&iter->list, &q->cache);
+	q->nr_events--;
+}
+
+
 static int perf_session_deliver_event(struct perf_session *session,
 				      union perf_event *event,
 				      struct perf_sample *sample,
@@ -508,10 +601,8 @@ static int ordered_events_flush(struct perf_session *s,
 				return ret;
 		}
 
+		ordered_event_put(q, iter);
 		q->last_flush = iter->timestamp;
-		list_del(&iter->list);
-		list_add(&iter->list, &q->cache);
-		q->nr_events--;
 
 		if (show_progress)
 			ui_progress__update(&prog, 1);
@@ -575,59 +666,10 @@ static int process_finished_round(struct perf_tool *tool,
 	return ret;
 }
 
-/* The queue is ordered by time */
-static void __queue_event(struct ordered_event *new, struct perf_session *s)
-{
-	struct ordered_events_queue *q = &s->ordered_events;
-	struct ordered_event *last = q->last;
-	u64 timestamp = new->timestamp;
-	struct list_head *p;
-
-	++q->nr_events;
-	q->last = new;
-
-	if (!last) {
-		list_add(&new->list, &q->events);
-		q->max_timestamp = timestamp;
-		return;
-	}
-
-	/*
-	 * last event might point to some random place in the list as it's
-	 * the last queued event. We expect that the new event is clqe to
-	 * this.
-	 */
-	if (last->timestamp <= timestamp) {
-		while (last->timestamp <= timestamp) {
-			p = last->list.next;
-			if (p == &q->events) {
-				list_add_tail(&new->list, &q->events);
-				q->max_timestamp = timestamp;
-				return;
-			}
-			last = list_entry(p, struct ordered_event, list);
-		}
-		list_add_tail(&new->list, &last->list);
-	} else {
-		while (last->timestamp > timestamp) {
-			p = last->list.prev;
-			if (p == &q->events) {
-				list_add(&new->list, &q->events);
-				return;
-			}
-			last = list_entry(p, struct ordered_event, list);
-		}
-		list_add(&new->list, &last->list);
-	}
-}
-
-#define MAX_SAMPLE_BUFFER	(64 * 1024 / sizeof(struct ordered_event))
-
 int perf_session_queue_event(struct perf_session *s, union perf_event *event,
 				    struct perf_sample *sample, u64 file_offset)
 {
 	struct ordered_events_queue *q = &s->ordered_events;
-	struct list_head *cache = &q->cache;
 	u64 timestamp = sample->time;
 	struct ordered_event *new;
 
@@ -639,29 +681,13 @@ int perf_session_queue_event(struct perf_session *s, union perf_event *event,
 		return -EINVAL;
 	}
 
-	if (!list_empty(cache)) {
-		new = list_entry(cache->next, struct ordered_event, list);
-		list_del(&new->list);
-	} else if (q->buffer) {
-		new = q->buffer + q->buffer_idx;
-		if (++q->buffer_idx == MAX_SAMPLE_BUFFER)
-			q->buffer = NULL;
-	} else {
-		q->buffer = malloc(MAX_SAMPLE_BUFFER * sizeof(*new));
-		if (!q->buffer)
-			return -ENOMEM;
-		list_add(&q->buffer->list, &q->to_free);
-		q->buffer_idx = 2;
-		new = q->buffer + 1;
+	new = ordered_events_get(q, timestamp);
+	if (new) {
+		new->file_offset = file_offset;
+		new->event = event;
 	}
 
-	new->timestamp = timestamp;
-	new->file_offset = file_offset;
-	new->event = event;
-
-	__queue_event(new, s);
-
-	return 0;
+	return new ? 0 : -ENOMEM;
 }
 
 static void callchain__printf(struct perf_sample *sample)
-- 
1.8.3.1


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

* [PATCH 06/17] perf tools: Factor ordered_events_flush to be more generic
  2014-06-12 22:08 [PATCH 00/17] perf tools: Factor ordered samples queue Jiri Olsa
                   ` (4 preceding siblings ...)
  2014-06-12 22:08 ` [PATCH 05/17] perf tools: Add ordered_events_(get|put) interface Jiri Olsa
@ 2014-06-12 22:08 ` Jiri Olsa
  2014-06-12 22:08 ` [PATCH 07/17] perf tools: Limit ordered events queue size Jiri Olsa
                   ` (10 subsequent siblings)
  16 siblings, 0 replies; 28+ messages in thread
From: Jiri Olsa @ 2014-06-12 22:08 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Arnaldo Carvalho de Melo, Corey Ashford, David Ahern,
	Frederic Weisbecker, Ingo Molnar, Jean Pihet, Namhyung Kim,
	Paul Mackerras, Peter Zijlstra

Centralizing the next_flush calculation under the
ordered_events_flush function.

Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jean Pihet <jean.pihet@linaro.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/util/session.c | 47 ++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 36 insertions(+), 11 deletions(-)

diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 966132d..76df5c9 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -453,6 +453,11 @@ struct ordered_event {
 	struct list_head	list;
 };
 
+enum oeq_flush {
+	OEQ_FLUSH__FINAL,
+	OEQ_FLUSH__ROUND,
+};
+
 static void perf_session_free_sample_buffers(struct perf_session *session)
 {
 	struct ordered_events_queue *q = &session->ordered_events;
@@ -565,8 +570,8 @@ static int perf_session_deliver_event(struct perf_session *session,
 				      struct perf_tool *tool,
 				      u64 file_offset);
 
-static int ordered_events_flush(struct perf_session *s,
-		       struct perf_tool *tool)
+static int __ordered_events_flush(struct perf_session *s,
+				  struct perf_tool *tool)
 {
 	struct ordered_events_queue *q = &s->ordered_events;
 	struct list_head *head = &q->events;
@@ -616,6 +621,32 @@ static int ordered_events_flush(struct perf_session *s,
 	return 0;
 }
 
+static int ordered_events_flush(struct perf_session *s, struct perf_tool *tool,
+				enum oeq_flush how)
+{
+	struct ordered_events_queue *q = &s->ordered_events;
+	int err;
+
+	switch (how) {
+	case OEQ_FLUSH__FINAL:
+		q->next_flush = ULLONG_MAX;
+		break;
+
+	case OEQ_FLUSH__ROUND:
+	default:
+		break;
+	};
+
+	err = __ordered_events_flush(s, tool);
+
+	if (!err) {
+		if (how == OEQ_FLUSH__ROUND)
+			q->next_flush = q->max_timestamp;
+	}
+
+	return err;
+}
+
 /*
  * When perf record finishes a pass on every buffers, it records this pseudo
  * event.
@@ -659,11 +690,7 @@ static int process_finished_round(struct perf_tool *tool,
 				  union perf_event *event __maybe_unused,
 				  struct perf_session *session)
 {
-	int ret = ordered_events_flush(session, tool);
-	if (!ret)
-		session->ordered_events.next_flush = session->ordered_events.max_timestamp;
-
-	return ret;
+	return ordered_events_flush(session, tool, OEQ_FLUSH__ROUND);
 }
 
 int perf_session_queue_event(struct perf_session *s, union perf_event *event,
@@ -1245,8 +1272,7 @@ more:
 		goto more;
 done:
 	/* do the final flush for ordered samples */
-	session->ordered_events.next_flush = ULLONG_MAX;
-	err = ordered_events_flush(session, tool);
+	err = ordered_events_flush(session, tool, OEQ_FLUSH__FINAL);
 out_err:
 	free(buf);
 	perf_session__warn_about_errors(session, tool);
@@ -1381,8 +1407,7 @@ more:
 
 out:
 	/* do the final flush for ordered samples */
-	session->ordered_events.next_flush = ULLONG_MAX;
-	err = ordered_events_flush(session, tool);
+	err = ordered_events_flush(session, tool, OEQ_FLUSH__FINAL);
 out_err:
 	ui_progress__finish();
 	perf_session__warn_about_errors(session, tool);
-- 
1.8.3.1


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

* [PATCH 07/17] perf tools: Limit ordered events queue size
  2014-06-12 22:08 [PATCH 00/17] perf tools: Factor ordered samples queue Jiri Olsa
                   ` (5 preceding siblings ...)
  2014-06-12 22:08 ` [PATCH 06/17] perf tools: Factor ordered_events_flush to be more generic Jiri Olsa
@ 2014-06-12 22:08 ` Jiri Olsa
  2014-06-12 22:08 ` [PATCH 08/17] perf tools: Flush ordered events in case of allocation failure Jiri Olsa
                   ` (9 subsequent siblings)
  16 siblings, 0 replies; 28+ messages in thread
From: Jiri Olsa @ 2014-06-12 22:08 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Arnaldo Carvalho de Melo, Corey Ashford, David Ahern,
	Frederic Weisbecker, Ingo Molnar, Jean Pihet, Namhyung Kim,
	Paul Mackerras, Peter Zijlstra

Add limit to the ordered events queue allocation. This way
we will be able to control the size of the queue buffers.

There's no limit at the moment (it's set to (u64) -1). The config
code will come in following patches.

Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jean Pihet <jean.pihet@linaro.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/util/session.c | 12 +++++++++---
 tools/perf/util/session.h |  2 ++
 2 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 76df5c9..1ff4695 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -79,6 +79,8 @@ struct perf_session *perf_session__new(struct perf_data_file *file,
 	INIT_LIST_HEAD(&session->ordered_events.events);
 	INIT_LIST_HEAD(&session->ordered_events.cache);
 	INIT_LIST_HEAD(&session->ordered_events.to_free);
+	session->ordered_events.max_alloc_size = (u64) -1;
+	session->ordered_events.cur_alloc_size = 0;
 	machines__init(&session->machines);
 
 	if (file) {
@@ -520,7 +522,7 @@ static void queue_event(struct ordered_events_queue *q, struct ordered_event *ne
 static struct ordered_event *alloc_event(struct ordered_events_queue *q)
 {
 	struct list_head *cache = &q->cache;
-	struct ordered_event *new;
+	struct ordered_event *new = NULL;
 
 	if (!list_empty(cache)) {
 		new = list_entry(cache->next, struct ordered_event, list);
@@ -529,10 +531,14 @@ static struct ordered_event *alloc_event(struct ordered_events_queue *q)
 		new = q->buffer + q->buffer_idx;
 		if (++q->buffer_idx == MAX_SAMPLE_BUFFER)
 			q->buffer = NULL;
-	} else {
-		q->buffer = malloc(MAX_SAMPLE_BUFFER * sizeof(*new));
+	} else if (q->cur_alloc_size < q->max_alloc_size) {
+		size_t size = MAX_SAMPLE_BUFFER * sizeof(*new);
+
+		q->buffer = malloc(size);
 		if (!q->buffer)
 			return NULL;
+
+		q->cur_alloc_size += size;
 		list_add(&q->buffer->list, &q->to_free);
 		q->buffer_idx = 2;
 		new = q->buffer + 1;
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h
index 76b897f..9f64ac9 100644
--- a/tools/perf/util/session.h
+++ b/tools/perf/util/session.h
@@ -20,6 +20,8 @@ struct ordered_events_queue {
 	u64			last_flush;
 	u64			next_flush;
 	u64			max_timestamp;
+	u64			max_alloc_size;
+	u64			cur_alloc_size;
 	struct list_head	events;
 	struct list_head	cache;
 	struct list_head	to_free;
-- 
1.8.3.1


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

* [PATCH 08/17] perf tools: Flush ordered events in case of allocation failure
  2014-06-12 22:08 [PATCH 00/17] perf tools: Factor ordered samples queue Jiri Olsa
                   ` (6 preceding siblings ...)
  2014-06-12 22:08 ` [PATCH 07/17] perf tools: Limit ordered events queue size Jiri Olsa
@ 2014-06-12 22:08 ` Jiri Olsa
  2014-06-12 22:08 ` [PATCH 09/17] perf tools: Make perf_session_deliver_event global Jiri Olsa
                   ` (8 subsequent siblings)
  16 siblings, 0 replies; 28+ messages in thread
From: Jiri Olsa @ 2014-06-12 22:08 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Arnaldo Carvalho de Melo, Corey Ashford, David Ahern,
	Frederic Weisbecker, Ingo Molnar, Jean Pihet, Namhyung Kim,
	Paul Mackerras, Peter Zijlstra

In previous patches we added a limit for ordered events
queue allocation size. If we reach this size we need to
flush (part of) the queue to get some free buffers.

The current functionality is not affected, because the
limit is hard coded to (u64) -1. The configuration code
for size will come in following patches.

Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jean Pihet <jean.pihet@linaro.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/builtin-kvm.c  |  2 +-
 tools/perf/util/session.c | 28 ++++++++++++++++++++++++++--
 tools/perf/util/session.h |  3 ++-
 3 files changed, 29 insertions(+), 4 deletions(-)

diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c
index b2f0ddb..b4fd302 100644
--- a/tools/perf/builtin-kvm.c
+++ b/tools/perf/builtin-kvm.c
@@ -902,7 +902,7 @@ static s64 perf_kvm__mmap_read_idx(struct perf_kvm_stat *kvm, int idx,
 			return -1;
 		}
 
-		err = perf_session_queue_event(kvm->session, event, &sample, 0);
+		err = perf_session_queue_event(kvm->session, event, &kvm->tool, &sample, 0);
 		/*
 		 * FIXME: Here we can't consume the event, as perf_session_queue_event will
 		 *        point to it, and it'll get possibly overwritten by the kernel.
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 1ff4695..fc085c3 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -15,6 +15,7 @@
 #include "cpumap.h"
 #include "perf_regs.h"
 #include "vdso.h"
+#include "asm/bug.h"
 
 static int perf_session__open(struct perf_session *session)
 {
@@ -458,6 +459,7 @@ struct ordered_event {
 enum oeq_flush {
 	OEQ_FLUSH__FINAL,
 	OEQ_FLUSH__ROUND,
+	OEQ_FLUSH__HALF,
 };
 
 static void perf_session_free_sample_buffers(struct perf_session *session)
@@ -638,6 +640,22 @@ static int ordered_events_flush(struct perf_session *s, struct perf_tool *tool,
 		q->next_flush = ULLONG_MAX;
 		break;
 
+	case OEQ_FLUSH__HALF:
+	{
+		struct ordered_event *first, *last;
+		struct list_head *head = &q->events;
+
+		first = list_entry(head->next, struct ordered_event, list);
+		last = q->last;
+
+		if (WARN_ONCE(!last || list_empty(head), "empty queue"))
+			return 0;
+
+		q->next_flush  = first->timestamp;
+		q->next_flush += (last->timestamp - first->timestamp) / 2;
+		break;
+	}
+
 	case OEQ_FLUSH__ROUND:
 	default:
 		break;
@@ -700,7 +718,8 @@ static int process_finished_round(struct perf_tool *tool,
 }
 
 int perf_session_queue_event(struct perf_session *s, union perf_event *event,
-				    struct perf_sample *sample, u64 file_offset)
+			     struct perf_tool *tool, struct perf_sample *sample,
+			     u64 file_offset)
 {
 	struct ordered_events_queue *q = &s->ordered_events;
 	u64 timestamp = sample->time;
@@ -715,6 +734,11 @@ int perf_session_queue_event(struct perf_session *s, union perf_event *event,
 	}
 
 	new = ordered_events_get(q, timestamp);
+	if (!new) {
+		ordered_events_flush(s, tool, OEQ_FLUSH__HALF);
+		new = ordered_events_get(q, timestamp);
+	}
+
 	if (new) {
 		new->file_offset = file_offset;
 		new->event = event;
@@ -1120,7 +1144,7 @@ static int perf_session__process_event(struct perf_session *session,
 		return ret;
 
 	if (tool->ordered_events) {
-		ret = perf_session_queue_event(session, event, &sample,
+		ret = perf_session_queue_event(session, event, tool, &sample,
 					       file_offset);
 		if (ret != -ETIME)
 			return ret;
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h
index 9f64ac9..af38954 100644
--- a/tools/perf/util/session.h
+++ b/tools/perf/util/session.h
@@ -64,7 +64,8 @@ int perf_session__process_events(struct perf_session *session,
 				 struct perf_tool *tool);
 
 int perf_session_queue_event(struct perf_session *s, union perf_event *event,
-			     struct perf_sample *sample, u64 file_offset);
+			     struct perf_tool *tool, struct perf_sample *sample,
+			     u64 file_offset);
 
 void perf_tool__fill_defaults(struct perf_tool *tool);
 
-- 
1.8.3.1


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

* [PATCH 09/17] perf tools: Make perf_session_deliver_event global
  2014-06-12 22:08 [PATCH 00/17] perf tools: Factor ordered samples queue Jiri Olsa
                   ` (7 preceding siblings ...)
  2014-06-12 22:08 ` [PATCH 08/17] perf tools: Flush ordered events in case of allocation failure Jiri Olsa
@ 2014-06-12 22:08 ` Jiri Olsa
  2014-06-12 22:08 ` [PATCH 10/17] perf tools: Create ordered-events object Jiri Olsa
                   ` (7 subsequent siblings)
  16 siblings, 0 replies; 28+ messages in thread
From: Jiri Olsa @ 2014-06-12 22:08 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Arnaldo Carvalho de Melo, Corey Ashford, David Ahern,
	Frederic Weisbecker, Ingo Molnar, Jean Pihet, Namhyung Kim,
	Paul Mackerras, Peter Zijlstra

Making perf_session_deliver_event global function, as it will
be called from another object in following patch.

Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jean Pihet <jean.pihet@linaro.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/util/session.c | 17 +++++------------
 tools/perf/util/session.h |  6 ++++++
 2 files changed, 11 insertions(+), 12 deletions(-)

diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index fc085c3..08aa245 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -571,13 +571,6 @@ ordered_event_put(struct ordered_events_queue *q, struct ordered_event *iter)
 	q->nr_events--;
 }
 
-
-static int perf_session_deliver_event(struct perf_session *session,
-				      union perf_event *event,
-				      struct perf_sample *sample,
-				      struct perf_tool *tool,
-				      u64 file_offset);
-
 static int __ordered_events_flush(struct perf_session *s,
 				  struct perf_tool *tool)
 {
@@ -1003,11 +996,11 @@ perf_session__deliver_sample(struct perf_session *session,
 					    &sample->read.one, machine);
 }
 
-static int perf_session_deliver_event(struct perf_session *session,
-				      union perf_event *event,
-				      struct perf_sample *sample,
-				      struct perf_tool *tool,
-				      u64 file_offset)
+int perf_session_deliver_event(struct perf_session *session,
+			       union perf_event *event,
+			       struct perf_sample *sample,
+			       struct perf_tool *tool,
+			       u64 file_offset)
 {
 	struct perf_evsel *evsel;
 	struct machine *machine;
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h
index af38954..58acad4 100644
--- a/tools/perf/util/session.h
+++ b/tools/perf/util/session.h
@@ -69,6 +69,12 @@ int perf_session_queue_event(struct perf_session *s, union perf_event *event,
 
 void perf_tool__fill_defaults(struct perf_tool *tool);
 
+int perf_session_deliver_event(struct perf_session *session,
+			       union perf_event *event,
+			       struct perf_sample *sample,
+			       struct perf_tool *tool,
+			       u64 file_offset);
+
 int perf_session__resolve_callchain(struct perf_session *session,
 				    struct perf_evsel *evsel,
 				    struct thread *thread,
-- 
1.8.3.1


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

* [PATCH 10/17] perf tools: Create ordered-events object
  2014-06-12 22:08 [PATCH 00/17] perf tools: Factor ordered samples queue Jiri Olsa
                   ` (8 preceding siblings ...)
  2014-06-12 22:08 ` [PATCH 09/17] perf tools: Make perf_session_deliver_event global Jiri Olsa
@ 2014-06-12 22:08 ` Jiri Olsa
  2014-06-12 22:08 ` [PATCH 11/17] perf tools: Add ordered_events_queue_init function Jiri Olsa
                   ` (6 subsequent siblings)
  16 siblings, 0 replies; 28+ messages in thread
From: Jiri Olsa @ 2014-06-12 22:08 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Arnaldo Carvalho de Melo, Corey Ashford, David Ahern,
	Frederic Weisbecker, Ingo Molnar, Jean Pihet, Namhyung Kim,
	Paul Mackerras, Peter Zijlstra

Move ordered events code into separated object ordered-events.[ch].

Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jean Pihet <jean.pihet@linaro.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/Makefile.perf         |   2 +
 tools/perf/util/ordered-events.c | 193 +++++++++++++++++++++++++++++++++++++
 tools/perf/util/ordered-events.h |  43 +++++++++
 tools/perf/util/session.c        | 203 ---------------------------------------
 tools/perf/util/session.h        |  17 +---
 5 files changed, 239 insertions(+), 219 deletions(-)
 create mode 100644 tools/perf/util/ordered-events.c
 create mode 100644 tools/perf/util/ordered-events.h

diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 9670a16..1351cfe 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -263,6 +263,7 @@ LIB_H += util/xyarray.h
 LIB_H += util/header.h
 LIB_H += util/help.h
 LIB_H += util/session.h
+LIB_H += util/ordered-events.h
 LIB_H += util/strbuf.h
 LIB_H += util/strlist.h
 LIB_H += util/strfilter.h
@@ -345,6 +346,7 @@ LIB_OBJS += $(OUTPUT)util/machine.o
 LIB_OBJS += $(OUTPUT)util/map.o
 LIB_OBJS += $(OUTPUT)util/pstack.o
 LIB_OBJS += $(OUTPUT)util/session.o
+LIB_OBJS += $(OUTPUT)util/ordered-events.o
 LIB_OBJS += $(OUTPUT)util/comm.o
 LIB_OBJS += $(OUTPUT)util/thread.o
 LIB_OBJS += $(OUTPUT)util/thread_map.o
diff --git a/tools/perf/util/ordered-events.c b/tools/perf/util/ordered-events.c
new file mode 100644
index 0000000..2d943eb
--- /dev/null
+++ b/tools/perf/util/ordered-events.c
@@ -0,0 +1,193 @@
+#include <linux/list.h>
+#include "ordered-events.h"
+#include "evlist.h"
+#include "session.h"
+#include "asm/bug.h"
+
+static void queue_event(struct ordered_events_queue *q, struct ordered_event *new)
+{
+	struct ordered_event *last = q->last;
+	u64 timestamp = new->timestamp;
+	struct list_head *p;
+
+	++q->nr_events;
+	q->last = new;
+
+	if (!last) {
+		list_add(&new->list, &q->events);
+		q->max_timestamp = timestamp;
+		return;
+	}
+
+	/*
+	 * last event might point to some random place in the list as it's
+	 * the last queued event. We expect that the new event is clqe to
+	 * this.
+	 */
+	if (last->timestamp <= timestamp) {
+		while (last->timestamp <= timestamp) {
+			p = last->list.next;
+			if (p == &q->events) {
+				list_add_tail(&new->list, &q->events);
+				q->max_timestamp = timestamp;
+				return;
+			}
+			last = list_entry(p, struct ordered_event, list);
+		}
+		list_add_tail(&new->list, &last->list);
+	} else {
+		while (last->timestamp > timestamp) {
+			p = last->list.prev;
+			if (p == &q->events) {
+				list_add(&new->list, &q->events);
+				return;
+			}
+			last = list_entry(p, struct ordered_event, list);
+		}
+		list_add(&new->list, &last->list);
+	}
+}
+
+#define MAX_SAMPLE_BUFFER	(64 * 1024 / sizeof(struct ordered_event))
+static struct ordered_event *alloc_event(struct ordered_events_queue *q)
+{
+	struct list_head *cache = &q->cache;
+	struct ordered_event *new = NULL;
+
+	if (!list_empty(cache)) {
+		new = list_entry(cache->next, struct ordered_event, list);
+		list_del(&new->list);
+	} else if (q->buffer) {
+		new = q->buffer + q->buffer_idx;
+		if (++q->buffer_idx == MAX_SAMPLE_BUFFER)
+			q->buffer = NULL;
+	} else if (q->cur_alloc_size < q->max_alloc_size) {
+		size_t size = MAX_SAMPLE_BUFFER * sizeof(*new);
+
+		q->buffer = malloc(size);
+		if (!q->buffer)
+			return NULL;
+
+		q->cur_alloc_size += size;
+		list_add(&q->buffer->list, &q->to_free);
+		q->buffer_idx = 2;
+		new = q->buffer + 1;
+	}
+
+	return new;
+}
+
+struct ordered_event*
+ordered_events_get(struct ordered_events_queue *q, u64 timestamp)
+{
+	struct ordered_event *new;
+
+	new = alloc_event(q);
+	if (new) {
+		new->timestamp = timestamp;
+		queue_event(q, new);
+	}
+
+	return new;
+}
+
+void
+ordered_event_put(struct ordered_events_queue *q, struct ordered_event *iter)
+{
+	list_del(&iter->list);
+	list_add(&iter->list, &q->cache);
+	q->nr_events--;
+}
+
+static int __ordered_events_flush(struct perf_session *s,
+				  struct perf_tool *tool)
+{
+	struct ordered_events_queue *q = &s->ordered_events;
+	struct list_head *head = &q->events;
+	struct ordered_event *tmp, *iter;
+	struct perf_sample sample;
+	u64 limit = q->next_flush;
+	u64 last_ts = q->last ? q->last->timestamp : 0ULL;
+	bool show_progress = limit == ULLONG_MAX;
+	struct ui_progress prog;
+	int ret;
+
+	if (!tool->ordered_events || !limit)
+		return 0;
+
+	if (show_progress)
+		ui_progress__init(&prog, q->nr_events, "Processing time ordered events...");
+
+	list_for_each_entry_safe(iter, tmp, head, list) {
+		if (session_done())
+			return 0;
+
+		if (iter->timestamp > limit)
+			break;
+
+		ret = perf_evlist__parse_sample(s->evlist, iter->event, &sample);
+		if (ret)
+			pr_err("Can't parse sample, err = %d\n", ret);
+		else {
+			ret = perf_session_deliver_event(s, iter->event, &sample, tool,
+							 iter->file_offset);
+			if (ret)
+				return ret;
+		}
+
+		ordered_event_put(q, iter);
+		q->last_flush = iter->timestamp;
+
+		if (show_progress)
+			ui_progress__update(&prog, 1);
+	}
+
+	if (list_empty(head))
+		q->last = NULL;
+	else if (last_ts <= limit)
+		q->last = list_entry(head->prev, struct ordered_event, list);
+
+	return 0;
+}
+
+int ordered_events_flush(struct perf_session *s, struct perf_tool *tool,
+			 enum oeq_flush how)
+{
+	struct ordered_events_queue *q = &s->ordered_events;
+	int err;
+
+	switch (how) {
+	case OEQ_FLUSH__FINAL:
+		q->next_flush = ULLONG_MAX;
+		break;
+
+	case OEQ_FLUSH__HALF:
+	{
+		struct ordered_event *first, *last;
+		struct list_head *head = &q->events;
+
+		first = list_entry(head->next, struct ordered_event, list);
+		last = q->last;
+
+		if (WARN_ONCE(!last || list_empty(head), "empty queue"))
+			return 0;
+
+		q->next_flush  = first->timestamp;
+		q->next_flush += (last->timestamp - first->timestamp) / 2;
+		break;
+	}
+
+	case OEQ_FLUSH__ROUND:
+	default:
+		break;
+	};
+
+	err = __ordered_events_flush(s, tool);
+
+	if (!err) {
+		if (how == OEQ_FLUSH__ROUND)
+			q->next_flush = q->max_timestamp;
+	}
+
+	return err;
+}
diff --git a/tools/perf/util/ordered-events.h b/tools/perf/util/ordered-events.h
new file mode 100644
index 0000000..c0dc00e
--- /dev/null
+++ b/tools/perf/util/ordered-events.h
@@ -0,0 +1,43 @@
+#ifndef __ORDERED_EVENTS_H
+#define __ORDERED_EVENTS_H
+
+#include <linux/types.h>
+#include "tool.h"
+
+struct perf_session;
+
+struct ordered_event {
+	u64			timestamp;
+	u64			file_offset;
+	union perf_event	*event;
+	struct list_head	list;
+};
+
+enum oeq_flush {
+	OEQ_FLUSH__FINAL,
+	OEQ_FLUSH__ROUND,
+	OEQ_FLUSH__HALF,
+};
+
+struct ordered_events_queue {
+	u64			last_flush;
+	u64			next_flush;
+	u64			max_timestamp;
+	u64			max_alloc_size;
+	u64			cur_alloc_size;
+	struct list_head	events;
+	struct list_head	cache;
+	struct list_head	to_free;
+	struct ordered_event	*buffer;
+	struct ordered_event	*last;
+	int			buffer_idx;
+	unsigned int		nr_events;
+};
+
+struct ordered_event *ordered_events_get(struct ordered_events_queue *q,
+					 u64 timestamp);
+void ordered_event_put(struct ordered_events_queue *q,
+		       struct ordered_event *iter);
+int ordered_events_flush(struct perf_session *s, struct perf_tool *tool,
+			 enum oeq_flush how);
+#endif /* __ORDERED_EVENTS_H */
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 08aa245..0548d72 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -15,7 +15,6 @@
 #include "cpumap.h"
 #include "perf_regs.h"
 #include "vdso.h"
-#include "asm/bug.h"
 
 static int perf_session__open(struct perf_session *session)
 {
@@ -449,19 +448,6 @@ static perf_event__swap_op perf_event__swap_ops[] = {
 	[PERF_RECORD_HEADER_MAX]	  = NULL,
 };
 
-struct ordered_event {
-	u64			timestamp;
-	u64			file_offset;
-	union perf_event	*event;
-	struct list_head	list;
-};
-
-enum oeq_flush {
-	OEQ_FLUSH__FINAL,
-	OEQ_FLUSH__ROUND,
-	OEQ_FLUSH__HALF,
-};
-
 static void perf_session_free_sample_buffers(struct perf_session *session)
 {
 	struct ordered_events_queue *q = &session->ordered_events;
@@ -475,195 +461,6 @@ static void perf_session_free_sample_buffers(struct perf_session *session)
 	}
 }
 
-/* The queue is ordered by time */
-static void queue_event(struct ordered_events_queue *q, struct ordered_event *new)
-{
-	struct ordered_event *last = q->last;
-	u64 timestamp = new->timestamp;
-	struct list_head *p;
-
-	++q->nr_events;
-	q->last = new;
-
-	if (!last) {
-		list_add(&new->list, &q->events);
-		q->max_timestamp = timestamp;
-		return;
-	}
-
-	/*
-	 * last event might point to some random place in the list as it's
-	 * the last queued event. We expect that the new event is clqe to
-	 * this.
-	 */
-	if (last->timestamp <= timestamp) {
-		while (last->timestamp <= timestamp) {
-			p = last->list.next;
-			if (p == &q->events) {
-				list_add_tail(&new->list, &q->events);
-				q->max_timestamp = timestamp;
-				return;
-			}
-			last = list_entry(p, struct ordered_event, list);
-		}
-		list_add_tail(&new->list, &last->list);
-	} else {
-		while (last->timestamp > timestamp) {
-			p = last->list.prev;
-			if (p == &q->events) {
-				list_add(&new->list, &q->events);
-				return;
-			}
-			last = list_entry(p, struct ordered_event, list);
-		}
-		list_add(&new->list, &last->list);
-	}
-}
-
-#define MAX_SAMPLE_BUFFER	(64 * 1024 / sizeof(struct ordered_event))
-static struct ordered_event *alloc_event(struct ordered_events_queue *q)
-{
-	struct list_head *cache = &q->cache;
-	struct ordered_event *new = NULL;
-
-	if (!list_empty(cache)) {
-		new = list_entry(cache->next, struct ordered_event, list);
-		list_del(&new->list);
-	} else if (q->buffer) {
-		new = q->buffer + q->buffer_idx;
-		if (++q->buffer_idx == MAX_SAMPLE_BUFFER)
-			q->buffer = NULL;
-	} else if (q->cur_alloc_size < q->max_alloc_size) {
-		size_t size = MAX_SAMPLE_BUFFER * sizeof(*new);
-
-		q->buffer = malloc(size);
-		if (!q->buffer)
-			return NULL;
-
-		q->cur_alloc_size += size;
-		list_add(&q->buffer->list, &q->to_free);
-		q->buffer_idx = 2;
-		new = q->buffer + 1;
-	}
-
-	return new;
-}
-
-static struct ordered_event*
-ordered_events_get(struct ordered_events_queue *q, u64 timestamp)
-{
-	struct ordered_event *new;
-
-	new = alloc_event(q);
-	if (new) {
-		new->timestamp = timestamp;
-		queue_event(q, new);
-	}
-
-	return new;
-}
-
-static void
-ordered_event_put(struct ordered_events_queue *q, struct ordered_event *iter)
-{
-	list_del(&iter->list);
-	list_add(&iter->list, &q->cache);
-	q->nr_events--;
-}
-
-static int __ordered_events_flush(struct perf_session *s,
-				  struct perf_tool *tool)
-{
-	struct ordered_events_queue *q = &s->ordered_events;
-	struct list_head *head = &q->events;
-	struct ordered_event *tmp, *iter;
-	struct perf_sample sample;
-	u64 limit = q->next_flush;
-	u64 last_ts = q->last ? q->last->timestamp : 0ULL;
-	bool show_progress = limit == ULLONG_MAX;
-	struct ui_progress prog;
-	int ret;
-
-	if (!tool->ordered_events || !limit)
-		return 0;
-
-	if (show_progress)
-		ui_progress__init(&prog, q->nr_events, "Processing time ordered events...");
-
-	list_for_each_entry_safe(iter, tmp, head, list) {
-		if (session_done())
-			return 0;
-
-		if (iter->timestamp > limit)
-			break;
-
-		ret = perf_evlist__parse_sample(s->evlist, iter->event, &sample);
-		if (ret)
-			pr_err("Can't parse sample, err = %d\n", ret);
-		else {
-			ret = perf_session_deliver_event(s, iter->event, &sample, tool,
-							 iter->file_offset);
-			if (ret)
-				return ret;
-		}
-
-		ordered_event_put(q, iter);
-		q->last_flush = iter->timestamp;
-
-		if (show_progress)
-			ui_progress__update(&prog, 1);
-	}
-
-	if (list_empty(head))
-		q->last = NULL;
-	else if (last_ts <= limit)
-		q->last = list_entry(head->prev, struct ordered_event, list);
-
-	return 0;
-}
-
-static int ordered_events_flush(struct perf_session *s, struct perf_tool *tool,
-				enum oeq_flush how)
-{
-	struct ordered_events_queue *q = &s->ordered_events;
-	int err;
-
-	switch (how) {
-	case OEQ_FLUSH__FINAL:
-		q->next_flush = ULLONG_MAX;
-		break;
-
-	case OEQ_FLUSH__HALF:
-	{
-		struct ordered_event *first, *last;
-		struct list_head *head = &q->events;
-
-		first = list_entry(head->next, struct ordered_event, list);
-		last = q->last;
-
-		if (WARN_ONCE(!last || list_empty(head), "empty queue"))
-			return 0;
-
-		q->next_flush  = first->timestamp;
-		q->next_flush += (last->timestamp - first->timestamp) / 2;
-		break;
-	}
-
-	case OEQ_FLUSH__ROUND:
-	default:
-		break;
-	};
-
-	err = __ordered_events_flush(s, tool);
-
-	if (!err) {
-		if (how == OEQ_FLUSH__ROUND)
-			q->next_flush = q->max_timestamp;
-	}
-
-	return err;
-}
-
 /*
  * When perf record finishes a pass on every buffers, it records this pseudo
  * event.
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h
index 58acad4..f8dcbf9 100644
--- a/tools/perf/util/session.h
+++ b/tools/perf/util/session.h
@@ -9,28 +9,13 @@
 #include "symbol.h"
 #include "thread.h"
 #include "data.h"
+#include "ordered-events.h"
 #include <linux/rbtree.h>
 #include <linux/perf_event.h>
 
-struct ordered_event;
 struct ip_callchain;
 struct thread;
 
-struct ordered_events_queue {
-	u64			last_flush;
-	u64			next_flush;
-	u64			max_timestamp;
-	u64			max_alloc_size;
-	u64			cur_alloc_size;
-	struct list_head	events;
-	struct list_head	cache;
-	struct list_head	to_free;
-	struct ordered_event	*buffer;
-	struct ordered_event	*last;
-	int			buffer_idx;
-	unsigned int		nr_events;
-};
-
 struct perf_session {
 	struct perf_header		header;
 	struct machines			machines;
-- 
1.8.3.1


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

* [PATCH 11/17] perf tools: Add ordered_events_queue_init function
  2014-06-12 22:08 [PATCH 00/17] perf tools: Factor ordered samples queue Jiri Olsa
                   ` (9 preceding siblings ...)
  2014-06-12 22:08 ` [PATCH 10/17] perf tools: Create ordered-events object Jiri Olsa
@ 2014-06-12 22:08 ` Jiri Olsa
  2014-06-12 22:08 ` [PATCH 12/17] perf tools: Add ordered_events_queue_free function Jiri Olsa
                   ` (5 subsequent siblings)
  16 siblings, 0 replies; 28+ messages in thread
From: Jiri Olsa @ 2014-06-12 22:08 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Arnaldo Carvalho de Melo, Corey Ashford, David Ahern,
	Frederic Weisbecker, Ingo Molnar, Jean Pihet, Namhyung Kim,
	Paul Mackerras, Peter Zijlstra

Adding ordered_events_queue_init function for struct
ordered_events_queue initialization.

Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jean Pihet <jean.pihet@linaro.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/util/ordered-events.c | 9 +++++++++
 tools/perf/util/ordered-events.h | 1 +
 tools/perf/util/session.c        | 6 +-----
 3 files changed, 11 insertions(+), 5 deletions(-)

diff --git a/tools/perf/util/ordered-events.c b/tools/perf/util/ordered-events.c
index 2d943eb..0ca34ee 100644
--- a/tools/perf/util/ordered-events.c
+++ b/tools/perf/util/ordered-events.c
@@ -191,3 +191,12 @@ int ordered_events_flush(struct perf_session *s, struct perf_tool *tool,
 
 	return err;
 }
+
+void ordered_events_queue_init(struct ordered_events_queue *q)
+{
+	INIT_LIST_HEAD(&q->events);
+	INIT_LIST_HEAD(&q->cache);
+	INIT_LIST_HEAD(&q->to_free);
+	q->max_alloc_size = (u64) -1;
+	q->cur_alloc_size = 0;
+}
diff --git a/tools/perf/util/ordered-events.h b/tools/perf/util/ordered-events.h
index c0dc00e..0633b09 100644
--- a/tools/perf/util/ordered-events.h
+++ b/tools/perf/util/ordered-events.h
@@ -40,4 +40,5 @@ void ordered_event_put(struct ordered_events_queue *q,
 		       struct ordered_event *iter);
 int ordered_events_flush(struct perf_session *s, struct perf_tool *tool,
 			 enum oeq_flush how);
+void ordered_events_queue_init(struct ordered_events_queue *q);
 #endif /* __ORDERED_EVENTS_H */
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 0548d72..09d1052 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -76,11 +76,7 @@ struct perf_session *perf_session__new(struct perf_data_file *file,
 		goto out;
 
 	session->repipe = repipe;
-	INIT_LIST_HEAD(&session->ordered_events.events);
-	INIT_LIST_HEAD(&session->ordered_events.cache);
-	INIT_LIST_HEAD(&session->ordered_events.to_free);
-	session->ordered_events.max_alloc_size = (u64) -1;
-	session->ordered_events.cur_alloc_size = 0;
+	ordered_events_queue_init(&session->ordered_events);
 	machines__init(&session->machines);
 
 	if (file) {
-- 
1.8.3.1


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

* [PATCH 12/17] perf tools: Add ordered_events_queue_free function
  2014-06-12 22:08 [PATCH 00/17] perf tools: Factor ordered samples queue Jiri Olsa
                   ` (10 preceding siblings ...)
  2014-06-12 22:08 ` [PATCH 11/17] perf tools: Add ordered_events_queue_init function Jiri Olsa
@ 2014-06-12 22:08 ` Jiri Olsa
  2014-06-12 22:08 ` [PATCH 13/17] perf tools: Add perf_config_u64 function Jiri Olsa
                   ` (4 subsequent siblings)
  16 siblings, 0 replies; 28+ messages in thread
From: Jiri Olsa @ 2014-06-12 22:08 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Arnaldo Carvalho de Melo, Corey Ashford, David Ahern,
	Frederic Weisbecker, Ingo Molnar, Jean Pihet, Namhyung Kim,
	Paul Mackerras, Peter Zijlstra

Adding ordered_events_queue_free function to release all
the struct ordered_events_queue data. It's replacement
for former perf_session_free_sample_buffers function.

Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jean Pihet <jean.pihet@linaro.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/util/ordered-events.c | 11 +++++++++++
 tools/perf/util/ordered-events.h |  1 +
 tools/perf/util/session.c        | 17 ++---------------
 3 files changed, 14 insertions(+), 15 deletions(-)

diff --git a/tools/perf/util/ordered-events.c b/tools/perf/util/ordered-events.c
index 0ca34ee..eaf2c47 100644
--- a/tools/perf/util/ordered-events.c
+++ b/tools/perf/util/ordered-events.c
@@ -200,3 +200,14 @@ void ordered_events_queue_init(struct ordered_events_queue *q)
 	q->max_alloc_size = (u64) -1;
 	q->cur_alloc_size = 0;
 }
+
+void ordered_events_queue_free(struct ordered_events_queue *q)
+{
+	while (!list_empty(&q->to_free)) {
+		struct ordered_event *event;
+
+		event = list_entry(q->to_free.next, struct ordered_event, list);
+		list_del(&event->list);
+		free(event);
+	}
+}
diff --git a/tools/perf/util/ordered-events.h b/tools/perf/util/ordered-events.h
index 0633b09..25ec273 100644
--- a/tools/perf/util/ordered-events.h
+++ b/tools/perf/util/ordered-events.h
@@ -41,4 +41,5 @@ void ordered_event_put(struct ordered_events_queue *q,
 int ordered_events_flush(struct perf_session *s, struct perf_tool *tool,
 			 enum oeq_flush how);
 void ordered_events_queue_init(struct ordered_events_queue *q);
+void ordered_events_queue_free(struct ordered_events_queue *q);
 #endif /* __ORDERED_EVENTS_H */
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 09d1052..26bedac 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -444,19 +444,6 @@ static perf_event__swap_op perf_event__swap_ops[] = {
 	[PERF_RECORD_HEADER_MAX]	  = NULL,
 };
 
-static void perf_session_free_sample_buffers(struct perf_session *session)
-{
-	struct ordered_events_queue *q = &session->ordered_events;
-
-	while (!list_empty(&q->to_free)) {
-		struct ordered_event *sq;
-
-		sq = list_entry(q->to_free.next, struct ordered_event, list);
-		list_del(&sq->list);
-		free(sq);
-	}
-}
-
 /*
  * When perf record finishes a pass on every buffers, it records this pseudo
  * event.
@@ -1092,7 +1079,7 @@ done:
 out_err:
 	free(buf);
 	perf_session__warn_about_errors(session, tool);
-	perf_session_free_sample_buffers(session);
+	ordered_events_queue_free(&session->ordered_events);
 	return err;
 }
 
@@ -1227,7 +1214,7 @@ out:
 out_err:
 	ui_progress__finish();
 	perf_session__warn_about_errors(session, tool);
-	perf_session_free_sample_buffers(session);
+	ordered_events_queue_free(&session->ordered_events);
 	return err;
 }
 
-- 
1.8.3.1


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

* [PATCH 13/17] perf tools: Add perf_config_u64 function
  2014-06-12 22:08 [PATCH 00/17] perf tools: Factor ordered samples queue Jiri Olsa
                   ` (11 preceding siblings ...)
  2014-06-12 22:08 ` [PATCH 12/17] perf tools: Add ordered_events_queue_free function Jiri Olsa
@ 2014-06-12 22:08 ` Jiri Olsa
  2014-06-13 12:07   ` Namhyung Kim
  2014-06-12 22:08 ` [PATCH 14/17] perf tools: Add report.queue-size config file option Jiri Olsa
                   ` (3 subsequent siblings)
  16 siblings, 1 reply; 28+ messages in thread
From: Jiri Olsa @ 2014-06-12 22:08 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Arnaldo Carvalho de Melo, Corey Ashford, David Ahern,
	Frederic Weisbecker, Ingo Molnar, Jean Pihet, Namhyung Kim,
	Paul Mackerras, Peter Zijlstra, Jiri Olsa

From: Jiri Olsa <jolsa@redhat.com>

Adding perf_config_u64 function to be able to parse
'llong' values out of config file.

Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jean Pihet <jean.pihet@linaro.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/util/cache.h  |  1 +
 tools/perf/util/config.c | 22 ++++++++++++++++++++++
 2 files changed, 23 insertions(+)

diff --git a/tools/perf/util/cache.h b/tools/perf/util/cache.h
index 7b176dd..5cf9e1b 100644
--- a/tools/perf/util/cache.h
+++ b/tools/perf/util/cache.h
@@ -22,6 +22,7 @@ typedef int (*config_fn_t)(const char *, const char *, void *);
 extern int perf_default_config(const char *, const char *, void *);
 extern int perf_config(config_fn_t fn, void *);
 extern int perf_config_int(const char *, const char *);
+extern u64 perf_config_u64(const char *, const char *);
 extern int perf_config_bool(const char *, const char *);
 extern int config_error_nonbool(const char *);
 extern const char *perf_config_dirname(const char *, const char *);
diff --git a/tools/perf/util/config.c b/tools/perf/util/config.c
index 24519e1..e68bbe3 100644
--- a/tools/perf/util/config.c
+++ b/tools/perf/util/config.c
@@ -286,6 +286,20 @@ static int parse_unit_factor(const char *end, unsigned long *val)
 	return 0;
 }
 
+static int perf_parse_llong(const char *value, long long *ret)
+{
+	if (value && *value) {
+		char *end;
+		long val = strtoll(value, &end, 0);
+		unsigned long factor = 1;
+		if (!parse_unit_factor(end, &factor))
+			return 0;
+		*ret = val * factor;
+		return 1;
+	}
+	return 0;
+}
+
 static int perf_parse_long(const char *value, long *ret)
 {
 	if (value && *value) {
@@ -307,6 +321,14 @@ static void die_bad_config(const char *name)
 	die("bad config value for '%s'", name);
 }
 
+u64 perf_config_u64(const char *name, const char *value)
+{
+	long long ret = 0;
+	if (!perf_parse_llong(value, &ret))
+		die_bad_config(name);
+	return (u64) ret;
+}
+
 int perf_config_int(const char *name, const char *value)
 {
 	long ret = 0;
-- 
1.8.3.1


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

* [PATCH 14/17] perf tools: Add report.queue-size config file option
  2014-06-12 22:08 [PATCH 00/17] perf tools: Factor ordered samples queue Jiri Olsa
                   ` (12 preceding siblings ...)
  2014-06-12 22:08 ` [PATCH 13/17] perf tools: Add perf_config_u64 function Jiri Olsa
@ 2014-06-12 22:08 ` Jiri Olsa
  2014-06-13 12:08   ` Namhyung Kim
  2014-06-12 22:08 ` [PATCH 15/17] perf tools: Add debug prints for ordered events queue Jiri Olsa
                   ` (2 subsequent siblings)
  16 siblings, 1 reply; 28+ messages in thread
From: Jiri Olsa @ 2014-06-12 22:08 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Arnaldo Carvalho de Melo, Corey Ashford, David Ahern,
	Frederic Weisbecker, Ingo Molnar, Jean Pihet, Namhyung Kim,
	Paul Mackerras, Peter Zijlstra

Adding report.queue-size config file option to setup
the maximum allocation size for session's struct
ordered_events_queue object.

Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jean Pihet <jean.pihet@linaro.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/builtin-report.c      | 13 ++++++++++++-
 tools/perf/util/ordered-events.h |  6 ++++++
 2 files changed, 18 insertions(+), 1 deletion(-)

diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index c72cc5a..09b9d0c 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -58,17 +58,19 @@ struct report {
 	const char		*symbol_filter_str;
 	float			min_percent;
 	u64			nr_entries;
+	u64			queue_size;
 	DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS);
 };
 
 static int report__config(const char *var, const char *value, void *cb)
 {
+	struct report *rep = cb;
+
 	if (!strcmp(var, "report.group")) {
 		symbol_conf.event_group = perf_config_bool(var, value);
 		return 0;
 	}
 	if (!strcmp(var, "report.percent-limit")) {
-		struct report *rep = cb;
 		rep->min_percent = strtof(value, NULL);
 		return 0;
 	}
@@ -76,6 +78,10 @@ static int report__config(const char *var, const char *value, void *cb)
 		symbol_conf.cumulate_callchain = perf_config_bool(var, value);
 		return 0;
 	}
+	if (!strcmp(var, "report.queue-size")) {
+		rep->queue_size = perf_config_u64(var, value);
+		return 0;
+	}
 
 	return perf_default_config(var, value, cb);
 }
@@ -714,6 +720,11 @@ repeat:
 	if (session == NULL)
 		return -ENOMEM;
 
+	if (report.queue_size) {
+		ordered_events_queue_alloc_size(&session->ordered_events,
+						report.queue_size);
+	}
+
 	report.session = session;
 
 	has_br_stack = perf_header__has_feat(&session->header,
diff --git a/tools/perf/util/ordered-events.h b/tools/perf/util/ordered-events.h
index 25ec273..04cb295 100644
--- a/tools/perf/util/ordered-events.h
+++ b/tools/perf/util/ordered-events.h
@@ -42,4 +42,10 @@ int ordered_events_flush(struct perf_session *s, struct perf_tool *tool,
 			 enum oeq_flush how);
 void ordered_events_queue_init(struct ordered_events_queue *q);
 void ordered_events_queue_free(struct ordered_events_queue *q);
+
+static inline void
+ordered_events_queue_alloc_size(struct ordered_events_queue *q, u64 size)
+{
+	q->max_alloc_size = size;
+}
 #endif /* __ORDERED_EVENTS_H */
-- 
1.8.3.1


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

* [PATCH 15/17] perf tools: Add debug prints for ordered events queue
  2014-06-12 22:08 [PATCH 00/17] perf tools: Factor ordered samples queue Jiri Olsa
                   ` (13 preceding siblings ...)
  2014-06-12 22:08 ` [PATCH 14/17] perf tools: Add report.queue-size config file option Jiri Olsa
@ 2014-06-12 22:08 ` Jiri Olsa
  2014-06-13 12:12   ` Namhyung Kim
  2014-06-12 22:08 ` [PATCH 16/17] perf tools: Limit the ordered events queue by default to 100MB Jiri Olsa
  2014-06-12 22:08 ` [PATCH 17/17] perf tools: Allow out of order messages in forced flush Jiri Olsa
  16 siblings, 1 reply; 28+ messages in thread
From: Jiri Olsa @ 2014-06-12 22:08 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Arnaldo Carvalho de Melo, Corey Ashford, David Ahern,
	Frederic Weisbecker, Ingo Molnar, Jean Pihet, Namhyung Kim,
	Paul Mackerras, Peter Zijlstra

Adding some prints for ordered events queue, to help
debug issues.

Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jean Pihet <jean.pihet@linaro.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/builtin-report.c      |  4 +++
 tools/perf/util/ordered-events.c | 54 ++++++++++++++++++++++++++++++++++++++++
 tools/perf/util/ordered-events.h |  2 ++
 3 files changed, 60 insertions(+)

diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index 09b9d0c..130ab5c 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -82,6 +82,10 @@ static int report__config(const char *var, const char *value, void *cb)
 		rep->queue_size = perf_config_u64(var, value);
 		return 0;
 	}
+	if (!strcmp(var, "report.queue-debug")) {
+		debug_sample_queue = perf_config_int(var, value);
+		return 0;
+	}
 
 	return perf_default_config(var, value, cb);
 }
diff --git a/tools/perf/util/ordered-events.c b/tools/perf/util/ordered-events.c
index eaf2c47..80f1daa 100644
--- a/tools/perf/util/ordered-events.c
+++ b/tools/perf/util/ordered-events.c
@@ -4,6 +4,37 @@
 #include "session.h"
 #include "asm/bug.h"
 
+int debug_sample_queue;
+
+static int pr_level(int level, const char *fmt, ...)
+{
+	int ret = 0;
+
+	if (unlikely(debug_sample_queue >= level)) {
+		va_list args;
+
+		va_start(args, fmt);
+		ret = vfprintf(stderr, fmt, args);
+		va_end(args);
+	}
+
+	return ret;
+}
+
+#define pr_N(n, fmt, ...) \
+	pr_level(n, fmt, ##__VA_ARGS__)
+#define pr(fmt, ...)  pr_N(1, pr_fmt(fmt), ##__VA_ARGS__)
+
+static int pr_time(const char *str, u64 time)
+{
+	u64 secs, usecs, nsecs = time;
+
+	secs = nsecs / NSECS_PER_SEC;
+	nsecs -= secs * NSECS_PER_SEC;
+	usecs = nsecs / NSECS_PER_USEC;
+	return fprintf(stderr, "\t[%13lu.%06lu] %s\n", secs, usecs, str);
+}
+
 static void queue_event(struct ordered_events_queue *q, struct ordered_event *new)
 {
 	struct ordered_event *last = q->last;
@@ -68,6 +99,9 @@ static struct ordered_event *alloc_event(struct ordered_events_queue *q)
 		if (!q->buffer)
 			return NULL;
 
+		pr("alloc size %" PRIu64 "B, max %" PRIu64 "B\n",
+		   q->cur_alloc_size, q->max_alloc_size);
+
 		q->cur_alloc_size += size;
 		list_add(&q->buffer->list, &q->to_free);
 		q->buffer_idx = 2;
@@ -182,6 +216,19 @@ int ordered_events_flush(struct perf_session *s, struct perf_tool *tool,
 		break;
 	};
 
+	if (unlikely(debug_sample_queue)) {
+		static const char * const str[] = {
+			"FINAL",
+			"ROUND",
+			"HALF ",
+		};
+
+		fprintf(stderr, "ordered_events_flush %s, nr_events %u\n",
+			str[how], q->nr_events);
+		pr_time("next_flush",    q->next_flush);
+		pr_time("max_timestamp", q->max_timestamp);
+	}
+
 	err = __ordered_events_flush(s, tool);
 
 	if (!err) {
@@ -189,6 +236,13 @@ int ordered_events_flush(struct perf_session *s, struct perf_tool *tool,
 			q->next_flush = q->max_timestamp;
 	}
 
+	if (unlikely(debug_sample_queue)) {
+		fprintf(stderr, "ordered_events_flush nr_events %u\n",
+			q->nr_events);
+		pr_time("next_flush", q->next_flush);
+		pr_time("last_flush", q->last_flush);
+	}
+
 	return err;
 }
 
diff --git a/tools/perf/util/ordered-events.h b/tools/perf/util/ordered-events.h
index 04cb295..8a717de 100644
--- a/tools/perf/util/ordered-events.h
+++ b/tools/perf/util/ordered-events.h
@@ -48,4 +48,6 @@ ordered_events_queue_alloc_size(struct ordered_events_queue *q, u64 size)
 {
 	q->max_alloc_size = size;
 }
+
+extern int debug_sample_queue;
 #endif /* __ORDERED_EVENTS_H */
-- 
1.8.3.1


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

* [PATCH 16/17] perf tools: Limit the ordered events queue by default to 100MB
  2014-06-12 22:08 [PATCH 00/17] perf tools: Factor ordered samples queue Jiri Olsa
                   ` (14 preceding siblings ...)
  2014-06-12 22:08 ` [PATCH 15/17] perf tools: Add debug prints for ordered events queue Jiri Olsa
@ 2014-06-12 22:08 ` Jiri Olsa
  2014-06-12 22:08 ` [PATCH 17/17] perf tools: Allow out of order messages in forced flush Jiri Olsa
  16 siblings, 0 replies; 28+ messages in thread
From: Jiri Olsa @ 2014-06-12 22:08 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Arnaldo Carvalho de Melo, Corey Ashford, David Ahern,
	Frederic Weisbecker, Ingo Molnar, Jean Pihet, Namhyung Kim,
	Paul Mackerras, Peter Zijlstra

It's still configurable by report.queue-size config option,
but looks like 100MB limit is more sane than no limit at all.

There's some speedup for report on huge data files:

With the limit of 100 MB, I've got around 15% speedup on reporting
of ~10GB perf.data file.

  current code:
   621,685,704,665      cycles                    ( +-  0.52% )
   873,397,467,969      instructions              ( +-  0.00% )

     286.133268732 seconds time elapsed           ( +-  1.13% )

  with patches:
   603,933,987,185      cycles                    ( +-  0.45% )
   869,139,445,070      instructions              ( +-  0.00% )

     245.337510637 seconds time elapsed           ( +-  0.49% )

The speed up seems to be mainly in less cycles spent in servicing
page faults.

  current code:
     4.44%     0.01%  perf.old  [kernel.kallsyms]   [k] page_fault

  with patches:
     1.45%     0.00%      perf  [kernel.kallsyms]   [k] page_fault

  current code (faults event):
         6,643,807      faults                    ( +-  0.36% )

  with patches (faults event):
         2,214,756      faults                    ( +-  3.03% )

Also there's lower memory consuption.

Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jean Pihet <jean.pihet@linaro.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/util/ordered-events.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/tools/perf/util/ordered-events.c b/tools/perf/util/ordered-events.c
index 80f1daa..c47475e 100644
--- a/tools/perf/util/ordered-events.c
+++ b/tools/perf/util/ordered-events.c
@@ -251,7 +251,8 @@ void ordered_events_queue_init(struct ordered_events_queue *q)
 	INIT_LIST_HEAD(&q->events);
 	INIT_LIST_HEAD(&q->cache);
 	INIT_LIST_HEAD(&q->to_free);
-	q->max_alloc_size = (u64) -1;
+	/* 100MB limitation by default */
+	q->max_alloc_size = 100 * 1024 * 1024;
 	q->cur_alloc_size = 0;
 }
 
-- 
1.8.3.1


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

* [PATCH 17/17] perf tools: Allow out of order messages in forced flush
  2014-06-12 22:08 [PATCH 00/17] perf tools: Factor ordered samples queue Jiri Olsa
                   ` (15 preceding siblings ...)
  2014-06-12 22:08 ` [PATCH 16/17] perf tools: Limit the ordered events queue by default to 100MB Jiri Olsa
@ 2014-06-12 22:08 ` Jiri Olsa
  16 siblings, 0 replies; 28+ messages in thread
From: Jiri Olsa @ 2014-06-12 22:08 UTC (permalink / raw)
  To: linux-kernel
  Cc: Jiri Olsa, Arnaldo Carvalho de Melo, Corey Ashford, David Ahern,
	Frederic Weisbecker, Ingo Molnar, Jean Pihet, Namhyung Kim,
	Paul Mackerras, Peter Zijlstra

In forced flush (OEQ_FLUSH__HALF) we break the rules of the
flush timestamp via PERF_RECORD_FINISHED_ROUND event, so
we could get out of order event.

Do not force error in this case and also changing the
output warning to use WARN_ONCE.

Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jean Pihet <jean.pihet@linaro.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/perf/util/ordered-events.c | 4 ++++
 tools/perf/util/ordered-events.h | 2 ++
 tools/perf/util/session.c        | 8 ++++++--
 3 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/tools/perf/util/ordered-events.c b/tools/perf/util/ordered-events.c
index c47475e..f92c2d0 100644
--- a/tools/perf/util/ordered-events.c
+++ b/tools/perf/util/ordered-events.c
@@ -212,12 +212,14 @@ int ordered_events_flush(struct perf_session *s, struct perf_tool *tool,
 	}
 
 	case OEQ_FLUSH__ROUND:
+	case OEQ_FLUSH__NONE:
 	default:
 		break;
 	};
 
 	if (unlikely(debug_sample_queue)) {
 		static const char * const str[] = {
+			"NONE",
 			"FINAL",
 			"ROUND",
 			"HALF ",
@@ -234,6 +236,8 @@ int ordered_events_flush(struct perf_session *s, struct perf_tool *tool,
 	if (!err) {
 		if (how == OEQ_FLUSH__ROUND)
 			q->next_flush = q->max_timestamp;
+
+		q->last_flush_type = how;
 	}
 
 	if (unlikely(debug_sample_queue)) {
diff --git a/tools/perf/util/ordered-events.h b/tools/perf/util/ordered-events.h
index 8a717de..7e92688 100644
--- a/tools/perf/util/ordered-events.h
+++ b/tools/perf/util/ordered-events.h
@@ -14,6 +14,7 @@ struct ordered_event {
 };
 
 enum oeq_flush {
+	OEQ_FLUSH__NONE,
 	OEQ_FLUSH__FINAL,
 	OEQ_FLUSH__ROUND,
 	OEQ_FLUSH__HALF,
@@ -32,6 +33,7 @@ struct ordered_events_queue {
 	struct ordered_event	*last;
 	int			buffer_idx;
 	unsigned int		nr_events;
+	enum oeq_flush		last_flush_type;
 };
 
 struct ordered_event *ordered_events_get(struct ordered_events_queue *q,
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 26bedac..a954702 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -15,6 +15,7 @@
 #include "cpumap.h"
 #include "perf_regs.h"
 #include "vdso.h"
+#include "asm/bug.h"
 
 static int perf_session__open(struct perf_session *session)
 {
@@ -502,8 +503,11 @@ int perf_session_queue_event(struct perf_session *s, union perf_event *event,
 		return -ETIME;
 
 	if (timestamp < s->ordered_events.last_flush) {
-		printf("Warning: Timestamp below last timeslice flush\n");
-		return -EINVAL;
+		WARN_ONCE(1, "Timestamp below last timeslice flush\n");
+
+		/* We could get out of order messages after forced flush. */
+		if (q->last_flush_type != OEQ_FLUSH__HALF)
+			return -EINVAL;
 	}
 
 	new = ordered_events_get(q, timestamp);
-- 
1.8.3.1


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

* Re: [PATCH 01/17] perf tools: Always force PERF_RECORD_FINISHED_ROUND event
  2014-06-12 22:08 ` [PATCH 01/17] perf tools: Always force PERF_RECORD_FINISHED_ROUND event Jiri Olsa
@ 2014-06-13 11:51   ` Namhyung Kim
  2014-06-15 17:17     ` Jiri Olsa
  0 siblings, 1 reply; 28+ messages in thread
From: Namhyung Kim @ 2014-06-13 11:51 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: linux-kernel, Arnaldo Carvalho de Melo, Corey Ashford,
	David Ahern, Frederic Weisbecker, Ingo Molnar, Jean Pihet,
	Paul Mackerras, Peter Zijlstra

Hi Jiri,

2014-06-13 (금), 00:08 +0200, Jiri Olsa:
> The PERF_RECORD_FINISHED_ROUND governs queue flushing in
> reporting, so it needs to be stored for any kind of event.
> 
> Forcing the PERF_RECORD_FINISHED_ROUND event to be stored any
> time we finish the round and wrote at least one event.
> 
> Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
> Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
> Cc: David Ahern <dsahern@gmail.com>
> Cc: Frederic Weisbecker <fweisbec@gmail.com>
> Cc: Ingo Molnar <mingo@kernel.org>
> Cc: Jean Pihet <jean.pihet@linaro.org>
> Cc: Namhyung Kim <namhyung@kernel.org>
> Cc: Paul Mackerras <paulus@samba.org>
> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
> Signed-off-by: Jiri Olsa <jolsa@kernel.org>
> ---
>  tools/perf/builtin-record.c | 7 ++++++-
>  1 file changed, 6 insertions(+), 1 deletion(-)
> 
> diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
> index 378b85b..4869050 100644
> --- a/tools/perf/builtin-record.c
> +++ b/tools/perf/builtin-record.c
> @@ -238,6 +238,7 @@ static struct perf_event_header finished_round_event = {
>  
>  static int record__mmap_read_all(struct record *rec)
>  {
> +	u64 bytes_written = rec->bytes_written;
>  	int i;
>  	int rc = 0;
>  
> @@ -250,7 +251,11 @@ static int record__mmap_read_all(struct record *rec)
>  		}
>  	}
>  
> -	if (perf_header__has_feat(&rec->session->header, HEADER_TRACING_DATA))
> +	/*
> +	 * Mark the round finished in case we wrote
> +	 * at least one event.
> +	 */
> +	if (bytes_written != rec->bytes_written)
>  		rc = record__write(rec, &finished_round_event, sizeof(finished_round_event));

Hmm.. what was the rational behind the original code?  Why did it flush
the events only if session has tracepoint events?  Frederic?

I guess this change alone can impact the performance in your case.
Jiri, do you have a test result of it?

Thanks,
Namhyung



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

* Re: [PATCH 05/17] perf tools: Add ordered_events_(get|put) interface
  2014-06-12 22:08 ` [PATCH 05/17] perf tools: Add ordered_events_(get|put) interface Jiri Olsa
@ 2014-06-13 12:05   ` Namhyung Kim
  2014-06-15 17:27     ` Jiri Olsa
  0 siblings, 1 reply; 28+ messages in thread
From: Namhyung Kim @ 2014-06-13 12:05 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: linux-kernel, Arnaldo Carvalho de Melo, Corey Ashford,
	David Ahern, Frederic Weisbecker, Ingo Molnar, Jean Pihet,
	Paul Mackerras, Peter Zijlstra

2014-06-13 (금), 00:08 +0200, Jiri Olsa:
> +#define MAX_SAMPLE_BUFFER	(64 * 1024 / sizeof(struct ordered_event))
> +static struct ordered_event *alloc_event(struct ordered_events_queue *q)
> +{
> +	struct list_head *cache = &q->cache;
> +	struct ordered_event *new;
> +
> +	if (!list_empty(cache)) {
> +		new = list_entry(cache->next, struct ordered_event, list);
> +		list_del(&new->list);
> +	} else if (q->buffer) {
> +		new = q->buffer + q->buffer_idx;
> +		if (++q->buffer_idx == MAX_SAMPLE_BUFFER)
> +			q->buffer = NULL;
> +	} else {
> +		q->buffer = malloc(MAX_SAMPLE_BUFFER * sizeof(*new));
> +		if (!q->buffer)
> +			return NULL;
> +		list_add(&q->buffer->list, &q->to_free);
> +		q->buffer_idx = 2;
> +		new = q->buffer + 1;

Hmm.. can we add a comment that the first entry is abused to maintain
the to_free list?


> +	}
> +
> +	return new;
> +}
> +
> +static struct ordered_event*
> +ordered_events_get(struct ordered_events_queue *q, u64 timestamp)
> +{
> +	struct ordered_event *new;
> +
> +	new = alloc_event(q);
> +	if (new) {
> +		new->timestamp = timestamp;
> +		queue_event(q, new);
> +	}
> +
> +	return new;
> +}
> +
> +static void
> +ordered_event_put(struct ordered_events_queue *q, struct ordered_event *iter)
> +{
> +	list_del(&iter->list);
> +	list_add(&iter->list, &q->cache);

list_move(&iter->list, &q->cache) ?

> +	q->nr_events--;
> +}


[SNIP]
> @@ -639,29 +681,13 @@ int perf_session_queue_event(struct perf_session *s, union perf_event *event,
>  		return -EINVAL;
>  	}
>  
> -	if (!list_empty(cache)) {
> -		new = list_entry(cache->next, struct ordered_event, list);
> -		list_del(&new->list);
> -	} else if (q->buffer) {
> -		new = q->buffer + q->buffer_idx;
> -		if (++q->buffer_idx == MAX_SAMPLE_BUFFER)
> -			q->buffer = NULL;
> -	} else {
> -		q->buffer = malloc(MAX_SAMPLE_BUFFER * sizeof(*new));
> -		if (!q->buffer)
> -			return -ENOMEM;
> -		list_add(&q->buffer->list, &q->to_free);
> -		q->buffer_idx = 2;
> -		new = q->buffer + 1;
> +	new = ordered_events_get(q, timestamp);
> +	if (new) {
> +		new->file_offset = file_offset;
> +		new->event = event;
>  	}

What about make it like below:

	if (!new)
		return -ENOMEM;

This way we can share more of the original code.

Thanks,
Namhyung


>  
> -	new->timestamp = timestamp;
> -	new->file_offset = file_offset;
> -	new->event = event;
> -
> -	__queue_event(new, s);
> -
> -	return 0;
> +	return new ? 0 : -ENOMEM;
>  }
>  
>  static void callchain__printf(struct perf_sample *sample)




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

* Re: [PATCH 13/17] perf tools: Add perf_config_u64 function
  2014-06-12 22:08 ` [PATCH 13/17] perf tools: Add perf_config_u64 function Jiri Olsa
@ 2014-06-13 12:07   ` Namhyung Kim
  2014-06-15 17:48     ` Jiri Olsa
  0 siblings, 1 reply; 28+ messages in thread
From: Namhyung Kim @ 2014-06-13 12:07 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: linux-kernel, Jiri Olsa, Arnaldo Carvalho de Melo, Corey Ashford,
	David Ahern, Frederic Weisbecker, Ingo Molnar, Jean Pihet,
	Paul Mackerras, Peter Zijlstra

2014-06-13 (금), 00:08 +0200, Jiri Olsa:
> From: Jiri Olsa <jolsa@redhat.com>
> 
> Adding perf_config_u64 function to be able to parse
> 'llong' values out of config file.
> 
> Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
> Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
> Cc: David Ahern <dsahern@gmail.com>
> Cc: Frederic Weisbecker <fweisbec@gmail.com>
> Cc: Ingo Molnar <mingo@kernel.org>
> Cc: Jean Pihet <jean.pihet@linaro.org>
> Cc: Namhyung Kim <namhyung@kernel.org>
> Cc: Paul Mackerras <paulus@samba.org>
> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
> Signed-off-by: Jiri Olsa <jolsa@kernel.org>
> ---
>  tools/perf/util/cache.h  |  1 +
>  tools/perf/util/config.c | 22 ++++++++++++++++++++++
>  2 files changed, 23 insertions(+)
> 
> diff --git a/tools/perf/util/cache.h b/tools/perf/util/cache.h
> index 7b176dd..5cf9e1b 100644
> --- a/tools/perf/util/cache.h
> +++ b/tools/perf/util/cache.h
> @@ -22,6 +22,7 @@ typedef int (*config_fn_t)(const char *, const char *, void *);
>  extern int perf_default_config(const char *, const char *, void *);
>  extern int perf_config(config_fn_t fn, void *);
>  extern int perf_config_int(const char *, const char *);
> +extern u64 perf_config_u64(const char *, const char *);
>  extern int perf_config_bool(const char *, const char *);
>  extern int config_error_nonbool(const char *);
>  extern const char *perf_config_dirname(const char *, const char *);
> diff --git a/tools/perf/util/config.c b/tools/perf/util/config.c
> index 24519e1..e68bbe3 100644
> --- a/tools/perf/util/config.c
> +++ b/tools/perf/util/config.c
> @@ -286,6 +286,20 @@ static int parse_unit_factor(const char *end, unsigned long *val)
>  	return 0;
>  }
>  
> +static int perf_parse_llong(const char *value, long long *ret)
> +{
> +	if (value && *value) {
> +		char *end;
> +		long val = strtoll(value, &end, 0);

Why not declare the val as long long?

> +		unsigned long factor = 1;

Also please add a blank line between declaration and actual body.

Thanks,
Namhyung


> +		if (!parse_unit_factor(end, &factor))
> +			return 0;
> +		*ret = val * factor;
> +		return 1;
> +	}
> +	return 0;
> +}
> +
>  static int perf_parse_long(const char *value, long *ret)
>  {
>  	if (value && *value) {
> @@ -307,6 +321,14 @@ static void die_bad_config(const char *name)
>  	die("bad config value for '%s'", name);
>  }
>  
> +u64 perf_config_u64(const char *name, const char *value)
> +{
> +	long long ret = 0;
> +	if (!perf_parse_llong(value, &ret))
> +		die_bad_config(name);
> +	return (u64) ret;
> +}
> +
>  int perf_config_int(const char *name, const char *value)
>  {
>  	long ret = 0;




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

* Re: [PATCH 14/17] perf tools: Add report.queue-size config file option
  2014-06-12 22:08 ` [PATCH 14/17] perf tools: Add report.queue-size config file option Jiri Olsa
@ 2014-06-13 12:08   ` Namhyung Kim
  2014-06-15 17:54     ` Jiri Olsa
  0 siblings, 1 reply; 28+ messages in thread
From: Namhyung Kim @ 2014-06-13 12:08 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: linux-kernel, Arnaldo Carvalho de Melo, Corey Ashford,
	David Ahern, Frederic Weisbecker, Ingo Molnar, Jean Pihet,
	Paul Mackerras, Peter Zijlstra

2014-06-13 (금), 00:08 +0200, Jiri Olsa:
> Adding report.queue-size config file option to setup
> the maximum allocation size for session's struct
> ordered_events_queue object.

Only a config option without a command line switch?

Thanks,
Namhyung




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

* Re: [PATCH 15/17] perf tools: Add debug prints for ordered events queue
  2014-06-12 22:08 ` [PATCH 15/17] perf tools: Add debug prints for ordered events queue Jiri Olsa
@ 2014-06-13 12:12   ` Namhyung Kim
  2014-06-15 17:58     ` Jiri Olsa
  0 siblings, 1 reply; 28+ messages in thread
From: Namhyung Kim @ 2014-06-13 12:12 UTC (permalink / raw)
  To: Jiri Olsa
  Cc: linux-kernel, Arnaldo Carvalho de Melo, Corey Ashford,
	David Ahern, Frederic Weisbecker, Ingo Molnar, Jean Pihet,
	Paul Mackerras, Peter Zijlstra

2014-06-13 (금), 00:08 +0200, Jiri Olsa:
> Adding some prints for ordered events queue, to help
> debug issues.
> 
> Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
> Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
> Cc: David Ahern <dsahern@gmail.com>
> Cc: Frederic Weisbecker <fweisbec@gmail.com>
> Cc: Ingo Molnar <mingo@kernel.org>
> Cc: Jean Pihet <jean.pihet@linaro.org>
> Cc: Namhyung Kim <namhyung@kernel.org>
> Cc: Paul Mackerras <paulus@samba.org>
> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
> Signed-off-by: Jiri Olsa <jolsa@kernel.org>
> ---
>  tools/perf/builtin-report.c      |  4 +++
>  tools/perf/util/ordered-events.c | 54 ++++++++++++++++++++++++++++++++++++++++
>  tools/perf/util/ordered-events.h |  2 ++
>  3 files changed, 60 insertions(+)
> 
> diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
> index 09b9d0c..130ab5c 100644
> --- a/tools/perf/builtin-report.c
> +++ b/tools/perf/builtin-report.c
> @@ -82,6 +82,10 @@ static int report__config(const char *var, const char *value, void *cb)
>  		rep->queue_size = perf_config_u64(var, value);
>  		return 0;
>  	}
> +	if (!strcmp(var, "report.queue-debug")) {
> +		debug_sample_queue = perf_config_int(var, value);
> +		return 0;
> +	}

Again, config option only?


>  
>  	return perf_default_config(var, value, cb);
>  }
> diff --git a/tools/perf/util/ordered-events.c b/tools/perf/util/ordered-events.c
> index eaf2c47..80f1daa 100644
> --- a/tools/perf/util/ordered-events.c
> +++ b/tools/perf/util/ordered-events.c
> @@ -4,6 +4,37 @@
>  #include "session.h"
>  #include "asm/bug.h"
>  
> +int debug_sample_queue;
> +
> +static int pr_level(int level, const char *fmt, ...)
> +{
> +	int ret = 0;
> +
> +	if (unlikely(debug_sample_queue >= level)) {
> +		va_list args;
> +
> +		va_start(args, fmt);
> +		ret = vfprintf(stderr, fmt, args);
> +		va_end(args);
> +	}
> +
> +	return ret;
> +}
> +
> +#define pr_N(n, fmt, ...) \
> +	pr_level(n, fmt, ##__VA_ARGS__)
> +#define pr(fmt, ...)  pr_N(1, pr_fmt(fmt), ##__VA_ARGS__)
> +
> +static int pr_time(const char *str, u64 time)
> +{
> +	u64 secs, usecs, nsecs = time;
> +
> +	secs = nsecs / NSECS_PER_SEC;
> +	nsecs -= secs * NSECS_PER_SEC;
> +	usecs = nsecs / NSECS_PER_USEC;
> +	return fprintf(stderr, "\t[%13lu.%06lu] %s\n", secs, usecs, str);
> +}

It'd be better if these functions somehow reuse existing pr_* functions
or at least honor the use_browser value IMHO.

Thanks,
Namhyung


> +
>  static void queue_event(struct ordered_events_queue *q, struct ordered_event *new)
>  {
>  	struct ordered_event *last = q->last;
> @@ -68,6 +99,9 @@ static struct ordered_event *alloc_event(struct ordered_events_queue *q)
>  		if (!q->buffer)
>  			return NULL;
>  
> +		pr("alloc size %" PRIu64 "B, max %" PRIu64 "B\n",
> +		   q->cur_alloc_size, q->max_alloc_size);
> +
>  		q->cur_alloc_size += size;
>  		list_add(&q->buffer->list, &q->to_free);
>  		q->buffer_idx = 2;
> @@ -182,6 +216,19 @@ int ordered_events_flush(struct perf_session *s, struct perf_tool *tool,
>  		break;
>  	};
>  
> +	if (unlikely(debug_sample_queue)) {
> +		static const char * const str[] = {
> +			"FINAL",
> +			"ROUND",
> +			"HALF ",
> +		};
> +
> +		fprintf(stderr, "ordered_events_flush %s, nr_events %u\n",
> +			str[how], q->nr_events);
> +		pr_time("next_flush",    q->next_flush);
> +		pr_time("max_timestamp", q->max_timestamp);
> +	}
> +
>  	err = __ordered_events_flush(s, tool);
>  
>  	if (!err) {
> @@ -189,6 +236,13 @@ int ordered_events_flush(struct perf_session *s, struct perf_tool *tool,
>  			q->next_flush = q->max_timestamp;
>  	}
>  
> +	if (unlikely(debug_sample_queue)) {
> +		fprintf(stderr, "ordered_events_flush nr_events %u\n",
> +			q->nr_events);
> +		pr_time("next_flush", q->next_flush);
> +		pr_time("last_flush", q->last_flush);
> +	}
> +
>  	return err;
>  }
>  
> diff --git a/tools/perf/util/ordered-events.h b/tools/perf/util/ordered-events.h
> index 04cb295..8a717de 100644
> --- a/tools/perf/util/ordered-events.h
> +++ b/tools/perf/util/ordered-events.h
> @@ -48,4 +48,6 @@ ordered_events_queue_alloc_size(struct ordered_events_queue *q, u64 size)
>  {
>  	q->max_alloc_size = size;
>  }
> +
> +extern int debug_sample_queue;
>  #endif /* __ORDERED_EVENTS_H */




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

* Re: [PATCH 01/17] perf tools: Always force PERF_RECORD_FINISHED_ROUND event
  2014-06-13 11:51   ` Namhyung Kim
@ 2014-06-15 17:17     ` Jiri Olsa
  0 siblings, 0 replies; 28+ messages in thread
From: Jiri Olsa @ 2014-06-15 17:17 UTC (permalink / raw)
  To: Namhyung Kim
  Cc: Jiri Olsa, linux-kernel, Arnaldo Carvalho de Melo, Corey Ashford,
	David Ahern, Frederic Weisbecker, Ingo Molnar, Jean Pihet,
	Paul Mackerras, Peter Zijlstra

On Fri, Jun 13, 2014 at 08:51:54PM +0900, Namhyung Kim wrote:
> Hi Jiri,
> 
> 2014-06-13 (금), 00:08 +0200, Jiri Olsa:
> > The PERF_RECORD_FINISHED_ROUND governs queue flushing in
> > reporting, so it needs to be stored for any kind of event.
> > 
> > Forcing the PERF_RECORD_FINISHED_ROUND event to be stored any
> > time we finish the round and wrote at least one event.
> > 
> > Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
> > Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
> > Cc: David Ahern <dsahern@gmail.com>
> > Cc: Frederic Weisbecker <fweisbec@gmail.com>
> > Cc: Ingo Molnar <mingo@kernel.org>
> > Cc: Jean Pihet <jean.pihet@linaro.org>
> > Cc: Namhyung Kim <namhyung@kernel.org>
> > Cc: Paul Mackerras <paulus@samba.org>
> > Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
> > Signed-off-by: Jiri Olsa <jolsa@kernel.org>
> > ---
> >  tools/perf/builtin-record.c | 7 ++++++-
> >  1 file changed, 6 insertions(+), 1 deletion(-)
> > 
> > diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
> > index 378b85b..4869050 100644
> > --- a/tools/perf/builtin-record.c
> > +++ b/tools/perf/builtin-record.c
> > @@ -238,6 +238,7 @@ static struct perf_event_header finished_round_event = {
> >  
> >  static int record__mmap_read_all(struct record *rec)
> >  {
> > +	u64 bytes_written = rec->bytes_written;
> >  	int i;
> >  	int rc = 0;
> >  
> > @@ -250,7 +251,11 @@ static int record__mmap_read_all(struct record *rec)
> >  		}
> >  	}
> >  
> > -	if (perf_header__has_feat(&rec->session->header, HEADER_TRACING_DATA))
> > +	/*
> > +	 * Mark the round finished in case we wrote
> > +	 * at least one event.
> > +	 */
> > +	if (bytes_written != rec->bytes_written)
> >  		rc = record__write(rec, &finished_round_event, sizeof(finished_round_event));
> 
> Hmm.. what was the rational behind the original code?  Why did it flush
> the events only if session has tracepoint events?  Frederic?

looks like the reason was the reordering in report, as described
in commit 984028075794c00cbf4fb1e94bb6233e8be08875

but there's no info why is this only for tracepoints
(or when tracepoints events are included)

> I guess this change alone can impact the performance in your case.
> Jiri, do you have a test result of it?

the impact is an extra 64 bytes (event header size) in perf.data
each time we read data from all cpus

I can see the impact more on the report size, where this events
governs the flushing of the reordering queue. If there's no
'finish_round' event, the queue is flushed at the end of the
processing (which leads to issues I explained in patch 0).

Now this problem is workarounded by this patchset via using the
HALF flush any time we reach the maximum of the reordering queue
size.

Still I think it's better to have 'finish_round' event for
any kind of event workloads, to keep the standard/expected
reordering processing in the report command.

thanks,
jirka

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

* Re: [PATCH 05/17] perf tools: Add ordered_events_(get|put) interface
  2014-06-13 12:05   ` Namhyung Kim
@ 2014-06-15 17:27     ` Jiri Olsa
  0 siblings, 0 replies; 28+ messages in thread
From: Jiri Olsa @ 2014-06-15 17:27 UTC (permalink / raw)
  To: Namhyung Kim
  Cc: Jiri Olsa, linux-kernel, Arnaldo Carvalho de Melo, Corey Ashford,
	David Ahern, Frederic Weisbecker, Ingo Molnar, Jean Pihet,
	Paul Mackerras, Peter Zijlstra

On Fri, Jun 13, 2014 at 09:05:05PM +0900, Namhyung Kim wrote:
> 2014-06-13 (금), 00:08 +0200, Jiri Olsa:
> > +#define MAX_SAMPLE_BUFFER	(64 * 1024 / sizeof(struct ordered_event))
> > +static struct ordered_event *alloc_event(struct ordered_events_queue *q)
> > +{
> > +	struct list_head *cache = &q->cache;
> > +	struct ordered_event *new;
> > +
> > +	if (!list_empty(cache)) {
> > +		new = list_entry(cache->next, struct ordered_event, list);
> > +		list_del(&new->list);
> > +	} else if (q->buffer) {
> > +		new = q->buffer + q->buffer_idx;
> > +		if (++q->buffer_idx == MAX_SAMPLE_BUFFER)
> > +			q->buffer = NULL;
> > +	} else {
> > +		q->buffer = malloc(MAX_SAMPLE_BUFFER * sizeof(*new));
> > +		if (!q->buffer)
> > +			return NULL;
> > +		list_add(&q->buffer->list, &q->to_free);
> > +		q->buffer_idx = 2;
> > +		new = q->buffer + 1;
> 
> Hmm.. can we add a comment that the first entry is abused to maintain
> the to_free list?

ook

> 
> 
> > +	}
> > +
> > +	return new;
> > +}
> > +
> > +static struct ordered_event*
> > +ordered_events_get(struct ordered_events_queue *q, u64 timestamp)
> > +{
> > +	struct ordered_event *new;
> > +
> > +	new = alloc_event(q);
> > +	if (new) {
> > +		new->timestamp = timestamp;
> > +		queue_event(q, new);
> > +	}
> > +
> > +	return new;
> > +}
> > +
> > +static void
> > +ordered_event_put(struct ordered_events_queue *q, struct ordered_event *iter)
> > +{
> > +	list_del(&iter->list);
> > +	list_add(&iter->list, &q->cache);
> 
> list_move(&iter->list, &q->cache) ?

ok, I'll make that a separate patch, so it's obvious here
that I used the original code

> 
> > +	q->nr_events--;
> > +}
> 
> 
> [SNIP]
> > @@ -639,29 +681,13 @@ int perf_session_queue_event(struct perf_session *s, union perf_event *event,
> >  		return -EINVAL;
> >  	}
> >  
> > -	if (!list_empty(cache)) {
> > -		new = list_entry(cache->next, struct ordered_event, list);
> > -		list_del(&new->list);
> > -	} else if (q->buffer) {
> > -		new = q->buffer + q->buffer_idx;
> > -		if (++q->buffer_idx == MAX_SAMPLE_BUFFER)
> > -			q->buffer = NULL;
> > -	} else {
> > -		q->buffer = malloc(MAX_SAMPLE_BUFFER * sizeof(*new));
> > -		if (!q->buffer)
> > -			return -ENOMEM;
> > -		list_add(&q->buffer->list, &q->to_free);
> > -		q->buffer_idx = 2;
> > -		new = q->buffer + 1;
> > +	new = ordered_events_get(q, timestamp);
> > +	if (new) {
> > +		new->file_offset = file_offset;
> > +		new->event = event;
> >  	}
> 
> What about make it like below:
> 
> 	if (!new)
> 		return -ENOMEM;
> 
> This way we can share more of the original code.

ook, will do

thanks,
jirka

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

* Re: [PATCH 13/17] perf tools: Add perf_config_u64 function
  2014-06-13 12:07   ` Namhyung Kim
@ 2014-06-15 17:48     ` Jiri Olsa
  0 siblings, 0 replies; 28+ messages in thread
From: Jiri Olsa @ 2014-06-15 17:48 UTC (permalink / raw)
  To: Namhyung Kim
  Cc: Jiri Olsa, linux-kernel, Arnaldo Carvalho de Melo, Corey Ashford,
	David Ahern, Frederic Weisbecker, Ingo Molnar, Jean Pihet,
	Paul Mackerras, Peter Zijlstra

On Fri, Jun 13, 2014 at 09:07:43PM +0900, Namhyung Kim wrote:
> 2014-06-13 (금), 00:08 +0200, Jiri Olsa:
> > From: Jiri Olsa <jolsa@redhat.com>
> > 
> > Adding perf_config_u64 function to be able to parse
> > 'llong' values out of config file.
> > 
> > Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
> > Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
> > Cc: David Ahern <dsahern@gmail.com>
> > Cc: Frederic Weisbecker <fweisbec@gmail.com>
> > Cc: Ingo Molnar <mingo@kernel.org>
> > Cc: Jean Pihet <jean.pihet@linaro.org>
> > Cc: Namhyung Kim <namhyung@kernel.org>
> > Cc: Paul Mackerras <paulus@samba.org>
> > Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
> > Signed-off-by: Jiri Olsa <jolsa@kernel.org>
> > ---
> >  tools/perf/util/cache.h  |  1 +
> >  tools/perf/util/config.c | 22 ++++++++++++++++++++++
> >  2 files changed, 23 insertions(+)
> > 
> > diff --git a/tools/perf/util/cache.h b/tools/perf/util/cache.h
> > index 7b176dd..5cf9e1b 100644
> > --- a/tools/perf/util/cache.h
> > +++ b/tools/perf/util/cache.h
> > @@ -22,6 +22,7 @@ typedef int (*config_fn_t)(const char *, const char *, void *);
> >  extern int perf_default_config(const char *, const char *, void *);
> >  extern int perf_config(config_fn_t fn, void *);
> >  extern int perf_config_int(const char *, const char *);
> > +extern u64 perf_config_u64(const char *, const char *);
> >  extern int perf_config_bool(const char *, const char *);
> >  extern int config_error_nonbool(const char *);
> >  extern const char *perf_config_dirname(const char *, const char *);
> > diff --git a/tools/perf/util/config.c b/tools/perf/util/config.c
> > index 24519e1..e68bbe3 100644
> > --- a/tools/perf/util/config.c
> > +++ b/tools/perf/util/config.c
> > @@ -286,6 +286,20 @@ static int parse_unit_factor(const char *end, unsigned long *val)
> >  	return 0;
> >  }
> >  
> > +static int perf_parse_llong(const char *value, long long *ret)
> > +{
> > +	if (value && *value) {
> > +		char *end;
> > +		long val = strtoll(value, &end, 0);
> 
> Why not declare the val as long long?

copy/paste error ;-)

> 
> > +		unsigned long factor = 1;
> 
> Also please add a blank line between declaration and actual body.

ook, thanks,
jirka

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

* Re: [PATCH 14/17] perf tools: Add report.queue-size config file option
  2014-06-13 12:08   ` Namhyung Kim
@ 2014-06-15 17:54     ` Jiri Olsa
  0 siblings, 0 replies; 28+ messages in thread
From: Jiri Olsa @ 2014-06-15 17:54 UTC (permalink / raw)
  To: Namhyung Kim
  Cc: Jiri Olsa, linux-kernel, Arnaldo Carvalho de Melo, Corey Ashford,
	David Ahern, Frederic Weisbecker, Ingo Molnar, Jean Pihet,
	Paul Mackerras, Peter Zijlstra

On Fri, Jun 13, 2014 at 09:08:58PM +0900, Namhyung Kim wrote:
> 2014-06-13 (금), 00:08 +0200, Jiri Olsa:
> > Adding report.queue-size config file option to setup
> > the maximum allocation size for session's struct
> > ordered_events_queue object.
> 
> Only a config option without a command line switch?

Yea.. it did not seem necessary to me to add another
one to the report heap for this.

Also considering the default size I added (100MB) and quite low
level nature of this.. but I dont have strong opinion on this..

thoughts?

thanks,
jirka

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

* Re: [PATCH 15/17] perf tools: Add debug prints for ordered events queue
  2014-06-13 12:12   ` Namhyung Kim
@ 2014-06-15 17:58     ` Jiri Olsa
  0 siblings, 0 replies; 28+ messages in thread
From: Jiri Olsa @ 2014-06-15 17:58 UTC (permalink / raw)
  To: Namhyung Kim
  Cc: Jiri Olsa, linux-kernel, Arnaldo Carvalho de Melo, Corey Ashford,
	David Ahern, Frederic Weisbecker, Ingo Molnar, Jean Pihet,
	Paul Mackerras, Peter Zijlstra

On Fri, Jun 13, 2014 at 09:12:23PM +0900, Namhyung Kim wrote:
> 2014-06-13 (금), 00:08 +0200, Jiri Olsa:
> > Adding some prints for ordered events queue, to help
> > debug issues.
> > 
> > Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
> > Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
> > Cc: David Ahern <dsahern@gmail.com>
> > Cc: Frederic Weisbecker <fweisbec@gmail.com>
> > Cc: Ingo Molnar <mingo@kernel.org>
> > Cc: Jean Pihet <jean.pihet@linaro.org>
> > Cc: Namhyung Kim <namhyung@kernel.org>
> > Cc: Paul Mackerras <paulus@samba.org>
> > Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
> > Signed-off-by: Jiri Olsa <jolsa@kernel.org>
> > ---
> >  tools/perf/builtin-report.c      |  4 +++
> >  tools/perf/util/ordered-events.c | 54 ++++++++++++++++++++++++++++++++++++++++
> >  tools/perf/util/ordered-events.h |  2 ++
> >  3 files changed, 60 insertions(+)
> > 
> > diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
> > index 09b9d0c..130ab5c 100644
> > --- a/tools/perf/builtin-report.c
> > +++ b/tools/perf/builtin-report.c
> > @@ -82,6 +82,10 @@ static int report__config(const char *var, const char *value, void *cb)
> >  		rep->queue_size = perf_config_u64(var, value);
> >  		return 0;
> >  	}
> > +	if (!strcmp(var, "report.queue-debug")) {
> > +		debug_sample_queue = perf_config_int(var, value);
> > +		return 0;
> > +	}
> 
> Again, config option only?

same reason as for the previous one

> > +
> > +#define pr_N(n, fmt, ...) \
> > +	pr_level(n, fmt, ##__VA_ARGS__)
> > +#define pr(fmt, ...)  pr_N(1, pr_fmt(fmt), ##__VA_ARGS__)
> > +
> > +static int pr_time(const char *str, u64 time)
> > +{
> > +	u64 secs, usecs, nsecs = time;
> > +
> > +	secs = nsecs / NSECS_PER_SEC;
> > +	nsecs -= secs * NSECS_PER_SEC;
> > +	usecs = nsecs / NSECS_PER_USEC;
> > +	return fprintf(stderr, "\t[%13lu.%06lu] %s\n", secs, usecs, str);
> > +}
> 
> It'd be better if these functions somehow reuse existing pr_* functions
> or at least honor the use_browser value IMHO.

I wanted to separate this output so I could have it not
mixed with standard debug messages.. it could get messy

I was thinking maybe we want some smart debug/verbose system
that would allow this.. separate debug messages based on the
config/subsystem/option/objects/whatever implemented via
generic code

thanks,
jirka

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

end of thread, other threads:[~2014-06-15 17:59 UTC | newest]

Thread overview: 28+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-06-12 22:08 [PATCH 00/17] perf tools: Factor ordered samples queue Jiri Olsa
2014-06-12 22:08 ` [PATCH 01/17] perf tools: Always force PERF_RECORD_FINISHED_ROUND event Jiri Olsa
2014-06-13 11:51   ` Namhyung Kim
2014-06-15 17:17     ` Jiri Olsa
2014-06-12 22:08 ` [PATCH 02/17] perf tools: Fix accounting of ordered samples queue Jiri Olsa
2014-06-12 22:08 ` [PATCH 03/17] perf tools: Rename ordered_samples to ordered_events Jiri Olsa
2014-06-12 22:08 ` [PATCH 04/17] perf tools: Rename ordered_events_queue members Jiri Olsa
2014-06-12 22:08 ` [PATCH 05/17] perf tools: Add ordered_events_(get|put) interface Jiri Olsa
2014-06-13 12:05   ` Namhyung Kim
2014-06-15 17:27     ` Jiri Olsa
2014-06-12 22:08 ` [PATCH 06/17] perf tools: Factor ordered_events_flush to be more generic Jiri Olsa
2014-06-12 22:08 ` [PATCH 07/17] perf tools: Limit ordered events queue size Jiri Olsa
2014-06-12 22:08 ` [PATCH 08/17] perf tools: Flush ordered events in case of allocation failure Jiri Olsa
2014-06-12 22:08 ` [PATCH 09/17] perf tools: Make perf_session_deliver_event global Jiri Olsa
2014-06-12 22:08 ` [PATCH 10/17] perf tools: Create ordered-events object Jiri Olsa
2014-06-12 22:08 ` [PATCH 11/17] perf tools: Add ordered_events_queue_init function Jiri Olsa
2014-06-12 22:08 ` [PATCH 12/17] perf tools: Add ordered_events_queue_free function Jiri Olsa
2014-06-12 22:08 ` [PATCH 13/17] perf tools: Add perf_config_u64 function Jiri Olsa
2014-06-13 12:07   ` Namhyung Kim
2014-06-15 17:48     ` Jiri Olsa
2014-06-12 22:08 ` [PATCH 14/17] perf tools: Add report.queue-size config file option Jiri Olsa
2014-06-13 12:08   ` Namhyung Kim
2014-06-15 17:54     ` Jiri Olsa
2014-06-12 22:08 ` [PATCH 15/17] perf tools: Add debug prints for ordered events queue Jiri Olsa
2014-06-13 12:12   ` Namhyung Kim
2014-06-15 17:58     ` Jiri Olsa
2014-06-12 22:08 ` [PATCH 16/17] perf tools: Limit the ordered events queue by default to 100MB Jiri Olsa
2014-06-12 22:08 ` [PATCH 17/17] perf tools: Allow out of order messages in forced flush Jiri Olsa

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).