aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJiri Olsa <jolsa@kernel.org>2014-08-01 12:01:04 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2014-08-12 11:02:57 -0400
commitd40b4a15ab2bfcfa7d946b69ca1f12c93b22d169 (patch)
tree7919b10cf1b3834c06eb9c6be215e006a30b5102
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>
-rw-r--r--tools/perf/builtin-kvm.c2
-rw-r--r--tools/perf/util/session.c29
-rw-r--r--tools/perf/util/session.h3
3 files changed, 30 insertions, 4 deletions
diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c
index 258a5274099d..7ccceadcd9f8 100644
--- a/tools/perf/builtin-kvm.c
+++ b/tools/perf/builtin-kvm.c
@@ -732,7 +732,7 @@ static s64 perf_kvm__mmap_read_idx(struct perf_kvm_stat *kvm, int idx,
732 return -1; 732 return -1;
733 } 733 }
734 734
735 err = perf_session_queue_event(kvm->session, event, &sample, 0); 735 err = perf_session_queue_event(kvm->session, event, &kvm->tool, &sample, 0);
736 /* 736 /*
737 * FIXME: Here we can't consume the event, as perf_session_queue_event will 737 * FIXME: Here we can't consume the event, as perf_session_queue_event will
738 * point to it, and it'll get possibly overwritten by the kernel. 738 * 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 8d4538c91076..bd2483b6b446 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -14,6 +14,7 @@
14#include "util.h" 14#include "util.h"
15#include "cpumap.h" 15#include "cpumap.h"
16#include "perf_regs.h" 16#include "perf_regs.h"
17#include "asm/bug.h"
17 18
18static int perf_session__open(struct perf_session *session) 19static int perf_session__open(struct perf_session *session)
19{ 20{
@@ -456,6 +457,7 @@ struct ordered_event {
456enum oe_flush { 457enum oe_flush {
457 OE_FLUSH__FINAL, 458 OE_FLUSH__FINAL,
458 OE_FLUSH__ROUND, 459 OE_FLUSH__ROUND,
460 OE_FLUSH__HALF,
459}; 461};
460 462
461static void perf_session_free_sample_buffers(struct perf_session *session) 463static 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,
637 oe->next_flush = ULLONG_MAX; 639 oe->next_flush = ULLONG_MAX;
638 break; 640 break;
639 641
642 case OE_FLUSH__HALF:
643 {
644 struct ordered_event *first, *last;
645 struct list_head *head = &oe->events;
646
647 first = list_entry(head->next, struct ordered_event, list);
648 last = oe->last;
649
650 /* Warn if we are called before any event got allocated. */
651 if (WARN_ONCE(!last || list_empty(head), "empty queue"))
652 return 0;
653
654 oe->next_flush = first->timestamp;
655 oe->next_flush += (last->timestamp - first->timestamp) / 2;
656 break;
657 }
658
640 case OE_FLUSH__ROUND: 659 case OE_FLUSH__ROUND:
641 default: 660 default:
642 break; 661 break;
@@ -699,7 +718,8 @@ static int process_finished_round(struct perf_tool *tool,
699} 718}
700 719
701int perf_session_queue_event(struct perf_session *s, union perf_event *event, 720int perf_session_queue_event(struct perf_session *s, union perf_event *event,
702 struct perf_sample *sample, u64 file_offset) 721 struct perf_tool *tool, struct perf_sample *sample,
722 u64 file_offset)
703{ 723{
704 struct ordered_events *oe = &s->ordered_events; 724 struct ordered_events *oe = &s->ordered_events;
705 u64 timestamp = sample->time; 725 u64 timestamp = sample->time;
@@ -714,6 +734,11 @@ int perf_session_queue_event(struct perf_session *s, union perf_event *event,
714 } 734 }
715 735
716 new = ordered_events__new(oe, timestamp); 736 new = ordered_events__new(oe, timestamp);
737 if (!new) {
738 ordered_events__flush(s, tool, OE_FLUSH__HALF);
739 new = ordered_events__new(oe, timestamp);
740 }
741
717 if (!new) 742 if (!new)
718 return -ENOMEM; 743 return -ENOMEM;
719 744
@@ -1121,7 +1146,7 @@ static s64 perf_session__process_event(struct perf_session *session,
1121 return ret; 1146 return ret;
1122 1147
1123 if (tool->ordered_events) { 1148 if (tool->ordered_events) {
1124 ret = perf_session_queue_event(session, event, &sample, 1149 ret = perf_session_queue_event(session, event, tool, &sample,
1125 file_offset); 1150 file_offset);
1126 if (ret != -ETIME) 1151 if (ret != -ETIME)
1127 return ret; 1152 return ret;
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h
index e2fbaf2567e1..a09e3c8d825a 100644
--- a/tools/perf/util/session.h
+++ b/tools/perf/util/session.h
@@ -67,7 +67,8 @@ int perf_session__process_events(struct perf_session *session,
67 struct perf_tool *tool); 67 struct perf_tool *tool);
68 68
69int perf_session_queue_event(struct perf_session *s, union perf_event *event, 69int perf_session_queue_event(struct perf_session *s, union perf_event *event,
70 struct perf_sample *sample, u64 file_offset); 70 struct perf_tool *tool, struct perf_sample *sample,
71 u64 file_offset);
71 72
72void perf_tool__fill_defaults(struct perf_tool *tool); 73void perf_tool__fill_defaults(struct perf_tool *tool);
73 74