From: David Ahern <dsahern@gmail.com>
To: Stephane Eranian <eranian@google.com>
Cc: linux-kernel@vger.kernel.org, peterz@infradead.org,
mingo@elte.hu, acme@redhat.com, ming.m.lin@intel.com
Subject: Re: [PATCH] perf: collect multiplexing timing information in perf record
Date: Fri, 26 Aug 2011 10:32:00 -0600 [thread overview]
Message-ID: <4E57CA80.4070509@gmail.com> (raw)
In-Reply-To: <20110826152256.GA9421@quad>
On 08/26/2011 09:22 AM, Stephane Eranian wrote:
>
> This patch modifies perf record to collect multiplexing timing
> information (time_enabled, time_running) when the -R (raw) option
> is used.
>
> This allows you to compare events captured on a single run and
> compute multi-event metrics. Further it allows you to compare
> measurements between different runs where the number of collected
> events has changed and across different architectures where the
> event count will surely change.
>
> To normalize an event (assuming a fixed period), you do:
> total_events = n_samples * period * time_enabled / time_running
>
> You need the timing information to compensate for multiplexing
> which may have happened.
>
> To add timing information in each sample, it is necessary to
> set PERF_SAMPLE_READ as per the kernel API. That has the side
> effect of also storing the value of the sampling event in each
> sample. This patch modifies perf report to correctly parse
> such samples.
>
> Signed-off-by: Stephane Eranian <eranian@google.com>
>
> ---
> diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
> index 6b0519f..c54e580 100644
> --- a/tools/perf/builtin-record.c
> +++ b/tools/perf/builtin-record.c
> @@ -166,7 +166,7 @@ static void config_attr(struct perf_evsel *evsel, struct perf_evlist *evlist)
> PERF_FORMAT_TOTAL_TIME_RUNNING |
> PERF_FORMAT_ID;
>
> - attr->sample_type |= PERF_SAMPLE_IP | PERF_SAMPLE_TID;
> + attr->sample_type |= PERF_SAMPLE_IP | PERF_SAMPLE_TID;
>
> if (evlist->nr_entries > 1)
> attr->sample_type |= PERF_SAMPLE_ID;
> @@ -211,6 +211,7 @@ static void config_attr(struct perf_evsel *evsel, struct perf_evlist *evlist)
> attr->sample_type |= PERF_SAMPLE_TIME;
> attr->sample_type |= PERF_SAMPLE_RAW;
> attr->sample_type |= PERF_SAMPLE_CPU;
> + attr->sample_type |= PERF_SAMPLE_ID | PERF_SAMPLE_READ;
> }
>
> if (nodelay) {
> diff --git a/tools/perf/builtin-test.c b/tools/perf/builtin-test.c
> index 55f4c76..997b7d7 100644
> --- a/tools/perf/builtin-test.c
> +++ b/tools/perf/builtin-test.c
> @@ -561,7 +561,7 @@ static int test__basic_mmap(void)
> }
>
> err = perf_event__parse_sample(event, attr.sample_type, sample_size,
> - false, &sample);
> + false, 0, &sample);
> if (err) {
> pr_err("Can't parse sample, err = %d\n", err);
> goto out_munmap;
> diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h
> index 1d7f664..ed193eb 100644
> --- a/tools/perf/util/event.h
> +++ b/tools/perf/util/event.h
> @@ -186,6 +186,6 @@ const char *perf_event__name(unsigned int id);
>
> int perf_event__parse_sample(const union perf_event *event, u64 type,
> int sample_size, bool sample_id_all,
> - struct perf_sample *sample);
> + u64 read_format, struct perf_sample *sample);
>
> #endif /* __PERF_RECORD_H */
> diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
> index c12bd47..be0e30c 100644
> --- a/tools/perf/util/evlist.c
> +++ b/tools/perf/util/evlist.c
> @@ -477,6 +477,14 @@ int perf_evlist__set_filters(struct perf_evlist *evlist)
> return 0;
> }
>
> +u64 perf_evlist__read_format(const struct perf_evlist *evlist)
> +{
> + struct perf_evsel *first;
> +
> + first = list_entry(evlist->entries.next, struct perf_evsel, node);
> + return first->attr.read_format;
> +}
> +
> bool perf_evlist__valid_sample_type(const struct perf_evlist *evlist)
> {
> struct perf_evsel *pos, *first;
> diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h
> index ce85ae9..0c0d0ff 100644
> --- a/tools/perf/util/evlist.h
> +++ b/tools/perf/util/evlist.h
> @@ -68,6 +68,7 @@ int perf_evlist__create_maps(struct perf_evlist *evlist, pid_t target_pid,
> void perf_evlist__delete_maps(struct perf_evlist *evlist);
> int perf_evlist__set_filters(struct perf_evlist *evlist);
>
> +u64 perf_evlist__read_format(const struct perf_evlist *evlist);
> u64 perf_evlist__sample_type(const struct perf_evlist *evlist);
> bool perf_evlist__sample_id_all(const const struct perf_evlist *evlist);
>
> diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
> index a03a36b..630a7da 100644
> --- a/tools/perf/util/evsel.c
> +++ b/tools/perf/util/evsel.c
> @@ -340,9 +340,32 @@ static bool sample_overlap(const union perf_event *event,
> return false;
> }
>
> +static int
> +sample_read2u64(const u64 *array, u64 fmt)
> +{
> + u64 nr = 1;
> + int ret = 1; /* nr or value */
> +
> + if (fmt & PERF_FORMAT_TOTAL_TIME_ENABLED)
> + ret++;
> +
> + if (fmt & PERF_FORMAT_TOTAL_TIME_RUNNING)
> + ret++;
> +
> + if (fmt & PERF_FORMAT_GROUP) {
> + nr = *(u64 *)array;
> + ret += nr;
> + }
> +
> + if (fmt & PERF_FORMAT_ID)
> + ret += nr;
Why not add
struct read_format {
u64 value;
u64 time_enabled;
u64 time_running;
u64 id;
};
to perf_sample and save the data there?
David
> +
> + return ret;
> +}
> +
> int perf_event__parse_sample(const union perf_event *event, u64 type,
> int sample_size, bool sample_id_all,
> - struct perf_sample *data)
> + u64 read_format,struct perf_sample *data)
> {
> const u64 *array;
>
> @@ -405,10 +428,8 @@ int perf_event__parse_sample(const union perf_event *event, u64 type,
> array++;
> }
>
> - if (type & PERF_SAMPLE_READ) {
> - fprintf(stderr, "PERF_SAMPLE_READ is unsuported for now\n");
> - return -1;
> - }
> + if (type & PERF_SAMPLE_READ)
> + array += sample_read2u64(array, read_format);
>
> if (type & PERF_SAMPLE_CALLCHAIN) {
> if (sample_overlap(event, array, sizeof(data->callchain->nr)))
> diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
> index 72458d9..25a4cf9 100644
> --- a/tools/perf/util/session.c
> +++ b/tools/perf/util/session.c
> @@ -108,6 +108,7 @@ out:
> void perf_session__update_sample_type(struct perf_session *self)
> {
> self->sample_type = perf_evlist__sample_type(self->evlist);
> + self->read_format = perf_evlist__read_format(self->evlist);
> self->sample_size = __perf_evsel__sample_size(self->sample_type);
> self->sample_id_all = perf_evlist__sample_id_all(self->evlist);
> perf_session__id_header_size(self);
> diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h
> index 170601e..903fc1a 100644
> --- a/tools/perf/util/session.h
> +++ b/tools/perf/util/session.h
> @@ -42,7 +42,8 @@ struct perf_session {
> * perf.data file.
> */
> struct hists hists;
> - u64 sample_type;
> + u64 sample_type; /* identical for all events */
> + u64 read_format; /* identical for all events */
> int sample_size;
> int fd;
> bool fd_pipe;
> @@ -162,7 +163,9 @@ static inline int perf_session__parse_sample(struct perf_session *session,
> {
> return perf_event__parse_sample(event, session->sample_type,
> session->sample_size,
> - session->sample_id_all, sample);
> + session->sample_id_all,
> + session->read_format,
> + sample);
> }
>
> struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session,
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
next prev parent reply other threads:[~2011-08-26 16:32 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-08-26 15:22 [PATCH] perf: collect multiplexing timing information in perf record Stephane Eranian
2011-08-26 16:32 ` David Ahern [this message]
2011-08-26 18:02 ` Stephane Eranian
2011-08-26 19:17 ` David Ahern
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=4E57CA80.4070509@gmail.com \
--to=dsahern@gmail.com \
--cc=acme@redhat.com \
--cc=eranian@google.com \
--cc=linux-kernel@vger.kernel.org \
--cc=ming.m.lin@intel.com \
--cc=mingo@elte.hu \
--cc=peterz@infradead.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.