Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 63e0c771 authored by Tom Zanussi's avatar Tom Zanussi Committed by Arnaldo Carvalho de Melo
Browse files

perf: record TRACE_INFO only if using tracepoints and SAMPLE_RAW



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: default avatarTom Zanussi <tzanussi@gmail.com>
Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent 090f7204
Loading
Loading
Loading
Loading
+21 −14
Original line number Diff line number Diff line
@@ -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,20 +663,26 @@ static int __cmd_record(int argc, const char **argv)
			return err;
		}

		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);
		/*
		 * 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 (err <= 0) {
				pr_err("Couldn't record tracing data.\n");
				return err;
			}
			advance_output(err);
		}
	}

	machine = perf_session__find_host_machine(session);
	if (!machine) {
+0 −1
Original line number Diff line number Diff line
@@ -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;

+1 −0
Original line number Diff line number Diff line
@@ -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;

+5 −0
Original line number Diff line number Diff line
@@ -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];