Skip to content

Commit

Permalink
trace: fix task state printout
Browse files Browse the repository at this point in the history
Impact: fix occasionally incorrect trace output

The tracing code has interesting varieties of printing out task state.

Unfortunalely only one of the instances is correct as it copies the
code from sched.c:sched_show_task(). The others are plain wrong as
they treatthe bitfield as an integer offset into the character
array. Also the size check of the character array is wrong as it
includes the trailing \0.

Use a common state decoder inline which does the Right Thing.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
  • Loading branch information
Thomas Gleixner authored and Ingo Molnar committed Dec 18, 2008
1 parent 55dac3a commit 3d9101e
Showing 1 changed file with 17 additions and 22 deletions.
39 changes: 17 additions & 22 deletions kernel/trace/trace.c
Original file line number Diff line number Diff line change
Expand Up @@ -1301,6 +1301,13 @@ lat_print_timestamp(struct trace_seq *s, u64 abs_usecs,

static const char state_to_char[] = TASK_STATE_TO_CHAR_STR;

static int task_state_char(unsigned long state)
{
int bit = state ? __ffs(state) + 1 : 0;

return bit < sizeof(state_to_char) - 1 ? state_to_char[bit] : '?';
}

/*
* The message is supposed to contain an ending newline.
* If the printing stops prematurely, try to add a newline of our own.
Expand Down Expand Up @@ -1396,12 +1403,8 @@ print_lat_fmt(struct trace_iterator *iter, unsigned int trace_idx, int cpu)

trace_assign_type(field, entry);

T = field->next_state < sizeof(state_to_char) ?
state_to_char[field->next_state] : 'X';

state = field->prev_state ?
__ffs(field->prev_state) + 1 : 0;
S = state < sizeof(state_to_char) - 1 ? state_to_char[state] : 'X';
T = task_state_char(field->next_state);
S = task_state_char(field->prev_state);
comm = trace_find_cmdline(field->next_pid);
trace_seq_printf(s, " %5d:%3d:%c %s [%03d] %5d:%3d:%c %s\n",
field->prev_pid,
Expand Down Expand Up @@ -1519,10 +1522,8 @@ static enum print_line_t print_trace_fmt(struct trace_iterator *iter)

trace_assign_type(field, entry);

S = field->prev_state < sizeof(state_to_char) ?
state_to_char[field->prev_state] : 'X';
T = field->next_state < sizeof(state_to_char) ?
state_to_char[field->next_state] : 'X';
T = task_state_char(field->next_state);
S = task_state_char(field->prev_state);
ret = trace_seq_printf(s, " %5d:%3d:%c %s [%03d] %5d:%3d:%c\n",
field->prev_pid,
field->prev_prio,
Expand Down Expand Up @@ -1621,12 +1622,9 @@ static enum print_line_t print_raw_fmt(struct trace_iterator *iter)

trace_assign_type(field, entry);

S = field->prev_state < sizeof(state_to_char) ?
state_to_char[field->prev_state] : 'X';
T = field->next_state < sizeof(state_to_char) ?
state_to_char[field->next_state] : 'X';
if (entry->type == TRACE_WAKE)
S = '+';
T = task_state_char(field->next_state);
S = entry->type == TRACE_WAKE ? '+' :
task_state_char(field->prev_state);
ret = trace_seq_printf(s, "%d %d %c %d %d %d %c\n",
field->prev_pid,
field->prev_prio,
Expand Down Expand Up @@ -1712,12 +1710,9 @@ static enum print_line_t print_hex_fmt(struct trace_iterator *iter)

trace_assign_type(field, entry);

S = field->prev_state < sizeof(state_to_char) ?
state_to_char[field->prev_state] : 'X';
T = field->next_state < sizeof(state_to_char) ?
state_to_char[field->next_state] : 'X';
if (entry->type == TRACE_WAKE)
S = '+';
T = task_state_char(field->next_state);
S = entry->type == TRACE_WAKE ? '+' :
task_state_char(field->prev_state);
SEQ_PUT_HEX_FIELD_RET(s, field->prev_pid);
SEQ_PUT_HEX_FIELD_RET(s, field->prev_prio);
SEQ_PUT_HEX_FIELD_RET(s, S);
Expand Down

0 comments on commit 3d9101e

Please sign in to comment.