perf: record TRACE_INFO only if using tracepoints and SAMPLE_RAW
authorTom Zanussi <tzanussi@gmail.com>
Mon, 3 May 2010 05:14:48 +0000 (00:14 -0500)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Mon, 3 May 2010 13:31:48 +0000 (10:31 -0300)
The current perf code implicitly assumes SAMPLE_RAW means tracepoints
are being used, but doesn't check for that.  It happily records the
TRACE_INFO even if SAMPLE_RAW is used without tracepoints, but when the
perf data is read it won't go any further when it finds TRACE_INFO but
no tracepoints, and displays misleading errors.

This adds a check for both in perf-record, and won't record TRACE_INFO
unless both are true.  This at least allows perf report -D to dump raw
events, and avoids triggering a misleading error condition in perf
trace.  It doesn't actually enable the non-tracepoint raw events to be
displayed in perf trace, since perf trace currently only deals with
tracepoint events.

Cc: Frédéric Weisbecker <fweisbec@gmail.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
LKML-Reference: <1272865861.7932.16.camel@tropicana>
Signed-off-by: Tom Zanussi <tzanussi@gmail.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/builtin-record.c
tools/perf/util/header.c
tools/perf/util/parse-events.h
tools/perf/util/trace-event-info.c

index ac989e9ba8fe067dd1e94a1e2d48ea42ef3b471f..0ff67d1c4752c930719f810e57c226d98f03facc 100644 (file)
@@ -560,11 +560,12 @@ static int __cmd_record(int argc, const char **argv)
                        return err;
        }
 
-       if (raw_samples) {
+       if (raw_samples && have_tracepoints(attrs, nr_counters)) {
                perf_header__set_feat(&session->header, HEADER_TRACE_INFO);
        } else {
                for (i = 0; i < nr_counters; i++) {
-                       if (attrs[i].sample_type & PERF_SAMPLE_RAW) {
+                       if (attrs[i].sample_type & PERF_SAMPLE_RAW &&
+                               attrs[i].type == PERF_TYPE_TRACEPOINT) {
                                perf_header__set_feat(&session->header, HEADER_TRACE_INFO);
                                break;
                        }
@@ -662,19 +663,25 @@ static int __cmd_record(int argc, const char **argv)
                        return err;
                }
 
-               err = event__synthesize_tracing_data(output, attrs,
-                                                    nr_counters,
-                                                    process_synthesized_event,
-                                                    session);
-               /*
-                * FIXME err <= 0 here actually means that there were no tracepoints
-                * so its not really an error, just that we don't need to synthesize
-                * anything.
-                * We really have to return this more properly and also propagate
-                * errors that now are calling die()
-                */
-               if (err > 0)
+               if (have_tracepoints(attrs, nr_counters)) {
+                       /*
+                        * FIXME err <= 0 here actually means that
+                        * there were no tracepoints so its not really
+                        * an error, just that we don't need to
+                        * synthesize anything.  We really have to
+                        * return this more properly and also
+                        * propagate errors that now are calling die()
+                        */
+                       err = event__synthesize_tracing_data(output, attrs,
+                                                            nr_counters,
+                                                            process_synthesized_event,
+                                                            session);
+                       if (err <= 0) {
+                               pr_err("Couldn't record tracing data.\n");
+                               return err;
+                       }
                        advance_output(err);
+               }
        }
 
        machine = perf_session__find_host_machine(session);
index 79da0e50ef8ff1a7456eb4757c94c7629f168fbb..2b9f898efea6479290018d3aa7c6339586d4b45f 100644 (file)
@@ -436,7 +436,6 @@ static int perf_header__adds_write(struct perf_header *self, int fd)
                trace_sec->size = lseek(fd, 0, SEEK_CUR) - trace_sec->offset;
        }
 
-
        if (perf_header__has_feat(self, HEADER_BUILD_ID)) {
                struct perf_file_section *buildid_sec;
 
index b8c1f64bc9351ac7f889340c20eb7755614f5227..fc4ab3fe877a22d191450a6bc4c75118cf71901d 100644 (file)
@@ -13,6 +13,7 @@ struct tracepoint_path {
 };
 
 extern struct tracepoint_path *tracepoint_id_to_path(u64 config);
+extern bool have_tracepoints(struct perf_event_attr *pattrs, int nb_events);
 
 extern int                     nr_counters;
 
index 30cd9b57595301ed3793f84f96b6ce6b279c8a40..0a1fb9d4f3b60b75edd8b00071ec9ef1062e8cea 100644 (file)
@@ -487,6 +487,11 @@ get_tracepoints_path(struct perf_event_attr *pattrs, int nb_events)
        return nr_tracepoints > 0 ? path.next : NULL;
 }
 
+bool have_tracepoints(struct perf_event_attr *pattrs, int nb_events)
+{
+       return get_tracepoints_path(pattrs, nb_events) ? true : false;
+}
+
 int read_tracing_data(int fd, struct perf_event_attr *pattrs, int nb_events)
 {
        char buf[BUFSIZ];