diff options
-rw-r--r-- | tools/perf/builtin-kvm.c | 2 | ||||
-rw-r--r-- | tools/perf/util/session.c | 29 | ||||
-rw-r--r-- | tools/perf/util/session.h | 3 |
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, 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 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; 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, 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); |