diff options
Diffstat (limited to 'kernel/trace/trace_output.c')
| -rw-r--r-- | kernel/trace/trace_output.c | 93 | 
1 files changed, 76 insertions, 17 deletions
diff --git a/kernel/trace/trace_output.c b/kernel/trace/trace_output.c index 61255bad7e01..d0368a569bfa 100644 --- a/kernel/trace/trace_output.c +++ b/kernel/trace/trace_output.c @@ -317,7 +317,7 @@ void trace_event_printf(struct trace_iterator *iter, const char *fmt, ...)  	va_list ap;  	va_start(ap, fmt); -	trace_seq_vprintf(&iter->seq, trace_event_format(iter, fmt), ap); +	trace_check_vprintf(iter, trace_event_format(iter, fmt), ap);  	va_end(ap);  }  EXPORT_SYMBOL(trace_event_printf); @@ -587,13 +587,26 @@ lat_print_timestamp(struct trace_iterator *iter, u64 next_ts)  	return !trace_seq_has_overflowed(s);  } +static void trace_print_time(struct trace_seq *s, struct trace_iterator *iter, +			     unsigned long long ts) +{ +	unsigned long secs, usec_rem; +	unsigned long long t; + +	if (iter->iter_flags & TRACE_FILE_TIME_IN_NS) { +		t = ns2usecs(ts); +		usec_rem = do_div(t, USEC_PER_SEC); +		secs = (unsigned long)t; +		trace_seq_printf(s, " %5lu.%06lu", secs, usec_rem); +	} else +		trace_seq_printf(s, " %12llu", ts); +} +  int trace_print_context(struct trace_iterator *iter)  {  	struct trace_array *tr = iter->tr;  	struct trace_seq *s = &iter->seq;  	struct trace_entry *entry = iter->ent; -	unsigned long long t; -	unsigned long secs, usec_rem;  	char comm[TASK_COMM_LEN];  	trace_find_cmdline(entry->pid, comm); @@ -614,13 +627,8 @@ int trace_print_context(struct trace_iterator *iter)  	if (tr->trace_flags & TRACE_ITER_IRQ_INFO)  		trace_print_lat_fmt(s, entry); -	if (iter->iter_flags & TRACE_FILE_TIME_IN_NS) { -		t = ns2usecs(iter->ts); -		usec_rem = do_div(t, USEC_PER_SEC); -		secs = (unsigned long)t; -		trace_seq_printf(s, " %5lu.%06lu: ", secs, usec_rem); -	} else -		trace_seq_printf(s, " %12llu: ", iter->ts); +	trace_print_time(s, iter, iter->ts); +	trace_seq_puts(s, ": ");  	return !trace_seq_has_overflowed(s);  } @@ -837,6 +845,17 @@ enum print_line_t trace_nop_print(struct trace_iterator *iter, int flags,  	return trace_handle_return(&iter->seq);  } +static void print_fn_trace(struct trace_seq *s, unsigned long ip, +			   unsigned long parent_ip, int flags) +{ +	seq_print_ip_sym(s, ip, flags); + +	if ((flags & TRACE_ITER_PRINT_PARENT) && parent_ip) { +		trace_seq_puts(s, " <-"); +		seq_print_ip_sym(s, parent_ip, flags); +	} +} +  /* TRACE_FN */  static enum print_line_t trace_fn_trace(struct trace_iterator *iter, int flags,  					struct trace_event *event) @@ -846,13 +865,7 @@ static enum print_line_t trace_fn_trace(struct trace_iterator *iter, int flags,  	trace_assign_type(field, iter->ent); -	seq_print_ip_sym(s, field->ip, flags); - -	if ((flags & TRACE_ITER_PRINT_PARENT) && field->parent_ip) { -		trace_seq_puts(s, " <-"); -		seq_print_ip_sym(s, field->parent_ip, flags); -	} - +	print_fn_trace(s, field->ip, field->parent_ip, flags);  	trace_seq_putc(s, '\n');  	return trace_handle_return(s); @@ -1373,6 +1386,51 @@ static struct trace_event trace_raw_data_event = {  	.funcs		= &trace_raw_data_funcs,  }; +static enum print_line_t +trace_func_repeats_raw(struct trace_iterator *iter, int flags, +			 struct trace_event *event) +{ +	struct func_repeats_entry *field; +	struct trace_seq *s = &iter->seq; + +	trace_assign_type(field, iter->ent); + +	trace_seq_printf(s, "%lu %lu %u %llu\n", +			 field->ip, +			 field->parent_ip, +			 field->count, +			 FUNC_REPEATS_GET_DELTA_TS(field)); + +	return trace_handle_return(s); +} + +static enum print_line_t +trace_func_repeats_print(struct trace_iterator *iter, int flags, +			 struct trace_event *event) +{ +	struct func_repeats_entry *field; +	struct trace_seq *s = &iter->seq; + +	trace_assign_type(field, iter->ent); + +	print_fn_trace(s, field->ip, field->parent_ip, flags); +	trace_seq_printf(s, " (repeats: %u, last_ts:", field->count); +	trace_print_time(s, iter, +			 iter->ts - FUNC_REPEATS_GET_DELTA_TS(field)); +	trace_seq_puts(s, ")\n"); + +	return trace_handle_return(s); +} + +static struct trace_event_functions trace_func_repeats_funcs = { +	.trace		= trace_func_repeats_print, +	.raw		= trace_func_repeats_raw, +}; + +static struct trace_event trace_func_repeats_event = { +	.type	 	= TRACE_FUNC_REPEATS, +	.funcs		= &trace_func_repeats_funcs, +};  static struct trace_event *events[] __initdata = {  	&trace_fn_event, @@ -1385,6 +1443,7 @@ static struct trace_event *events[] __initdata = {  	&trace_print_event,  	&trace_hwlat_event,  	&trace_raw_data_event, +	&trace_func_repeats_event,  	NULL  };  |