|
@@ -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;
|