diff options
author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2011-01-29 12:08:13 +0100 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2011-01-29 19:24:40 +0100 |
commit | 7bb41152b9be7e31f10d8919bce5034135525d9d (patch) | |
tree | 4a79423cd6f01f5e61251e6058ed41427230f63b /tools | |
parent | perf events: Account PERF_RECORD_LOST events in event__process (diff) | |
download | linux-7bb41152b9be7e31f10d8919bce5034135525d9d.tar.xz linux-7bb41152b9be7e31f10d8919bce5034135525d9d.zip |
perf evlist: Support non overwrite mode in perf_evlist__read_on_cpu
I.e. stash the overwrite mode in struct perf_evlist and act accordingly
in perf_evlist__read_on_cpu, not checking for overwrites and touching
the tail after consuming one event, like perf record does, for instance.
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Tom Zanussi <tzanussi@gmail.com>
LKML-Reference: <new-submission>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools')
-rw-r--r-- | tools/perf/util/evlist.c | 35 | ||||
-rw-r--r-- | tools/perf/util/evlist.h | 1 | ||||
-rw-r--r-- | tools/perf/util/evsel.c | 1 |
3 files changed, 22 insertions, 15 deletions
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index df0610e9c61b..b498eecbe850 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c @@ -116,24 +116,25 @@ event_t *perf_evlist__read_on_cpu(struct perf_evlist *evlist, int cpu) unsigned int old = md->prev; unsigned char *data = md->base + page_size; event_t *event = NULL; - int diff; - - /* - * If we're further behind than half the buffer, there's a chance - * the writer will bite our tail and mess up the samples under us. - * - * If we somehow ended up ahead of the head, we got messed up. - * - * In either case, truncate and restart at head. - */ - diff = head - old; - if (diff > md->mask / 2 || diff < 0) { - fprintf(stderr, "WARNING: failed to keep up with mmap data.\n"); + if (evlist->overwrite) { /* - * head points to a known good entry, start there. + * If we're further behind than half the buffer, there's a chance + * the writer will bite our tail and mess up the samples under us. + * + * If we somehow ended up ahead of the head, we got messed up. + * + * In either case, truncate and restart at head. */ - old = head; + int diff = head - old; + if (diff > md->mask / 2 || diff < 0) { + fprintf(stderr, "WARNING: failed to keep up with mmap data.\n"); + + /* + * head points to a known good entry, start there. + */ + old = head; + } } if (old != head) { @@ -166,5 +167,9 @@ event_t *perf_evlist__read_on_cpu(struct perf_evlist *evlist, int cpu) } md->prev = old; + + if (!evlist->overwrite) + perf_mmap__write_tail(md, old); + return event; } diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index acbe48eac608..2706ae40c8b3 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h @@ -16,6 +16,7 @@ struct perf_evlist { int nr_entries; int nr_fds; int mmap_len; + bool overwrite; event_t event_copy; struct perf_mmap *mmap; struct pollfd *pollfd; diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 76ab553637d6..f98b3e585039 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c @@ -327,6 +327,7 @@ int perf_evlist__mmap(struct perf_evlist *evlist, struct cpu_map *cpus, perf_evlist__alloc_pollfd(evlist, cpus->nr, threads->nr) < 0) return -ENOMEM; + evlist->overwrite = overwrite; evlist->mmap_len = (pages + 1) * page_size; first_evsel = list_entry(evlist->entries.next, struct perf_evsel, node); |