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

Commit 00966852 authored by Ingo Molnar's avatar Ingo Molnar
Browse files

Merge tag 'perf-core-for-mingo-20160303' of...

Merge tag 'perf-core-for-mingo-20160303' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux

 into perf/core

Pull perf/core improvements and fixes:

User visible changes:

 - Check existence of frontend/backed stalled cycles in 'perf stat' (Andi Kleen)

 - Implement CSV metrics output in 'perf stat' (Andi Kleen)

 - Support metrics in 'perf stat' --per-core/socket mode (Andi Kleen)

 - Avoid installing .o files from tools/lib/ into the python extension (Jiri Olsa)

 - Rename the tracepoint '/format' field that carries the syscall ID from 'nr',
   that is also the name of some syscalls arguments, to "__syscall_nr", to
   avoid having multiple fields with the same name, that was breaking the
   python script skeleton generator from perf.data files (Taeung Song)

 - Support converting data from bpf events in 'perf data' (Wang Nan)

 - Fix segfault in 'perf test' hists related entries (Arnaldo Carvalho de Melo)

 - Fix output of %llu for 64 bit values read on 32 bit machines in libtraceevent (Steven Rostedt)

 - Fix time stamp rounding issue in libtraceevent (Chaos.Chen)

Infrastructure changes:

 - Fix setlocale() breakage in the pmu parsing code (Jiri Olsa)

 - Split libtraceevent's pevent_print_event() (Steven Rostedt)

 - Librarize some 'perf record' bits to allow handling multiple perf.data
   files per session (Wang Nan)

 - Ensure return non-zero rc when mmap fails in 'perf record' (Wang Nan)

 - Fix double free on 'command_line' in a error path in 'perf script' (Colin Ian King)

 - Initialize struct sigaction 'sa_flags' field in a 'perf test' entry (Colin Ian King)

 - Fix various build warnings in turbostat, detected with gcc6 (Colin Ian King)

 - Use .s extension for preprocessed assembler code (Masahiro Yamada)

Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
parents 6f6e1516 fb4605ba
Loading
Loading
Loading
Loading
+9 −7
Original line number Original line Diff line number Diff line
@@ -186,11 +186,11 @@ print_syscall_exit(struct trace_iterator *iter, int flags,


extern char *__bad_type_size(void);
extern char *__bad_type_size(void);


#define SYSCALL_FIELD(type, name)					\
#define SYSCALL_FIELD(type, field, name)				\
	sizeof(type) != sizeof(trace.name) ?				\
	sizeof(type) != sizeof(trace.field) ?				\
		__bad_type_size() :					\
		__bad_type_size() :					\
		#type, #name, offsetof(typeof(trace), name),		\
		#type, #name, offsetof(typeof(trace), field),		\
		sizeof(trace.name), is_signed_type(type)
		sizeof(trace.field), is_signed_type(type)


static int __init
static int __init
__set_enter_print_fmt(struct syscall_metadata *entry, char *buf, int len)
__set_enter_print_fmt(struct syscall_metadata *entry, char *buf, int len)
@@ -261,7 +261,8 @@ static int __init syscall_enter_define_fields(struct trace_event_call *call)
	int i;
	int i;
	int offset = offsetof(typeof(trace), args);
	int offset = offsetof(typeof(trace), args);


	ret = trace_define_field(call, SYSCALL_FIELD(int, nr), FILTER_OTHER);
	ret = trace_define_field(call, SYSCALL_FIELD(int, nr, __syscall_nr),
				 FILTER_OTHER);
	if (ret)
	if (ret)
		return ret;
		return ret;


@@ -281,11 +282,12 @@ static int __init syscall_exit_define_fields(struct trace_event_call *call)
	struct syscall_trace_exit trace;
	struct syscall_trace_exit trace;
	int ret;
	int ret;


	ret = trace_define_field(call, SYSCALL_FIELD(int, nr), FILTER_OTHER);
	ret = trace_define_field(call, SYSCALL_FIELD(int, nr, __syscall_nr),
				 FILTER_OTHER);
	if (ret)
	if (ret)
		return ret;
		return ret;


	ret = trace_define_field(call, SYSCALL_FIELD(long, ret),
	ret = trace_define_field(call, SYSCALL_FIELD(long, ret, ret),
				 FILTER_OTHER);
				 FILTER_OTHER);


	return ret;
	return ret;
+1 −1
Original line number Original line Diff line number Diff line
@@ -85,7 +85,7 @@ $(OUTPUT)%.i: %.c FORCE
	$(call rule_mkdir)
	$(call rule_mkdir)
	$(call if_changed_dep,cc_i_c)
	$(call if_changed_dep,cc_i_c)


$(OUTPUT)%.i: %.S FORCE
$(OUTPUT)%.s: %.S FORCE
	$(call rule_mkdir)
	$(call rule_mkdir)
	$(call if_changed_dep,cc_i_c)
	$(call if_changed_dep,cc_i_c)


+113 −33
Original line number Original line Diff line number Diff line
@@ -2635,6 +2635,7 @@ process_hex(struct event_format *event, struct print_arg *arg, char **tok)


free_field:
free_field:
	free_arg(arg->hex.field);
	free_arg(arg->hex.field);
	arg->hex.field = NULL;
out:
out:
	*tok = NULL;
	*tok = NULL;
	return EVENT_ERROR;
	return EVENT_ERROR;
@@ -2659,8 +2660,10 @@ process_int_array(struct event_format *event, struct print_arg *arg, char **tok)


free_size:
free_size:
	free_arg(arg->int_array.count);
	free_arg(arg->int_array.count);
	arg->int_array.count = NULL;
free_field:
free_field:
	free_arg(arg->int_array.field);
	free_arg(arg->int_array.field);
	arg->int_array.field = NULL;
out:
out:
	*tok = NULL;
	*tok = NULL;
	return EVENT_ERROR;
	return EVENT_ERROR;
@@ -4975,7 +4978,7 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event
						break;
						break;
					}
					}
				}
				}
				if (pevent->long_size == 8 && ls &&
				if (pevent->long_size == 8 && ls == 1 &&
				    sizeof(long) != 8) {
				    sizeof(long) != 8) {
					char *p;
					char *p;


@@ -5339,51 +5342,89 @@ static bool is_timestamp_in_us(char *trace_clock, bool use_trace_clock)
	return false;
	return false;
}
}


