diff options
| author | Jiri Olsa <jolsa@redhat.com> | 2012-10-10 12:52:24 -0400 |
|---|---|---|
| committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2013-08-07 16:35:22 -0400 |
| commit | e4caec0d1af3d608d52e6b92d09fb862d7691d4b (patch) | |
| tree | 90f7181f9b5b7db3ddba0353e938ef42868f1006 /tools | |
| parent | 932a35940a3f03613796ab4855ecbb214dbdc0c2 (diff) | |
perf evsel: Add PERF_SAMPLE_READ sample related processing
For sample with sample type PERF_SAMPLE_READ the period value is stored
in the 'struct sample_read'.
Moreover if the read format has PERF_FORMAT_GROUP, the 'struct
sample_read' contains period values for all events in the group (for
which the sample's event is a leader).
We deliver separated samples for all the values contained within the
'struct sample_read'.
Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Acked-by: Namhyung Kim <namhyung@kernel.org>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/n/tip-6mdm5xkrm6kypouh1c33cyys@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools')
| -rw-r--r-- | tools/perf/util/evsel.h | 3 | ||||
| -rw-r--r-- | tools/perf/util/session.c | 72 |
2 files changed, 74 insertions, 1 deletions
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index 3f156ccc1acb..6a2cf261f38e 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h | |||
| @@ -38,6 +38,9 @@ struct perf_sample_id { | |||
| 38 | struct hlist_node node; | 38 | struct hlist_node node; |
| 39 | u64 id; | 39 | u64 id; |
| 40 | struct perf_evsel *evsel; | 40 | struct perf_evsel *evsel; |
| 41 | |||
| 42 | /* Holds total ID period value for PERF_SAMPLE_READ processing. */ | ||
| 43 | u64 period; | ||
| 41 | }; | 44 | }; |
| 42 | 45 | ||
| 43 | /** struct perf_evsel - event selector | 46 | /** struct perf_evsel - event selector |
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index f082921a062d..9247d9c2f5e3 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c | |||
| @@ -860,6 +860,75 @@ static struct machine * | |||
| 860 | return &session->machines.host; | 860 | return &session->machines.host; |
| 861 | } | 861 | } |
| 862 | 862 | ||
| 863 | static int deliver_sample_value(struct perf_session *session, | ||
| 864 | struct perf_tool *tool, | ||
| 865 | union perf_event *event, | ||
| 866 | struct perf_sample *sample, | ||
| 867 | struct sample_read_value *v, | ||
| 868 | struct machine *machine) | ||
| 869 | { | ||
| 870 | struct perf_sample_id *sid; | ||
| 871 | |||
| 872 | sid = perf_evlist__id2sid(session->evlist, v->id); | ||
| 873 | if (sid) { | ||
| 874 | sample->id = v->id; | ||
| 875 | sample->period = v->value - sid->period; | ||
| 876 | sid->period = v->value; | ||
| 877 | } | ||
| 878 | |||
| 879 | if (!sid || sid->evsel == NULL) { | ||
| 880 | ++session->stats.nr_unknown_id; | ||
| 881 | return 0; | ||
| 882 | } | ||
| 883 | |||
| 884 | return tool->sample(tool, event, sample, sid->evsel, machine); | ||
| 885 | } | ||
| 886 | |||
| 887 | static int deliver_sample_group(struct perf_session *session, | ||
| 888 | struct perf_tool *tool, | ||
| 889 | union perf_event *event, | ||
| 890 | struct perf_sample *sample, | ||
| 891 | struct machine *machine) | ||
| 892 | { | ||
| 893 | int ret = -EINVAL; | ||
| 894 | u64 i; | ||
| 895 | |||
| 896 | for (i = 0; i < sample->read.group.nr; i++) { | ||
| 897 | ret = deliver_sample_value(session, tool, event, sample, | ||
| 898 | &sample->read.group.values[i], | ||
| 899 | machine); | ||
| 900 | if (ret) | ||
| 901 | break; | ||
| 902 | } | ||
| 903 | |||
| 904 | return ret; | ||
| 905 | } | ||
| 906 | |||
| 907 | static int | ||
| 908 | perf_session__deliver_sample(struct perf_session *session, | ||
| 909 | struct perf_tool *tool, | ||
| 910 | union perf_event *event, | ||
| 911 | struct perf_sample *sample, | ||
| 912 | struct perf_evsel *evsel, | ||
| 913 | struct machine *machine) | ||
| 914 | { | ||
| 915 | /* We know evsel != NULL. */ | ||
| 916 | u64 sample_type = evsel->attr.sample_type; | ||
| 917 | u64 read_format = evsel->attr.read_format; | ||
| 918 | |||
| 919 | /* Standard sample delievery. */ | ||
| 920 | if (!(sample_type & PERF_SAMPLE_READ)) | ||
| 921 | return tool->sample(tool, event, sample, evsel, machine); | ||
| 922 | |||
| 923 | /* For PERF_SAMPLE_READ we have either single or group mode. */ | ||
| 924 | if (read_format & PERF_FORMAT_GROUP) | ||
| 925 | return deliver_sample_group(session, tool, event, sample, | ||
| 926 | machine); | ||
| 927 | else | ||
| 928 | return deliver_sample_value(session, tool, event, sample, | ||
| 929 | &sample->read.one, machine); | ||
| 930 | } | ||
| 931 | |||
| 863 | static int perf_session_deliver_event(struct perf_session *session, | 932 | static int perf_session_deliver_event(struct perf_session *session, |
| 864 | union perf_event *event, | 933 | union perf_event *event, |
| 865 | struct perf_sample *sample, | 934 | struct perf_sample *sample, |
| @@ -902,7 +971,8 @@ static int perf_session_deliver_event(struct perf_session *session, | |||
| 902 | ++session->stats.nr_unprocessable_samples; | 971 | ++session->stats.nr_unprocessable_samples; |
| 903 | return 0; | 972 | return 0; |
| 904 | } | 973 | } |
| 905 | return tool->sample(tool, event, sample, evsel, machine); | 974 | return perf_session__deliver_sample(session, tool, event, |
| 975 | sample, evsel, machine); | ||
| 906 | case PERF_RECORD_MMAP: | 976 | case PERF_RECORD_MMAP: |
| 907 | return tool->mmap(tool, event, sample, machine); | 977 | return tool->mmap(tool, event, sample, machine); |
| 908 | case PERF_RECORD_COMM: | 978 | case PERF_RECORD_COMM: |
