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