void pevent_print_event(struct pevent *pevent, struct trace_seq *s,
/**
			struct pevent_record *record, bool use_trace_clock)
 * pevent_find_event_by_record - return the event from a given record
 * @pevent: a handle to the pevent
 * @record: The record to get the event from
 *
 * Returns the associated event for a given record, or NULL if non is
 * is found.
 */
struct event_format *
pevent_find_event_by_record(struct pevent *pevent, struct pevent_record *record)
{
{
	static const char *spaces = "                    "; /* 20 spaces */
	struct event_format *event;
	unsigned long secs;
	unsigned long usecs;
	unsigned long nsecs;
	const char *comm;
	void *data = record->data;
	int type;
	int type;
	int pid;
	int len;
	int p;
	bool use_usec_format;

	use_usec_format = is_timestamp_in_us(pevent->trace_clock,
							use_trace_clock);
	if (use_usec_format) {
		secs = record->ts / NSECS_PER_SEC;
		nsecs = record->ts - secs * NSECS_PER_SEC;
	}


	if (record->size < 0) {
	if (record->size < 0) {
		do_warning("ug! negative record size %d", record->size);
		do_warning("ug! negative record size %d", record->size);
		return;
		return NULL;
	}
	}


	type = trace_parse_common_type(pevent, data);
	type = trace_parse_common_type(pevent, record->data);


	event = pevent_find_event(pevent, type);
	return pevent_find_event(pevent, type);
	if (!event) {
		do_warning("ug! no event found for type %d", type);
		return;
}
}


/**
 * pevent_print_event_task - Write the event task comm, pid and CPU
 * @pevent: a handle to the pevent
 * @s: the trace_seq to write to
 * @event: the handle to the record's event
 * @record: The record to get the event from
 *
 * Writes the tasks comm, pid and CPU to @s.
 */
void pevent_print_event_task(struct pevent *pevent, struct trace_seq *s,
			     struct event_format *event,
			     struct pevent_record *record)
{
	void *data = record->data;
	const char *comm;
	int pid;

	pid = parse_common_pid(pevent, data);
	pid = parse_common_pid(pevent, data);
	comm = find_cmdline(pevent, pid);
	comm = find_cmdline(pevent, pid);


	if (pevent->latency_format) {
	if (pevent->latency_format) {
		trace_seq_printf(s, "%8.8s-%-5d %3d",
		trace_seq_printf(s, "%8.8s-%-5d %3d",
		       comm, pid, record->cpu);
		       comm, pid, record->cpu);
		pevent_data_lat_fmt(pevent, s, record);
	} else
	} else
		trace_seq_printf(s, "%16s-%-5d [%03d]", comm, pid, record->cpu);
		trace_seq_printf(s, "%16s-%-5d [%03d]", comm, pid, record->cpu);
}

/**
 * pevent_print_event_time - Write the event timestamp
 * @pevent: a handle to the pevent
 * @s: the trace_seq to write to
 * @event: the handle to the record's event
 * @record: The record to get the event from
 * @use_trace_clock: Set to parse according to the @pevent->trace_clock
 *
 * Writes the timestamp of the record into @s.
 */
void pevent_print_event_time(struct pevent *pevent, struct trace_seq *s,
			     struct event_format *event,
			     struct pevent_record *record,
			     bool use_trace_clock)
{
	unsigned long secs;
	unsigned long usecs;
	unsigned long nsecs;
	int p;
	bool use_usec_format;

	use_usec_format = is_timestamp_in_us(pevent->trace_clock,
							use_trace_clock);
	if (use_usec_format) {
		secs = record->ts / NSECS_PER_SEC;
		nsecs = record->ts - secs * NSECS_PER_SEC;
	}

	if (pevent->latency_format) {
		trace_seq_printf(s, " %3d", record->cpu);
		pevent_data_lat_fmt(pevent, s, record);
	} else
		trace_seq_printf(s, " [%03d]", record->cpu);


	if (use_usec_format) {
	if (use_usec_format) {
		if (pevent->flags & PEVENT_NSEC_OUTPUT) {
		if (pevent->flags & PEVENT_NSEC_OUTPUT) {
@@ -5391,14 +5432,36 @@ void pevent_print_event(struct pevent *pevent, struct trace_seq *s,
			p = 9;
			p = 9;
		} else {
		} else {
			usecs = (nsecs + 500) / NSECS_PER_USEC;
			usecs = (nsecs + 500) / NSECS_PER_USEC;
			/* To avoid usecs larger than 1 sec */
			if (usecs >= 1000000) {
				usecs -= 1000000;
				secs++;
			}
			p = 6;
			p = 6;
		}
		}


		trace_seq_printf(s, " %5lu.%0*lu: %s: ",
		trace_seq_printf(s, " %5lu.%0*lu:", secs, p, usecs);
					secs, p, usecs, event->name);
	} else
	} else
		trace_seq_printf(s, " %12llu: %s: ",
		trace_seq_printf(s, " %12llu:", record->ts);
					record->ts, event->name);
}

/**
 * pevent_print_event_data - Write the event data section
 * @pevent: a handle to the pevent
 * @s: the trace_seq to write to
 * @event: the handle to the record's event
 * @record: The record to get the event from
 *
 * Writes the parsing of the record's data to @s.
 */
void pevent_print_event_data(struct pevent *pevent, struct trace_seq *s,
			     struct event_format *event,
			     struct pevent_record *record)
{
	static const char *spaces = "                    "; /* 20 spaces */
	int len;

	trace_seq_printf(s, " %s: ", event->name);


	/* Space out the event names evenly. */
	/* Space out the event names evenly. */
	len = strlen(event->name);
	len = strlen(event->name);
@@ -5408,6 +5471,23 @@ void pevent_print_event(struct pevent *pevent, struct trace_seq *s,
	pevent_event_info(s, event, record);
	pevent_event_info(s, event, record);
}
}


void pevent_print_event(struct pevent *pevent, struct trace_seq *s,
			struct pevent_record *record, bool use_trace_clock)
{
	struct event_format *event;

	event = pevent_find_event_by_record(pevent, record);
	if (!event) {
		do_warning("ug! no event found for type %d",
			   trace_parse_common_type(pevent, record->data));
		return;
	}

	pevent_print_event_task(pevent, s, event, record);
	pevent_print_event_time(pevent, s, event, record, use_trace_clock);
	pevent_print_event_data(pevent, s, event, record);
}

static int events_id_cmp(const void *a, const void *b)
static int events_id_cmp(const void *a, const void *b)
{
{
	struct event_format * const * ea = a;
	struct event_format * const * ea = a;
+13 −0
Original line number Original line Diff line number Diff line
@@ -628,6 +628,16 @@ int pevent_register_print_string(struct pevent *pevent, const char *fmt,
				 unsigned long long addr);
				 unsigned long long addr);
int pevent_pid_is_registered(struct pevent *pevent, int pid);
int pevent_pid_is_registered(struct pevent *pevent, int pid);


void pevent_print_event_task(struct pevent *pevent, struct trace_seq *s,
			     struct event_format *event,
			     struct pevent_record *record);
void pevent_print_event_time(struct pevent *pevent, struct trace_seq *s,
			     struct event_format *event,
			     struct pevent_record *record,
			     bool use_trace_clock);
void pevent_print_event_data(struct pevent *pevent, struct trace_seq *s,
			     struct event_format *event,
			     struct pevent_record *record);
void pevent_print_event(struct pevent *pevent, struct trace_seq *s,
void pevent_print_event(struct pevent *pevent, struct trace_seq *s,
			struct pevent_record *record, bool use_trace_clock);
			struct pevent_record *record, bool use_trace_clock);


@@ -694,6 +704,9 @@ struct event_format *pevent_find_event(struct pevent *pevent, int id);
struct event_format *
struct event_format *
pevent_find_event_by_name(struct pevent *pevent, const char *sys, const char *name);
pevent_find_event_by_name(struct pevent *pevent, const char *sys, const char *name);


struct event_format *
pevent_find_event_by_record(struct pevent *pevent, struct pevent_record *record);

void pevent_data_lat_fmt(struct pevent *pevent,
void pevent_data_lat_fmt(struct pevent *pevent,
			 struct trace_seq *s, struct pevent_record *record);
			 struct trace_seq *s, struct pevent_record *record);
int pevent_data_type(struct pevent *pevent, struct pevent_record *rec);
int pevent_data_type(struct pevent *pevent, struct pevent_record *rec);
+1 −0
Original line number Original line Diff line number Diff line
@@ -103,6 +103,7 @@ static int __test__rdpmc(void)


	sigfillset(&sa.sa_mask);
	sigfillset(&sa.sa_mask);
	sa.sa_sigaction = segfault_handler;
	sa.sa_sigaction = segfault_handler;
	sa.sa_flags = 0;
	sigaction(SIGSEGV, &sa, NULL);
	sigaction(SIGSEGV, &sa, NULL);


	fd = sys_perf_event_open(&attr, 0, -1, -1,
	fd = sys_perf_event_open(&attr, 0, -1, -1,
Loading