aboutsummaryrefslogtreecommitdiff
path: root/kernel/trace/trace_output.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/trace/trace_output.c')
-rw-r--r--kernel/trace/trace_output.c246
1 files changed, 169 insertions, 77 deletions
diff --git a/kernel/trace/trace_output.c b/kernel/trace/trace_output.c
index 1a4e144a9f8..c24503b281a 100644
--- a/kernel/trace/trace_output.c
+++ b/kernel/trace/trace_output.c
@@ -286,6 +286,113 @@ seq_print_ip_sym(struct trace_seq *s, unsigned long ip, unsigned long sym_flags)
return ret;
}
+static void
+lat_print_generic(struct trace_seq *s, struct trace_entry *entry, int cpu)
+{
+ int hardirq, softirq;
+ char *comm;
+
+ comm = trace_find_cmdline(entry->pid);
+
+ trace_seq_printf(s, "%8.8s-%-5d ", comm, entry->pid);
+ trace_seq_printf(s, "%3d", cpu);
+ trace_seq_printf(s, "%c%c",
+ (entry->flags & TRACE_FLAG_IRQS_OFF) ? 'd' :
+ (entry->flags & TRACE_FLAG_IRQS_NOSUPPORT) ? 'X' : '.',
+ ((entry->flags & TRACE_FLAG_NEED_RESCHED) ? 'N' : '.'));
+
+ hardirq = entry->flags & TRACE_FLAG_HARDIRQ;
+ softirq = entry->flags & TRACE_FLAG_SOFTIRQ;
+ if (hardirq && softirq) {
+ trace_seq_putc(s, 'H');
+ } else {
+ if (hardirq) {
+ trace_seq_putc(s, 'h');
+ } else {
+ if (softirq)
+ trace_seq_putc(s, 's');
+ else
+ trace_seq_putc(s, '.');
+ }
+ }
+
+ if (entry->preempt_count)
+ trace_seq_printf(s, "%x", entry->preempt_count);
+ else
+ trace_seq_puts(s, ".");
+}
+
+static unsigned long preempt_mark_thresh = 100;
+
+static void
+lat_print_timestamp(struct trace_seq *s, u64 abs_usecs,
+ unsigned long rel_usecs)
+{
+ trace_seq_printf(s, " %4lldus", abs_usecs);
+ if (rel_usecs > preempt_mark_thresh)
+ trace_seq_puts(s, "!: ");
+ else if (rel_usecs > 1)
+ trace_seq_puts(s, "+: ");
+ else
+ trace_seq_puts(s, " : ");
+}
+
+int trace_print_context(struct trace_iterator *iter)
+{
+ struct trace_seq *s = &iter->seq;
+ struct trace_entry *entry = iter->ent;
+ char *comm = trace_find_cmdline(entry->pid);
+ unsigned long long t = ns2usecs(iter->ts);
+ unsigned long usec_rem = do_div(t, USEC_PER_SEC);
+ unsigned long secs = (unsigned long)t;
+
+ if (!trace_seq_printf(s, "%16s-%-5d ", comm, entry->pid))
+ goto partial;
+ if (!trace_seq_printf(s, "[%03d] ", entry->cpu))
+ goto partial;
+ if (!trace_seq_printf(s, "%5lu.%06lu: ", secs, usec_rem))
+ goto partial;
+
+ return 0;
+
+partial:
+ return TRACE_TYPE_PARTIAL_LINE;
+}
+
+int trace_print_lat_context(struct trace_iterator *iter)
+{
+ u64 next_ts;
+ struct trace_seq *s = &iter->seq;
+ struct trace_entry *entry = iter->ent,
+ *next_entry = trace_find_next_entry(iter, NULL,
+ &next_ts);
+ unsigned long verbose = (trace_flags & TRACE_ITER_VERBOSE);
+ unsigned long abs_usecs = ns2usecs(iter->ts - iter->tr->time_start);
+ unsigned long rel_usecs;
+
+ if (!next_entry)
+ next_ts = iter->ts;
+ rel_usecs = ns2usecs(next_ts - iter->ts);
+
+ if (verbose) {
+ char *comm = trace_find_cmdline(entry->pid);
+ trace_seq_printf(s, "%16s %5d %3d %d %08x %08lx [%08lx]"
+ " %ld.%03ldms (+%ld.%03ldms): ",
+ comm,
+ entry->pid, entry->cpu, entry->flags,
+ entry->preempt_count, iter->idx,
+ ns2usecs(iter->ts),
+ abs_usecs/1000,
+ abs_usecs % 1000, rel_usecs/1000,
+ rel_usecs % 1000);
+ } else {
+ lat_print_generic(s, entry, entry->cpu);
+ lat_print_timestamp(s, abs_usecs, rel_usecs);
+ }
+
+ return 0;
+}
+
static const char state_to_char[] = TASK_STATE_TO_CHAR_STR;
static int task_state_char(unsigned long state)
@@ -377,19 +484,18 @@ int unregister_ftrace_event(struct trace_event *event)
* Standard events
*/
-int
-trace_nop_print(struct trace_seq *s, struct trace_entry *entry, int flags)
+int trace_nop_print(struct trace_iterator *iter, int flags)
{
return 0;
}
/* TRACE_FN */
-static int
-trace_fn_latency(struct trace_seq *s, struct trace_entry *entry, int flags)
+static int trace_fn_latency(struct trace_iterator *iter, int flags)
{
struct ftrace_entry *field;
+ struct trace_seq *s = &iter->seq;
- trace_assign_type(field, entry);
+ trace_assign_type(field, iter->ent);
if (!seq_print_ip_sym(s, field->ip, flags))
goto partial;
@@ -406,12 +512,12 @@ trace_fn_latency(struct trace_seq *s, struct trace_entry *entry, int flags)
return TRACE_TYPE_PARTIAL_LINE;
}
-static int
-trace_fn_trace(struct trace_seq *s, struct trace_entry *entry, int flags)
+static int trace_fn_trace(struct trace_iterator *iter, int flags)
{
struct ftrace_entry *field;
+ struct trace_seq *s = &iter->seq;
- trace_assign_type(field, entry);
+ trace_assign_type(field, iter->ent);
if (!seq_print_ip_sym(s, field->ip, flags))
goto partial;
@@ -433,14 +539,13 @@ trace_fn_trace(struct trace_seq *s, struct trace_entry *entry, int flags)
return TRACE_TYPE_PARTIAL_LINE;
}
-static int
-trace_fn_raw(struct trace_seq *s, struct trace_entry *entry, int flags)
+static int trace_fn_raw(struct trace_iterator *iter, int flags)
{
struct ftrace_entry *field;
- trace_assign_type(field, entry);
+ trace_assign_type(field, iter->ent);
- if (!trace_seq_printf(s, "%lx %lx\n",
+ if (!trace_seq_printf(&iter->seq, "%lx %lx\n",
field->ip,
field->parent_ip))
return TRACE_TYPE_PARTIAL_LINE;
@@ -448,12 +553,12 @@ trace_fn_raw(struct trace_seq *s, struct trace_entry *entry, int flags)
return 0;
}
-static int
-trace_fn_hex(struct trace_seq *s, struct trace_entry *entry, int flags)
+static int trace_fn_hex(struct trace_iterator *iter, int flags)
{
struct ftrace_entry *field;
+ struct trace_seq *s = &iter->seq;
- trace_assign_type(field, entry);
+ trace_assign_type(field, iter->ent);
SEQ_PUT_HEX_FIELD_RET(s, field->ip);
SEQ_PUT_HEX_FIELD_RET(s, field->parent_ip);
@@ -461,12 +566,12 @@ trace_fn_hex(struct trace_seq *s, struct trace_entry *entry, int flags)
return 0;
}
-static int
-trace_fn_bin(struct trace_seq *s, struct trace_entry *entry, int flags)
+static int trace_fn_bin(struct trace_iterator *iter, int flags)
{
struct ftrace_entry *field;
+ struct trace_seq *s = &iter->seq;
- trace_assign_type(field, entry);
+ trace_assign_type(field, iter->ent);
SEQ_PUT_FIELD_RET(s, field->ip);
SEQ_PUT_FIELD_RET(s, field->parent_ip);
@@ -484,20 +589,19 @@ static struct trace_event trace_fn_event = {
};
/* TRACE_CTX an TRACE_WAKE */
-static int
-trace_ctxwake_print(struct trace_seq *s, struct trace_entry *entry, int flags,
- char *delim)
+static int trace_ctxwake_print(struct trace_iterator *iter, char *delim)
{
struct ctx_switch_entry *field;
char *comm;
int S, T;
- trace_assign_type(field, entry);
+ trace_assign_type(field, iter->ent);
T = task_state_char(field->next_state);
S = task_state_char(field->prev_state);
comm = trace_find_cmdline(field->next_pid);
- if (!trace_seq_printf(s, " %5d:%3d:%c %s [%03d] %5d:%3d:%c %s\n",
+ if (!trace_seq_printf(&iter->seq,
+ " %5d:%3d:%c %s [%03d] %5d:%3d:%c %s\n",
field->prev_pid,
field->prev_prio,
S, delim,
@@ -510,31 +614,27 @@ trace_ctxwake_print(struct trace_seq *s, struct trace_entry *entry, int flags,
return 0;
}
-static int
-trace_ctx_print(struct trace_seq *s, struct trace_entry *entry, int flags)
+static int trace_ctx_print(struct trace_iterator *iter, int flags)
{
- return trace_ctxwake_print(s, entry, flags, "==>");
+ return trace_ctxwake_print(iter, "==>");
}
-static int
-trace_wake_print(struct trace_seq *s, struct trace_entry *entry, int flags)
+static int trace_wake_print(struct trace_iterator *iter, int flags)
{
- return trace_ctxwake_print(s, entry, flags, " +");
+ return trace_ctxwake_print(iter, " +");
}
-static int
-trace_ctxwake_raw(struct trace_seq *s, struct trace_entry *entry, int flags,
- char S)
+static int trace_ctxwake_raw(struct trace_iterator *iter, char S)
{
struct ctx_switch_entry *field;
int T;
- trace_assign_type(field, entry);
+ trace_assign_type(field, iter->ent);
if (!S)
task_state_char(field->prev_state);
T = task_state_char(field->next_state);
- if (!trace_seq_printf(s, "%d %d %c %d %d %d %c\n",
+ if (!trace_seq_printf(&iter->seq, "%d %d %c %d %d %d %c\n",
field->prev_pid,
field->prev_prio,
S,
@@ -547,27 +647,24 @@ trace_ctxwake_raw(struct trace_seq *s, struct trace_entry *entry, int flags,
return 0;
}
-static int
-trace_ctx_raw(struct trace_seq *s, struct trace_entry *entry, int flags)
+static int trace_ctx_raw(struct trace_iterator *iter, int flags)
{
- return trace_ctxwake_raw(s, entry, flags, 0);
+ return trace_ctxwake_raw(iter, 0);
}
-static int
-trace_wake_raw(struct trace_seq *s, struct trace_entry *entry, int flags)
+static int trace_wake_raw(struct trace_iterator *iter, int flags)
{
- return trace_ctxwake_raw(s, entry, flags, '+');
+ return trace_ctxwake_raw(iter, '+');
}
-static int
-trace_ctxwake_hex(struct trace_seq *s, struct trace_entry *entry, int flags,
- char S)
+static int trace_ctxwake_hex(struct trace_iterator *iter, char S)
{
struct ctx_switch_entry *field;
+ struct trace_seq *s = &iter->seq;
int T;
- trace_assign_type(field, entry);
+ trace_assign_type(field, iter->ent);
if (!S)
task_state_char(field->prev_state);
@@ -584,24 +681,22 @@ trace_ctxwake_hex(struct trace_seq *s, struct trace_entry *entry, int flags,
return 0;
}
-static int
-trace_ctx_hex(struct trace_seq *s, struct trace_entry *entry, int flags)
+static int trace_ctx_hex(struct trace_iterator *iter, int flags)
{
- return trace_ctxwake_hex(s, entry, flags, 0);
+ return trace_ctxwake_hex(iter, 0);
}
-static int
-trace_wake_hex(struct trace_seq *s, struct trace_entry *entry, int flags)
+static int trace_wake_hex(struct trace_iterator *iter, int flags)
{
- return trace_ctxwake_hex(s, entry, flags, '+');
+ return trace_ctxwake_hex(iter, '+');
}
-static int
-trace_ctxwake_bin(struct trace_seq *s, struct trace_entry *entry, int flags)
+static int trace_ctxwake_bin(struct trace_iterator *iter, int flags)
{
struct ctx_switch_entry *field;
+ struct trace_seq *s = &iter->seq;
- trace_assign_type(field, entry);
+ trace_assign_type(field, iter->ent);
SEQ_PUT_FIELD_RET(s, field->prev_pid);
SEQ_PUT_FIELD_RET(s, field->prev_prio);
@@ -632,14 +727,13 @@ static struct trace_event trace_wake_event = {
};
/* TRACE_SPECIAL */
-static int
-trace_special_print(struct trace_seq *s, struct trace_entry *entry, int flags)
+static int trace_special_print(struct trace_iterator *iter, int flags)
{
struct special_entry *field;
- trace_assign_type(field, entry);
+ trace_assign_type(field, iter->ent);
- if (!trace_seq_printf(s, "# %ld %ld %ld\n",
+ if (!trace_seq_printf(&iter->seq, "# %ld %ld %ld\n",
field->arg1,
field->arg2,
field->arg3))
@@ -648,12 +742,12 @@ trace_special_print(struct trace_seq *s, struct trace_entry *entry, int flags)
return 0;
}
-static int
-trace_special_hex(struct trace_seq *s, struct trace_entry *entry, int flags)
+static int trace_special_hex(struct trace_iterator *iter, int flags)
{
struct special_entry *field;
+ struct trace_seq *s = &iter->seq;
- trace_assign_type(field, entry);
+ trace_assign_type(field, iter->ent);
SEQ_PUT_HEX_FIELD_RET(s, field->arg1);
SEQ_PUT_HEX_FIELD_RET(s, field->arg2);
@@ -662,12 +756,12 @@ trace_special_hex(struct trace_seq *s, struct trace_entry *entry, int flags)
return 0;
}
-static int
-trace_special_bin(struct trace_seq *s, struct trace_entry *entry, int flags)
+static int trace_special_bin(struct trace_iterator *iter, int flags)
{
struct special_entry *field;
+ struct trace_seq *s = &iter->seq;
- trace_assign_type(field, entry);
+ trace_assign_type(field, iter->ent);
SEQ_PUT_FIELD_RET(s, field->arg1);
SEQ_PUT_FIELD_RET(s, field->arg2);
@@ -687,13 +781,13 @@ static struct trace_event trace_special_event = {
/* TRACE_STACK */
-static int
-trace_stack_print(struct trace_seq *s, struct trace_entry *entry, int flags)
+static int trace_stack_print(struct trace_iterator *iter, int flags)
{
struct stack_entry *field;
+ struct trace_seq *s = &iter->seq;
int i;
- trace_assign_type(field, entry);
+ trace_assign_type(field, iter->ent);
for (i = 0; i < FTRACE_STACK_ENTRIES; i++) {
if (i) {
@@ -723,13 +817,12 @@ static struct trace_event trace_stack_event = {
};
/* TRACE_USER_STACK */
-static int
-trace_user_stack_print(struct trace_seq *s, struct trace_entry *entry,
- int flags)
+static int trace_user_stack_print(struct trace_iterator *iter, int flags)
{
struct userstack_entry *field;
+ struct trace_seq *s = &iter->seq;
- trace_assign_type(field, entry);
+ trace_assign_type(field, iter->ent);
if (!seq_print_userip_objs(field, s, flags))
goto partial;
@@ -753,12 +846,12 @@ static struct trace_event trace_user_stack_event = {
};
/* TRACE_PRINT */
-static int
-trace_print_print(struct trace_seq *s, struct trace_entry *entry, int flags)
+static int trace_print_print(struct trace_iterator *iter, int flags)
{
struct print_entry *field;
+ struct trace_seq *s = &iter->seq;
- trace_assign_type(field, entry);
+ trace_assign_type(field, iter->ent);
if (!seq_print_ip_sym(s, field->ip, flags))
goto partial;
@@ -772,14 +865,13 @@ trace_print_print(struct trace_seq *s, struct trace_entry *entry, int flags)
return TRACE_TYPE_PARTIAL_LINE;
}
-static int
-trace_print_raw(struct trace_seq *s, struct trace_entry *entry, int flags)
+static int trace_print_raw(struct trace_iterator *iter, int flags)
{
struct print_entry *field;
- trace_assign_type(field, entry);
+ trace_assign_type(field, iter->ent);
- if (!trace_seq_printf(s, "# %lx %s", field->ip, field->buf))
+ if (!trace_seq_printf(&iter->seq, "# %lx %s", field->ip, field->buf))
goto partial;
return 0;