aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf
diff options
context:
space:
mode:
authorIan Munsie <imunsie@au1.ibm.com>2010-12-09 22:09:16 -0500
committerArnaldo Carvalho de Melo <acme@redhat.com>2010-12-21 17:17:51 -0500
commit21ef97f05a7da5bc23b26cb34d6746f83ca9bf20 (patch)
treec47c09c178f7929f01dcb7b302ceed21f3758ded /tools/perf
parent7639dae0ca11038286bbbcda05f2bef601c1eb8d (diff)
perf session: Fallback to unordered processing if no sample_id_all
If we are running the new perf on an old kernel without support for sample_id_all, we should fall back to the old unordered processing of events. If we didn't than we would *always* process events without timestamps out of order, whether or not we hit a reordering race. In other words, instead of there being a chance of not attributing samples correctly, we would guarantee that samples would not be attributed. While processing all events without timestamps before events with timestamps may seem like an intuitive solution, it falls down as PERF_RECORD_EXIT events would also be processed before any samples. Even with a workaround for that case, samples before/after an exec would not be attributed correctly. This patch allows commands to indicate whether they need to fall back to unordered processing, so that commands that do not care about timestamps on every event will not be affected. If we do fallback, this will print out a warning if report -D was invoked. This patch adds the test in perf_session__new so that we only need to test once per session. Commands that do not use an event_ops (such as record and top) can simply pass NULL in it's place. Acked-by: Thomas Gleixner <tglx@linutronix.de> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Ingo Molnar <mingo@elte.hu> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Thomas Gleixner <tglx@linutronix.de> LKML-Reference: <1291951882-sup-6069@au1.ibm.com> Signed-off-by: Ian Munsie <imunsie@au1.ibm.com> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf')
-rw-r--r--tools/perf/builtin-annotate.c2
-rw-r--r--tools/perf/builtin-buildid-list.c3
-rw-r--r--tools/perf/builtin-diff.c4
-rw-r--r--tools/perf/builtin-inject.c2
-rw-r--r--tools/perf/builtin-kmem.c3
-rw-r--r--tools/perf/builtin-lock.c2
-rw-r--r--tools/perf/builtin-record.c2
-rw-r--r--tools/perf/builtin-report.c2
-rw-r--r--tools/perf/builtin-sched.c3
-rw-r--r--tools/perf/builtin-script.c2
-rw-r--r--tools/perf/builtin-timechart.c3
-rw-r--r--tools/perf/builtin-top.c2
-rw-r--r--tools/perf/util/session.c11
-rw-r--r--tools/perf/util/session.h5
14 files changed, 31 insertions, 15 deletions
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index 569a2761b90a..48dbab4b482f 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -382,7 +382,7 @@ static int __cmd_annotate(void)
382 int ret; 382 int ret;
383 struct perf_session *session; 383 struct perf_session *session;
384 384
385 session = perf_session__new(input_name, O_RDONLY, force, false); 385 session = perf_session__new(input_name, O_RDONLY, force, false, &event_ops);
386 if (session == NULL) 386 if (session == NULL)
387 return -ENOMEM; 387 return -ENOMEM;
388 388
diff --git a/tools/perf/builtin-buildid-list.c b/tools/perf/builtin-buildid-list.c
index 44a47e13bd67..3b06f9ca2638 100644
--- a/tools/perf/builtin-buildid-list.c
+++ b/tools/perf/builtin-buildid-list.c
@@ -39,7 +39,8 @@ static int __cmd_buildid_list(void)
39 int err = -1; 39 int err = -1;
40 struct perf_session *session; 40 struct perf_session *session;
41 41
42 session = perf_session__new(input_name, O_RDONLY, force, false); 42 session = perf_session__new(input_name, O_RDONLY, force, false,
43 &build_id__mark_dso_hit_ops);
43 if (session == NULL) 44 if (session == NULL)
44 return -1; 45 return -1;
45 46
diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c
index 5e1a043aae03..af84e1c0519d 100644
--- a/tools/perf/builtin-diff.c
+++ b/tools/perf/builtin-diff.c
@@ -142,8 +142,8 @@ static int __cmd_diff(void)
142 int ret, i; 142 int ret, i;
143 struct perf_session *session[2]; 143 struct perf_session *session[2];
144 144
145 session[0] = perf_session__new(input_old, O_RDONLY, force, false); 145 session[0] = perf_session__new(input_old, O_RDONLY, force, false, &event_ops);
146 session[1] = perf_session__new(input_new, O_RDONLY, force, false); 146 session[1] = perf_session__new(input_new, O_RDONLY, force, false, &event_ops);
147 if (session[0] == NULL || session[1] == NULL) 147 if (session[0] == NULL || session[1] == NULL)
148 return -ENOMEM; 148 return -ENOMEM;
149 149
diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c
index 4b66b8579410..0c78ffa7bf67 100644
--- a/tools/perf/builtin-inject.c
+++ b/tools/perf/builtin-inject.c
@@ -196,7 +196,7 @@ static int __cmd_inject(void)
196 inject_ops.tracing_data = event__repipe_tracing_data; 196 inject_ops.tracing_data = event__repipe_tracing_data;
197 } 197 }
198 198
199 session = perf_session__new(input_name, O_RDONLY, false, true); 199 session = perf_session__new(input_name, O_RDONLY, false, true, &inject_ops);
200 if (session == NULL) 200 if (session == NULL)
201 return -ENOMEM; 201 return -ENOMEM;
202 202
diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c
index c9620ff6496f..def7ddc2fd4f 100644
--- a/tools/perf/builtin-kmem.c
+++ b/tools/perf/builtin-kmem.c
@@ -481,7 +481,8 @@ static void sort_result(void)
481static int __cmd_kmem(void) 481static int __cmd_kmem(void)
482{ 482{
483 int err = -EINVAL; 483 int err = -EINVAL;
484 struct perf_session *session = perf_session__new(input_name, O_RDONLY, 0, false); 484 struct perf_session *session = perf_session__new(input_name, O_RDONLY,
485 0, false, &event_ops);
485 if (session == NULL) 486 if (session == NULL)
486 return -ENOMEM; 487 return -ENOMEM;
487 488
diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c
index b41b4492b1cc..b9c6e5432971 100644
--- a/tools/perf/builtin-lock.c
+++ b/tools/perf/builtin-lock.c
@@ -858,7 +858,7 @@ static struct perf_event_ops eops = {
858 858
859static int read_events(void) 859static int read_events(void)
860{ 860{
861 session = perf_session__new(input_name, O_RDONLY, 0, false); 861 session = perf_session__new(input_name, O_RDONLY, 0, false, &eops);
862 if (!session) 862 if (!session)
863 die("Initializing perf session failed\n"); 863 die("Initializing perf session failed\n");
864 864
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index e9be6ae87a27..efd1b3c3d4a0 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -572,7 +572,7 @@ static int __cmd_record(int argc, const char **argv)
572 } 572 }
573 573
574 session = perf_session__new(output_name, O_WRONLY, 574 session = perf_session__new(output_name, O_WRONLY,
575 write_mode == WRITE_FORCE, false); 575 write_mode == WRITE_FORCE, false, NULL);
576 if (session == NULL) { 576 if (session == NULL) {
577 pr_err("Not enough memory for reading perf file header\n"); 577 pr_err("Not enough memory for reading perf file header\n");
578 return -1; 578 return -1;
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index b6a2a899aa8f..fd4c4500cd15 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -308,7 +308,7 @@ static int __cmd_report(void)
308 308
309 signal(SIGINT, sig_handler); 309 signal(SIGINT, sig_handler);
310 310
311 session = perf_session__new(input_name, O_RDONLY, force, false); 311 session = perf_session__new(input_name, O_RDONLY, force, false, &event_ops);
312 if (session == NULL) 312 if (session == NULL)
313 return -ENOMEM; 313 return -ENOMEM;
314 314
diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c
index c7753940aea0..7a4ebeb8b016 100644
--- a/tools/perf/builtin-sched.c
+++ b/tools/perf/builtin-sched.c
@@ -1643,7 +1643,8 @@ static struct perf_event_ops event_ops = {
1643static int read_events(void) 1643static int read_events(void)
1644{ 1644{
1645 int err = -EINVAL; 1645 int err = -EINVAL;
1646 struct perf_session *session = perf_session__new(input_name, O_RDONLY, 0, false); 1646 struct perf_session *session = perf_session__new(input_name, O_RDONLY,
1647 0, false, &event_ops);
1647 if (session == NULL) 1648 if (session == NULL)
1648 return -ENOMEM; 1649 return -ENOMEM;
1649 1650
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c
index 54f1ea808db5..6ef65c04ab9a 100644
--- a/tools/perf/builtin-script.c
+++ b/tools/perf/builtin-script.c
@@ -779,7 +779,7 @@ int cmd_script(int argc, const char **argv, const char *prefix __used)
779 if (!script_name) 779 if (!script_name)
780 setup_pager(); 780 setup_pager();
781 781
782 session = perf_session__new(input_name, O_RDONLY, 0, false); 782 session = perf_session__new(input_name, O_RDONLY, 0, false, &event_ops);
783 if (session == NULL) 783 if (session == NULL)
784 return -ENOMEM; 784 return -ENOMEM;
785 785
diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c
index d2fc46103f83..459b5e3db267 100644
--- a/tools/perf/builtin-timechart.c
+++ b/tools/perf/builtin-timechart.c
@@ -937,7 +937,8 @@ static struct perf_event_ops event_ops = {
937 937
938static int __cmd_timechart(void) 938static int __cmd_timechart(void)
939{ 939{
940 struct perf_session *session = perf_session__new(input_name, O_RDONLY, 0, false); 940 struct perf_session *session = perf_session__new(input_name, O_RDONLY,
941 0, false, &event_ops);
941 int ret = -EINVAL; 942 int ret = -EINVAL;
942 943
943 if (session == NULL) 944 if (session == NULL)
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index 0515ce9d3d3e..ae15f046c405 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -1272,7 +1272,7 @@ static int __cmd_top(void)
1272 * FIXME: perf_session__new should allow passing a O_MMAP, so that all this 1272 * FIXME: perf_session__new should allow passing a O_MMAP, so that all this
1273 * mmap reading, etc is encapsulated in it. Use O_WRONLY for now. 1273 * mmap reading, etc is encapsulated in it. Use O_WRONLY for now.
1274 */ 1274 */
1275 struct perf_session *session = perf_session__new(NULL, O_WRONLY, false, false); 1275 struct perf_session *session = perf_session__new(NULL, O_WRONLY, false, false, NULL);
1276 if (session == NULL) 1276 if (session == NULL)
1277 return -ENOMEM; 1277 return -ENOMEM;
1278 1278
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index b59abf5aba36..0f7e544544f5 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -125,7 +125,9 @@ static void perf_session__destroy_kernel_maps(struct perf_session *self)
125 machines__destroy_guest_kernel_maps(&self->machines); 125 machines__destroy_guest_kernel_maps(&self->machines);
126} 126}
127 127
128struct perf_session *perf_session__new(const char *filename, int mode, bool force, bool repipe) 128struct perf_session *perf_session__new(const char *filename, int mode,
129 bool force, bool repipe,
130 struct perf_event_ops *ops)
129{ 131{
130 size_t len = filename ? strlen(filename) + 1 : 0; 132 size_t len = filename ? strlen(filename) + 1 : 0;
131 struct perf_session *self = zalloc(sizeof(*self) + len); 133 struct perf_session *self = zalloc(sizeof(*self) + len);
@@ -170,6 +172,13 @@ struct perf_session *perf_session__new(const char *filename, int mode, bool forc
170 } 172 }
171 173
172 perf_session__update_sample_type(self); 174 perf_session__update_sample_type(self);
175
176 if (ops && ops->ordering_requires_timestamps &&
177 ops->ordered_samples && !self->sample_id_all) {
178 dump_printf("WARNING: No sample_id_all support, falling back to unordered processing\n");
179 ops->ordered_samples = false;
180 }
181
173out: 182out:
174 return self; 183 return self;
175out_free: 184out_free:
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h
index ac36f99f14af..ffe4b98db8f0 100644
--- a/tools/perf/util/session.h
+++ b/tools/perf/util/session.h
@@ -78,9 +78,12 @@ struct perf_event_ops {
78 build_id; 78 build_id;
79 event_op2 finished_round; 79 event_op2 finished_round;
80 bool ordered_samples; 80 bool ordered_samples;
81 bool ordering_requires_timestamps;
81}; 82};
82 83
83struct perf_session *perf_session__new(const char *filename, int mode, bool force, bool repipe); 84struct perf_session *perf_session__new(const char *filename, int mode,
85 bool force, bool repipe,
86 struct perf_event_ops *ops);
84void perf_session__delete(struct perf_session *self); 87void perf_session__delete(struct perf_session *self);
85 88
86void perf_event_header__bswap(struct perf_event_header *self); 89void perf_event_header__bswap(struct perf_event_header *self);