aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/builtin-annotate.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/builtin-annotate.c')
-rw-r--r--tools/perf/builtin-annotate.c62
1 files changed, 34 insertions, 28 deletions
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index 4f0c3d98352..483cb946644 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -30,7 +30,8 @@
30 30
31#include <linux/bitmap.h> 31#include <linux/bitmap.h>
32 32
33static struct perf_annotate { 33struct perf_annotate {
34 struct perf_event_ops ops;
34 char const *input_name; 35 char const *input_name;
35 bool force, use_tui, use_stdio; 36 bool force, use_tui, use_stdio;
36 bool full_paths; 37 bool full_paths;
@@ -38,13 +39,12 @@ static struct perf_annotate {
38 const char *sym_hist_filter; 39 const char *sym_hist_filter;
39 const char *cpu_list; 40 const char *cpu_list;
40 DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS); 41 DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS);
41} annotate = { 42};
42 .input_name = "perf.data",
43}, *ann = &annotate;
44 43
45static int perf_evsel__add_sample(struct perf_evsel *evsel, 44static int perf_evsel__add_sample(struct perf_evsel *evsel,
46 struct perf_sample *sample, 45 struct perf_sample *sample,
47 struct addr_location *al) 46 struct addr_location *al,
47 struct perf_annotate *ann)
48{ 48{
49 struct hist_entry *he; 49 struct hist_entry *he;
50 int ret; 50 int ret;
@@ -79,11 +79,13 @@ static int perf_evsel__add_sample(struct perf_evsel *evsel,
79 return ret; 79 return ret;
80} 80}
81 81
82static int process_sample_event(union perf_event *event, 82static int process_sample_event(struct perf_event_ops *ops,
83 union perf_event *event,
83 struct perf_sample *sample, 84 struct perf_sample *sample,
84 struct perf_evsel *evsel, 85 struct perf_evsel *evsel,
85 struct perf_session *session) 86 struct perf_session *session)
86{ 87{
88 struct perf_annotate *ann = container_of(ops, struct perf_annotate, ops);
87 struct addr_location al; 89 struct addr_location al;
88 90
89 if (perf_event__preprocess_sample(event, session, &al, sample, 91 if (perf_event__preprocess_sample(event, session, &al, sample,
@@ -96,7 +98,7 @@ static int process_sample_event(union perf_event *event,
96 if (ann->cpu_list && !test_bit(sample->cpu, ann->cpu_bitmap)) 98 if (ann->cpu_list && !test_bit(sample->cpu, ann->cpu_bitmap))
97 return 0; 99 return 0;
98 100
99 if (!al.filtered && perf_evsel__add_sample(evsel, sample, &al)) { 101 if (!al.filtered && perf_evsel__add_sample(evsel, sample, &al, ann)) {
100 pr_warning("problem incrementing symbol count, " 102 pr_warning("problem incrementing symbol count, "
101 "skipping event\n"); 103 "skipping event\n");
102 return -1; 104 return -1;
@@ -105,13 +107,15 @@ static int process_sample_event(union perf_event *event,
105 return 0; 107 return 0;
106} 108}
107 109
108static int hist_entry__tty_annotate(struct hist_entry *he, int evidx) 110static int hist_entry__tty_annotate(struct hist_entry *he, int evidx,
111 struct perf_annotate *ann)
109{ 112{
110 return symbol__tty_annotate(he->ms.sym, he->ms.map, evidx, 113 return symbol__tty_annotate(he->ms.sym, he->ms.map, evidx,
111 ann->print_line, ann->full_paths, 0, 0); 114 ann->print_line, ann->full_paths, 0, 0);
112} 115}
113 116
114static void hists__find_annotations(struct hists *self, int evidx) 117static void hists__find_annotations(struct hists *self, int evidx,
118 struct perf_annotate *ann)
115{ 119{
116 struct rb_node *nd = rb_first(&self->entries), *next; 120 struct rb_node *nd = rb_first(&self->entries), *next;
117 int key = K_RIGHT; 121 int key = K_RIGHT;
@@ -149,7 +153,7 @@ find_next:
149 if (next != NULL) 153 if (next != NULL)
150 nd = next; 154 nd = next;
151 } else { 155 } else {
152 hist_entry__tty_annotate(he, evidx); 156 hist_entry__tty_annotate(he, evidx, ann);
153 nd = rb_next(nd); 157 nd = rb_next(nd);
154 /* 158 /*
155 * Since we have a hist_entry per IP for the same 159 * Since we have a hist_entry per IP for the same
@@ -162,16 +166,7 @@ find_next:
162 } 166 }
163} 167}
164 168
165static struct perf_event_ops event_ops = { 169static int __cmd_annotate(struct perf_annotate *ann)
166 .sample = process_sample_event,
167 .mmap = perf_event__process_mmap,
168 .comm = perf_event__process_comm,
169 .fork = perf_event__process_task,
170 .ordered_samples = true,
171 .ordering_requires_timestamps = true,
172};
173
174static int __cmd_annotate(void)
175{ 170{
176 int ret; 171 int ret;
177 struct perf_session *session; 172 struct perf_session *session;
@@ -179,7 +174,7 @@ static int __cmd_annotate(void)
179 u64 total_nr_samples; 174 u64 total_nr_samples;
180 175
181 session = perf_session__new(ann->input_name, O_RDONLY, 176 session = perf_session__new(ann->input_name, O_RDONLY,
182 ann->force, false, &event_ops); 177 ann->force, false, &ann->ops);
183 if (session == NULL) 178 if (session == NULL)
184 return -ENOMEM; 179 return -ENOMEM;
185 180
@@ -190,7 +185,7 @@ static int __cmd_annotate(void)
190 goto out_delete; 185 goto out_delete;
191 } 186 }
192 187
193 ret = perf_session__process_events(session, &event_ops); 188 ret = perf_session__process_events(session, &ann->ops);
194 if (ret) 189 if (ret)
195 goto out_delete; 190 goto out_delete;
196 191
@@ -214,7 +209,7 @@ static int __cmd_annotate(void)
214 total_nr_samples += nr_samples; 209 total_nr_samples += nr_samples;
215 hists__collapse_resort(hists); 210 hists__collapse_resort(hists);
216 hists__output_resort(hists); 211 hists__output_resort(hists);
217 hists__find_annotations(hists, pos->idx); 212 hists__find_annotations(hists, pos->idx, ann);
218 } 213 }
219 } 214 }
220 215
@@ -243,7 +238,20 @@ static const char * const annotate_usage[] = {
243 NULL 238 NULL
244}; 239};
245 240
246static const struct option options[] = { 241int cmd_annotate(int argc, const char **argv, const char *prefix __used)
242{
243 struct perf_annotate annotate = {
244 .ops = {
245 .sample = process_sample_event,
246 .mmap = perf_event__process_mmap,
247 .comm = perf_event__process_comm,
248 .fork = perf_event__process_task,
249 .ordered_samples = true,
250 .ordering_requires_timestamps = true,
251 },
252 .input_name = "perf.data",
253 };
254 const struct option options[] = {
247 OPT_STRING('i', "input", &annotate.input_name, "file", 255 OPT_STRING('i', "input", &annotate.input_name, "file",
248 "input file name"), 256 "input file name"),
249 OPT_STRING('d', "dsos", &symbol_conf.dso_list_str, "dso[,dso...]", 257 OPT_STRING('d', "dsos", &symbol_conf.dso_list_str, "dso[,dso...]",
@@ -275,10 +283,8 @@ static const struct option options[] = {
275 OPT_STRING('M', "disassembler-style", &disassembler_style, "disassembler style", 283 OPT_STRING('M', "disassembler-style", &disassembler_style, "disassembler style",
276 "Specify disassembler style (e.g. -M intel for intel syntax)"), 284 "Specify disassembler style (e.g. -M intel for intel syntax)"),
277 OPT_END() 285 OPT_END()
278}; 286 };
279 287
280int cmd_annotate(int argc, const char **argv, const char *prefix __used)
281{
282 argc = parse_options(argc, argv, options, annotate_usage, 0); 288 argc = parse_options(argc, argv, options, annotate_usage, 0);
283 289
284 if (annotate.use_stdio) 290 if (annotate.use_stdio)
@@ -312,5 +318,5 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __used)
312 return -1; 318 return -1;
313 } 319 }
314 320
315 return __cmd_annotate(); 321 return __cmd_annotate(&annotate);
316} 322}