summaryrefslogtreecommitdiff
path: root/tools/perf/util/session.c
diff options
context:
space:
mode:
authorJiri Olsa <jolsa@kernel.org>2014-08-01 13:01:04 -0300
committerArnaldo Carvalho de Melo <acme@redhat.com>2014-08-12 12:02:57 -0300
commitd40b4a15ab2bfcfa7d946b69ca1f12c93b22d169 (patch)
tree7919b10cf1b3834c06eb9c6be215e006a30b5102 /tools/perf/util/session.c
parent8d99a6ceebe862ac4afd832cdab332ee7b3b5599 (diff)
perf tools: Flush ordered events in case of allocation failure
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. Signed-off-by: Jiri Olsa <jolsa@kernel.org> Acked-by: David Ahern <dsahern@gmail.com> 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> Link: http://lkml.kernel.org/n/tip-ggcas0xdq847fi85bz73do2e@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/util/session.c')
-rw-r--r--tools/perf/util/session.c29
1 files changed, 27 insertions, 2 deletions
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 8d4538c91076..bd2483b6b446 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -14,6 +14,7 @@
#include "util.h"
#include "cpumap.h"
#include "perf_regs.h"
+#include "asm/bug.h"
static int perf_session__open(struct perf_session *session)
{
@@ -456,6 +457,7 @@ struct ordered_event {
enum oe_flush {
OE_FLUSH__FINAL,
OE_FLUSH__ROUND,
+ OE_FLUSH__HALF,
};
static void perf_session_free_sample_buffers(struct perf_session *session)
@@ -637,6 +639,23 @@ static int ordered_events__flush(struct perf_session *s, struct perf_tool *tool,
oe->next_flush = ULLONG_MAX;
break;
+ case OE_FLUSH__HALF:
+ {
+ struct ordered_event *first, *last;
+ struct list_head *head = &oe->events;
+
+ first = list_entry(head->next, struct ordered_event, list);
+ last = oe->last;
+
+ /* Warn if we are called before any event got allocated. */
+ if (WARN_ONCE(!last || list_empty(head), "empty queue"))
+ return 0;
+
+ oe->next_flush = first->timestamp;
+ oe->next_flush += (last->timestamp - first->timestamp) / 2;
+ break;
+ }
+
case OE_FLUSH__ROUND:
default:
break;
@@ -699,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 *oe = &s->ordered_events;
u64 timestamp = sample->time;
@@ -714,6 +734,11 @@ int perf_session_queue_event(struct perf_session *s, union perf_event *event,
}
new = ordered_events__new(oe, timestamp);
+ if (!new) {
+ ordered_events__flush(s, tool, OE_FLUSH__HALF);
+ new = ordered_events__new(oe, timestamp);
+ }
+
if (!new)
return -ENOMEM;
@@ -1121,7 +1146,7 @@ static s64 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;