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) |
