perf trace: Add ordered processing
Sort events to provide the precise outcome of ordered events, just like is done with 'perf report' and 'perf top'. Signed-off-by: Jiri Olsa <jolsa@kernel.org> Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> Cc: Dmitry Levin <ldv@altlinux.org> Cc: Eugene Syromiatnikov <esyr@redhat.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Luis Cláudio Gonçalves <lclaudio@uudg.org> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Steven Rostedt (VMware) <rostedt@goodmis.org> Cc: Thomas Gleixner <tglx@linutronix.de> Link: http://lkml.kernel.org/r/20181205160509.1168-9-jolsa@kernel.org [ split from a larger patch, added trace__ prefixes to new 'struct trace' methods ] Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
parent
83356b3d12
commit
028713aa83
|
@ -127,6 +127,10 @@ struct trace {
|
||||||
bool force;
|
bool force;
|
||||||
bool vfs_getname;
|
bool vfs_getname;
|
||||||
int trace_pgfaults;
|
int trace_pgfaults;
|
||||||
|
struct {
|
||||||
|
struct ordered_events data;
|
||||||
|
u64 last;
|
||||||
|
} oe;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct tp_field {
|
struct tp_field {
|
||||||
|
@ -2652,6 +2656,42 @@ static int trace__deliver_event(struct trace *trace, union perf_event *event)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int trace__flush_ordered_events(struct trace *trace)
|
||||||
|
{
|
||||||
|
u64 first = ordered_events__first_time(&trace->oe.data);
|
||||||
|
u64 flush = trace->oe.last - NSEC_PER_SEC;
|
||||||
|
|
||||||
|
/* Is there some thing to flush.. */
|
||||||
|
if (first && first < flush)
|
||||||
|
return ordered_events__flush_time(&trace->oe.data, flush);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int trace__deliver_ordered_event(struct trace *trace, union perf_event *event)
|
||||||
|
{
|
||||||
|
struct perf_evlist *evlist = trace->evlist;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
err = perf_evlist__parse_sample_timestamp(evlist, event, &trace->oe.last);
|
||||||
|
if (err && err != -1)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
err = ordered_events__queue(&trace->oe.data, event, trace->oe.last, 0);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
return trace__flush_ordered_events(trace);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ordered_events__deliver_event(struct ordered_events *oe,
|
||||||
|
struct ordered_event *event)
|
||||||
|
{
|
||||||
|
struct trace *trace = container_of(oe, struct trace, oe.data);
|
||||||
|
|
||||||
|
return trace__deliver_event(trace, event->event);
|
||||||
|
}
|
||||||
|
|
||||||
static int trace__run(struct trace *trace, int argc, const char **argv)
|
static int trace__run(struct trace *trace, int argc, const char **argv)
|
||||||
{
|
{
|
||||||
struct perf_evlist *evlist = trace->evlist;
|
struct perf_evlist *evlist = trace->evlist;
|
||||||
|
@ -2819,7 +2859,9 @@ again:
|
||||||
while ((event = perf_mmap__read_event(md)) != NULL) {
|
while ((event = perf_mmap__read_event(md)) != NULL) {
|
||||||
++trace->nr_events;
|
++trace->nr_events;
|
||||||
|
|
||||||
trace__deliver_event(trace, event);
|
err = trace__deliver_ordered_event(trace, event);
|
||||||
|
if (err)
|
||||||
|
goto out_disable;
|
||||||
|
|
||||||
perf_mmap__consume(md);
|
perf_mmap__consume(md);
|
||||||
|
|
||||||
|
@ -2842,6 +2884,9 @@ again:
|
||||||
draining = true;
|
draining = true;
|
||||||
|
|
||||||
goto again;
|
goto again;
|
||||||
|
} else {
|
||||||
|
if (trace__flush_ordered_events(trace))
|
||||||
|
goto out_disable;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
goto again;
|
goto again;
|
||||||
|
@ -2852,6 +2897,8 @@ out_disable:
|
||||||
|
|
||||||
perf_evlist__disable(evlist);
|
perf_evlist__disable(evlist);
|
||||||
|
|
||||||
|
ordered_events__flush(&trace->oe.data, OE_FLUSH__FINAL);
|
||||||
|
|
||||||
if (!err) {
|
if (!err) {
|
||||||
if (trace->summary)
|
if (trace->summary)
|
||||||
trace__fprintf_thread_summary(trace, trace->output);
|
trace__fprintf_thread_summary(trace, trace->output);
|
||||||
|
@ -3562,6 +3609,9 @@ int cmd_trace(int argc, const char **argv)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ordered_events__init(&trace.oe.data, ordered_events__deliver_event, &trace);
|
||||||
|
ordered_events__set_copy_on_queue(&trace.oe.data, true);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If we are augmenting syscalls, then combine what we put in the
|
* If we are augmenting syscalls, then combine what we put in the
|
||||||
* __augmented_syscalls__ BPF map with what is in the
|
* __augmented_syscalls__ BPF map with what is in the
|
||||||
|
|
Loading…
Reference in New Issue