From: tip-bot for Thomas Gleixner <tglx@linutronix.de>
To: linux-tip-commits@vger.kernel.org
Cc: acme@redhat.com, linux-kernel@vger.kernel.org,
eranian@google.com, paulus@samba.org, hpa@zytor.com,
mingo@redhat.com, a.p.zijlstra@chello.nl, efault@gmx.de,
imunsie@au1.ibm.com, fweisbec@gmail.com, tglx@linutronix.de,
mingo@elte.hu
Subject: [tip:perf/core] perf session: Sort all events if ordered_samples=true
Date: Tue, 7 Dec 2010 06:57:07 GMT [thread overview]
Message-ID: <tip-cbf41645f35224798cb61641766e6a16e141ffe4@git.kernel.org> (raw)
In-Reply-To: <alpine.LFD.2.00.1012051220450.2653@localhost6.localdomain6>
Commit-ID: cbf41645f35224798cb61641766e6a16e141ffe4
Gitweb: http://git.kernel.org/tip/cbf41645f35224798cb61641766e6a16e141ffe4
Author: Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Sun, 5 Dec 2010 14:32:55 +0100
Committer: Arnaldo Carvalho de Melo <acme@redhat.com>
CommitDate: Mon, 6 Dec 2010 15:43:00 -0200
perf session: Sort all events if ordered_samples=true
Now that we have timestamps on FORK, EXIT, COMM, MMAP events we can
sort everything in time order. This fixes the following observed
problem:
mmap(file1) -> pagefault() -> munmap(file1)
mmap(file2) -> pagefault() -> munmap(file2)
Resulted in decoding both pagefaults in file2 because the file1 map
was already replaced by the file2 map when the map address was
identical.
With all events sorted we decode both pagefaults correctly.
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ian Munsie <imunsie@au1.ibm.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Stephane Eranian <eranian@google.com>
LKML-Reference: <alpine.LFD.2.00.1012051220450.2653@localhost6.localdomain6>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
tools/perf/util/session.c | 125 ++++++++++++++++++++++++++-------------------
1 files changed, 72 insertions(+), 53 deletions(-)
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 5c75660..3074d38 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -461,6 +461,11 @@ static void perf_session_free_sample_buffers(struct perf_session *session)
}
}
+static int perf_session_deliver_event(struct perf_session *session,
+ event_t *event,
+ struct sample_data *sample,
+ struct perf_event_ops *ops);
+
static void flush_sample_queue(struct perf_session *s,
struct perf_event_ops *ops)
{
@@ -479,7 +484,7 @@ static void flush_sample_queue(struct perf_session *s,
break;
event__parse_sample(iter->event, s, &sample);
- ops->sample(iter->event, &sample, s);
+ perf_session_deliver_event(s, iter->event, &sample, ops);
os->last_flush = iter->timestamp;
list_del(&iter->list);
@@ -544,8 +549,7 @@ static int process_finished_round(event_t *event __used,
}
/* The queue is ordered by time */
-static void __queue_sample_event(struct sample_queue *new,
- struct perf_session *s)
+static void __queue_event(struct sample_queue *new, struct perf_session *s)
{
struct ordered_samples *os = &s->ordered_samples;
struct sample_queue *sample = os->last_sample;
@@ -591,14 +595,17 @@ static void __queue_sample_event(struct sample_queue *new,
#define MAX_SAMPLE_BUFFER (64 * 1024 / sizeof(struct sample_queue))
-static int queue_sample_event(event_t *event, struct sample_data *data,
- struct perf_session *s)
+static int perf_session_queue_event(struct perf_session *s, event_t *event,
+ struct sample_data *data)
{
struct ordered_samples *os = &s->ordered_samples;
struct list_head *sc = &os->sample_cache;
u64 timestamp = data->time;
struct sample_queue *new;
+ if (!timestamp)
+ return -ETIME;
+
if (timestamp < s->ordered_samples.last_flush) {
printf("Warning: Timestamp below last timeslice flush\n");
return -EINVAL;
@@ -623,20 +630,8 @@ static int queue_sample_event(event_t *event, struct sample_data *data,
new->timestamp = timestamp;
new->event = event;
- __queue_sample_event(new, s);
-
- return 0;
-}
-
-static int perf_session__process_sample(event_t *event,
- struct sample_data *sample,
- struct perf_session *s,
- struct perf_event_ops *ops)
-{
- if (!ops->ordered_samples)
- return ops->sample(event, sample, s);
+ __queue_event(new, s);
- queue_sample_event(event, sample, s);
return 0;
}
@@ -670,83 +665,107 @@ static void perf_session__print_tstamp(struct perf_session *session,
printf("%Lu ", sample->time);
}
-static int perf_session__process_event(struct perf_session *self,
+static int perf_session_deliver_event(struct perf_session *session,
+ event_t *event,
+ struct sample_data *sample,
+ struct perf_event_ops *ops)
+{
+ switch (event->header.type) {
+ case PERF_RECORD_SAMPLE:
+ return ops->sample(event, sample, session);
+ case PERF_RECORD_MMAP:
+ return ops->mmap(event, sample, session);
+ case PERF_RECORD_COMM:
+ return ops->comm(event, sample, session);
+ case PERF_RECORD_FORK:
+ return ops->fork(event, sample, session);
+ case PERF_RECORD_EXIT:
+ return ops->exit(event, sample, session);
+ case PERF_RECORD_LOST:
+ return ops->lost(event, sample, session);
+ case PERF_RECORD_READ:
+ return ops->read(event, sample, session);
+ case PERF_RECORD_THROTTLE:
+ return ops->throttle(event, sample, session);
+ case PERF_RECORD_UNTHROTTLE:
+ return ops->unthrottle(event, sample, session);
+ default:
+ ++session->hists.stats.nr_unknown_events;
+ return -1;
+ }
+}
+
+static int perf_session__process_event(struct perf_session *session,
event_t *event,
struct perf_event_ops *ops,
u64 file_offset)
{
struct sample_data sample;
+ int ret;
trace_event(event);
- if (self->header.needs_swap && event__swap_ops[event->header.type])
+ if (session->header.needs_swap && event__swap_ops[event->header.type])
event__swap_ops[event->header.type](event);
if (event->header.type >= PERF_RECORD_MMAP &&
event->header.type <= PERF_RECORD_SAMPLE) {
- event__parse_sample(event, self, &sample);
+ event__parse_sample(event, session, &sample);
if (dump_trace)
- perf_session__print_tstamp(self, event, &sample);
+ perf_session__print_tstamp(session, event, &sample);
}
if (event->header.type < PERF_RECORD_HEADER_MAX) {
dump_printf("%#Lx [%#x]: PERF_RECORD_%s",
file_offset, event->header.size,
event__name[event->header.type]);
- hists__inc_nr_events(&self->hists, event->header.type);
+ hists__inc_nr_events(&session->hists, event->header.type);
}
+ /* These events are processed right away */
switch (event->header.type) {
case PERF_RECORD_SAMPLE:
- dump_printf("(IP, %d): %d/%d: %#Lx period: %Ld\n", event->header.misc,
+ dump_printf("(IP, %d): %d/%d: %#Lx period: %Ld\n",
+ event->header.misc,
sample.pid, sample.tid, sample.ip, sample.period);
- if (self->sample_type & PERF_SAMPLE_CALLCHAIN) {
+ if (session->sample_type & PERF_SAMPLE_CALLCHAIN) {
if (!ip_callchain__valid(sample.callchain, event)) {
pr_debug("call-chain problem with event, "
"skipping it.\n");
- ++self->hists.stats.nr_invalid_chains;
- self->hists.stats.total_invalid_chains += sample.period;
+ ++session->hists.stats.nr_invalid_chains;
+ session->hists.stats.total_invalid_chains +=
+ sample.period;
return 0;
}
callchain__dump(&sample);
}
+ break;
- return perf_session__process_sample(event, &sample, self, ops);
-
- case PERF_RECORD_MMAP:
- return ops->mmap(event, &sample, self);
- case PERF_RECORD_COMM:
- return ops->comm(event, &sample, self);
- case PERF_RECORD_FORK:
- return ops->fork(event, &sample, self);
- case PERF_RECORD_EXIT:
- return ops->exit(event, &sample, self);
- case PERF_RECORD_LOST:
- return ops->lost(event, &sample, self);
- case PERF_RECORD_READ:
- return ops->read(event, &sample, self);
- case PERF_RECORD_THROTTLE:
- return ops->throttle(event, &sample, self);
- case PERF_RECORD_UNTHROTTLE:
- return ops->unthrottle(event, &sample, self);
case PERF_RECORD_HEADER_ATTR:
- return ops->attr(event, self);
+ return ops->attr(event, session);
case PERF_RECORD_HEADER_EVENT_TYPE:
- return ops->event_type(event, self);
+ return ops->event_type(event, session);
case PERF_RECORD_HEADER_TRACING_DATA:
/* setup for reading amidst mmap */
- lseek(self->fd, file_offset, SEEK_SET);
- return ops->tracing_data(event, self);
+ lseek(session->fd, file_offset, SEEK_SET);
+ return ops->tracing_data(event, session);
case PERF_RECORD_HEADER_BUILD_ID:
- return ops->build_id(event, self);
+ return ops->build_id(event, session);
case PERF_RECORD_FINISHED_ROUND:
- return ops->finished_round(event, self, ops);
+ return ops->finished_round(event, session, ops);
default:
- ++self->hists.stats.nr_unknown_events;
- return -1;
+ break;
}
+
+ if (ops->ordered_samples) {
+ ret = perf_session_queue_event(session, event, &sample);
+ if (ret != -ETIME)
+ return ret;
+ }
+
+ return perf_session_deliver_event(session, event, &sample, ops);
}
void perf_event_header__bswap(struct perf_event_header *self)
prev parent reply other threads:[~2010-12-07 6:57 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-12-04 22:26 [GIT PULL 0/5] perf/core: Support for PERF_SAMPLE_ in all events Arnaldo Carvalho de Melo
2010-12-04 22:26 ` [PATCH 1/5] perf events: Fix event inherit fallout of precalculated headers Arnaldo Carvalho de Melo
2010-12-04 22:26 ` [PATCH 2/5] perf events: Separate the routines handling the PERF_SAMPLE_ identity fields Arnaldo Carvalho de Melo
2010-12-04 22:26 ` [PATCH 3/5] perf events: Make sample_type identity fields available in all PERF_RECORD_ events Arnaldo Carvalho de Melo
2010-12-04 22:26 ` [PATCH 4/5] perf session: Parse sample earlier Arnaldo Carvalho de Melo
2010-12-04 22:26 ` [PATCH 5/5] perf tools: Ask for ID PERF_SAMPLE_ info on all PERF_RECORD_ events Arnaldo Carvalho de Melo
2010-12-05 13:32 ` [Patch] perf: session: Sort all events if ordered_samples=true Thomas Gleixner
2010-12-06 2:37 ` Process events in order if recording from multiple CPUs Ian Munsie
2010-12-06 2:37 ` [PATCH 1/3] perf tool: Better displaying of unresolved DSOs and symbols Ian Munsie
2010-12-07 6:56 ` [tip:perf/core] perf hist: " tip-bot for Ian Munsie
2010-12-06 2:37 ` [PATCH 2/3] perf: Move all output for perf report -D into trace_event Ian Munsie
2010-12-06 2:37 ` [PATCH 3/3] perf record/report: Process events in order Ian Munsie
2010-12-06 9:20 ` Thomas Gleixner
2010-12-06 12:42 ` Ian Munsie
2010-12-06 13:04 ` Thomas Gleixner
2010-12-06 13:11 ` Ian Munsie
2010-12-06 14:41 ` Thomas Gleixner
2010-12-07 1:15 ` Ian Munsie
2010-12-07 10:47 ` Thomas Gleixner
2010-12-07 10:54 ` Arnaldo Carvalho de Melo
2010-12-07 12:24 ` Thomas Gleixner
2010-12-07 6:57 ` tip-bot for Thomas Gleixner [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=tip-cbf41645f35224798cb61641766e6a16e141ffe4@git.kernel.org \
--to=tglx@linutronix.de \
--cc=a.p.zijlstra@chello.nl \
--cc=acme@redhat.com \
--cc=efault@gmx.de \
--cc=eranian@google.com \
--cc=fweisbec@gmail.com \
--cc=hpa@zytor.com \
--cc=imunsie@au1.ibm.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-tip-commits@vger.kernel.org \
--cc=mingo@elte.hu \
--cc=mingo@redhat.com \
--cc=paulus@samba.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox