diff options
author | Jiri Olsa <jolsa@redhat.com> | 2012-03-22 09:37:26 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2012-03-22 14:12:09 -0400 |
commit | 4bf9ce1b5ecffffeb8b9d7e925bac3e6b10109aa (patch) | |
tree | 6405f45496261cbc233d8b4c1870bb05c647d966 /tools | |
parent | 5d7be90ed5cfb5dd3c9ab726d7daa91b86b81747 (diff) |
perf diff: Fix to work with new hists design
The perf diff command is broken since:
perf hists: Threaded addition and sorting of entries
commit 1980c2ebd7020d82c024b8c4046849b38e78e7da
Several places were broken:
- hists data need to be collected into opened sessions instead
of into events
- session's hists data need to be initialized properly when the
session is created
- hist_entry__pcnt_snprintf: the percentage and displacement
buffer preparation must not use 'ret' because it's used
as a pointer to the final buffer
Signed-off-by: Jiri Olsa <jolsa@redhat.com>
Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/20120322133726.GB1601@m.brq.redhat.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools')
-rw-r--r-- | tools/perf/builtin-diff.c | 60 | ||||
-rw-r--r-- | tools/perf/util/evsel.c | 2 | ||||
-rw-r--r-- | tools/perf/util/evsel.h | 2 | ||||
-rw-r--r-- | tools/perf/util/hist.c | 8 | ||||
-rw-r--r-- | tools/perf/util/session.c | 1 |
5 files changed, 43 insertions, 30 deletions
diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c index 4f19513d7dda..d29d350fb2b7 100644 --- a/tools/perf/builtin-diff.c +++ b/tools/perf/builtin-diff.c | |||
@@ -24,6 +24,11 @@ static char diff__default_sort_order[] = "dso,symbol"; | |||
24 | static bool force; | 24 | static bool force; |
25 | static bool show_displacement; | 25 | static bool show_displacement; |
26 | 26 | ||
27 | struct perf_diff { | ||
28 | struct perf_tool tool; | ||
29 | struct perf_session *session; | ||
30 | }; | ||
31 | |||
27 | static int hists__add_entry(struct hists *self, | 32 | static int hists__add_entry(struct hists *self, |
28 | struct addr_location *al, u64 period) | 33 | struct addr_location *al, u64 period) |
29 | { | 34 | { |
@@ -32,12 +37,14 @@ static int hists__add_entry(struct hists *self, | |||
32 | return -ENOMEM; | 37 | return -ENOMEM; |
33 | } | 38 | } |
34 | 39 | ||
35 | static int diff__process_sample_event(struct perf_tool *tool __used, | 40 | static int diff__process_sample_event(struct perf_tool *tool, |
36 | union perf_event *event, | 41 | union perf_event *event, |
37 | struct perf_sample *sample, | 42 | struct perf_sample *sample, |
38 | struct perf_evsel *evsel __used, | 43 | struct perf_evsel *evsel __used, |
39 | struct machine *machine) | 44 | struct machine *machine) |
40 | { | 45 | { |
46 | struct perf_diff *_diff = container_of(tool, struct perf_diff, tool); | ||
47 | struct perf_session *session = _diff->session; | ||
41 | struct addr_location al; | 48 | struct addr_location al; |
42 | 49 | ||
43 | if (perf_event__preprocess_sample(event, machine, &al, sample, NULL) < 0) { | 50 | if (perf_event__preprocess_sample(event, machine, &al, sample, NULL) < 0) { |
@@ -49,24 +56,26 @@ static int diff__process_sample_event(struct perf_tool *tool __used, | |||
49 | if (al.filtered || al.sym == NULL) | 56 | if (al.filtered || al.sym == NULL) |
50 | return 0; | 57 | return 0; |
51 | 58 | ||
52 | if (hists__add_entry(&evsel->hists, &al, sample->period)) { | 59 | if (hists__add_entry(&session->hists, &al, sample->period)) { |
53 | pr_warning("problem incrementing symbol period, skipping event\n"); | 60 | pr_warning("problem incrementing symbol period, skipping event\n"); |
54 | return -1; | 61 | return -1; |
55 | } | 62 | } |
56 | 63 | ||
57 | evsel->hists.stats.total_period += sample->period; | 64 | session->hists.stats.total_period += sample->period; |
58 | return 0; | 65 | return 0; |
59 | } | 66 | } |
60 | 67 | ||
61 | static struct perf_tool perf_diff = { | 68 | static struct perf_diff diff = { |
62 | .sample = diff__process_sample_event, | 69 | .tool = { |
63 | .mmap = perf_event__process_mmap, | 70 | .sample = diff__process_sample_event, |
64 | .comm = perf_event__process_comm, | 71 | .mmap = perf_event__process_mmap, |
65 | .exit = perf_event__process_task, | 72 | .comm = perf_event__process_comm, |
66 | .fork = perf_event__process_task, | 73 | .exit = perf_event__process_task, |
67 | .lost = perf_event__process_lost, | 74 | .fork = perf_event__process_task, |
68 | .ordered_samples = true, | 75 | .lost = perf_event__process_lost, |
69 | .ordering_requires_timestamps = true, | 76 | .ordered_samples = true, |
77 | .ordering_requires_timestamps = true, | ||
78 | }, | ||
70 | }; | 79 | }; |
71 | 80 | ||
72 | static void perf_session__insert_hist_entry_by_name(struct rb_root *root, | 81 | static void perf_session__insert_hist_entry_by_name(struct rb_root *root, |
@@ -107,12 +116,6 @@ static void hists__resort_entries(struct hists *self) | |||
107 | self->entries = tmp; | 116 | self->entries = tmp; |
108 | } | 117 | } |
109 | 118 | ||
110 | static void hists__set_positions(struct hists *self) | ||
111 | { | ||
112 | hists__output_resort(self); | ||
113 | hists__resort_entries(self); | ||
114 | } | ||
115 | |||
116 | static struct hist_entry *hists__find_entry(struct hists *self, | 119 | static struct hist_entry *hists__find_entry(struct hists *self, |
117 | struct hist_entry *he) | 120 | struct hist_entry *he) |
118 | { | 121 | { |
@@ -146,30 +149,37 @@ static void hists__match(struct hists *older, struct hists *newer) | |||
146 | static int __cmd_diff(void) | 149 | static int __cmd_diff(void) |
147 | { | 150 | { |
148 | int ret, i; | 151 | int ret, i; |
152 | #define older (session[0]) | ||
153 | #define newer (session[1]) | ||
149 | struct perf_session *session[2]; | 154 | struct perf_session *session[2]; |
150 | 155 | ||
151 | session[0] = perf_session__new(input_old, O_RDONLY, force, false, &perf_diff); | 156 | older = perf_session__new(input_old, O_RDONLY, force, false, |
152 | session[1] = perf_session__new(input_new, O_RDONLY, force, false, &perf_diff); | 157 | &diff.tool); |
158 | newer = perf_session__new(input_new, O_RDONLY, force, false, | ||
159 | &diff.tool); | ||
153 | if (session[0] == NULL || session[1] == NULL) | 160 | if (session[0] == NULL || session[1] == NULL) |
154 | return -ENOMEM; | 161 | return -ENOMEM; |
155 | 162 | ||
156 | for (i = 0; i < 2; ++i) { | 163 | for (i = 0; i < 2; ++i) { |
157 | ret = perf_session__process_events(session[i], &perf_diff); | 164 | diff.session = session[i]; |
165 | ret = perf_session__process_events(session[i], &diff.tool); | ||
158 | if (ret) | 166 | if (ret) |
159 | goto out_delete; | 167 | goto out_delete; |
168 | hists__output_resort(&session[i]->hists); | ||
160 | } | 169 | } |
161 | 170 | ||
162 | hists__output_resort(&session[1]->hists); | ||
163 | if (show_displacement) | 171 | if (show_displacement) |
164 | hists__set_positions(&session[0]->hists); | 172 | hists__resort_entries(&older->hists); |
165 | 173 | ||
166 | hists__match(&session[0]->hists, &session[1]->hists); | 174 | hists__match(&older->hists, &newer->hists); |
167 | hists__fprintf(&session[1]->hists, &session[0]->hists, | 175 | hists__fprintf(&newer->hists, &older->hists, |
168 | show_displacement, true, 0, 0, stdout); | 176 | show_displacement, true, 0, 0, stdout); |
169 | out_delete: | 177 | out_delete: |
170 | for (i = 0; i < 2; ++i) | 178 | for (i = 0; i < 2; ++i) |
171 | perf_session__delete(session[i]); | 179 | perf_session__delete(session[i]); |
172 | return ret; | 180 | return ret; |
181 | #undef older | ||
182 | #undef newer | ||
173 | } | 183 | } |
174 | 184 | ||
175 | static const char * const diff_usage[] = { | 185 | static const char * const diff_usage[] = { |
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 0221700075c5..d9da62a7234f 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c | |||
@@ -34,7 +34,7 @@ int __perf_evsel__sample_size(u64 sample_type) | |||
34 | return size; | 34 | return size; |
35 | } | 35 | } |
36 | 36 | ||
37 | static void hists__init(struct hists *hists) | 37 | void hists__init(struct hists *hists) |
38 | { | 38 | { |
39 | memset(hists, 0, sizeof(*hists)); | 39 | memset(hists, 0, sizeof(*hists)); |
40 | hists->entries_in_array[0] = hists->entries_in_array[1] = RB_ROOT; | 40 | hists->entries_in_array[0] = hists->entries_in_array[1] = RB_ROOT; |
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index 3158ca3d69a1..3d6b3e4cb66b 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h | |||
@@ -170,4 +170,6 @@ static inline int perf_evsel__sample_size(struct perf_evsel *evsel) | |||
170 | return __perf_evsel__sample_size(evsel->attr.sample_type); | 170 | return __perf_evsel__sample_size(evsel->attr.sample_type); |
171 | } | 171 | } |
172 | 172 | ||
173 | void hists__init(struct hists *hists); | ||
174 | |||
173 | #endif /* __PERF_EVSEL_H */ | 175 | #endif /* __PERF_EVSEL_H */ |
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index 5fb19013ca0c..c61235f81260 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c | |||
@@ -891,9 +891,9 @@ static int hist_entry__pcnt_snprintf(struct hist_entry *he, char *s, | |||
891 | diff = new_percent - old_percent; | 891 | diff = new_percent - old_percent; |
892 | 892 | ||
893 | if (fabs(diff) >= 0.01) | 893 | if (fabs(diff) >= 0.01) |
894 | ret += scnprintf(bf, sizeof(bf), "%+4.2F%%", diff); | 894 | scnprintf(bf, sizeof(bf), "%+4.2F%%", diff); |
895 | else | 895 | else |
896 | ret += scnprintf(bf, sizeof(bf), " "); | 896 | scnprintf(bf, sizeof(bf), " "); |
897 | 897 | ||
898 | if (sep) | 898 | if (sep) |
899 | ret += scnprintf(s + ret, size - ret, "%c%s", *sep, bf); | 899 | ret += scnprintf(s + ret, size - ret, "%c%s", *sep, bf); |
@@ -902,9 +902,9 @@ static int hist_entry__pcnt_snprintf(struct hist_entry *he, char *s, | |||
902 | 902 | ||
903 | if (show_displacement) { | 903 | if (show_displacement) { |
904 | if (displacement) | 904 | if (displacement) |
905 | ret += scnprintf(bf, sizeof(bf), "%+4ld", displacement); | 905 | scnprintf(bf, sizeof(bf), "%+4ld", displacement); |
906 | else | 906 | else |
907 | ret += scnprintf(bf, sizeof(bf), " "); | 907 | scnprintf(bf, sizeof(bf), " "); |
908 | 908 | ||
909 | if (sep) | 909 | if (sep) |
910 | ret += scnprintf(s + ret, size - ret, "%c%s", *sep, bf); | 910 | ret += scnprintf(s + ret, size - ret, "%c%s", *sep, bf); |
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 002ebbf59f48..9412e3b05f68 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c | |||
@@ -140,6 +140,7 @@ struct perf_session *perf_session__new(const char *filename, int mode, | |||
140 | INIT_LIST_HEAD(&self->ordered_samples.sample_cache); | 140 | INIT_LIST_HEAD(&self->ordered_samples.sample_cache); |
141 | INIT_LIST_HEAD(&self->ordered_samples.to_free); | 141 | INIT_LIST_HEAD(&self->ordered_samples.to_free); |
142 | machine__init(&self->host_machine, "", HOST_KERNEL_ID); | 142 | machine__init(&self->host_machine, "", HOST_KERNEL_ID); |
143 | hists__init(&self->hists); | ||
143 | 144 | ||
144 | if (mode == O_RDONLY) { | 145 | if (mode == O_RDONLY) { |
145 | if (perf_session__open(self, force) < 0) | 146 | if (perf_session__open(self, force) < 0) |