From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754237AbYLSVj1 (ORCPT ); Fri, 19 Dec 2008 16:39:27 -0500 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1753708AbYLSVit (ORCPT ); Fri, 19 Dec 2008 16:38:49 -0500 Received: from www.tglx.de ([62.245.132.106]:55761 "EHLO www.tglx.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753622AbYLSVir (ORCPT ); Fri, 19 Dec 2008 16:38:47 -0500 Message-Id: <20081219211945.404968770@linutronix.de> References: <20081219211656.875192771@linutronix.de> User-Agent: quilt/0.46-1 Date: Fri, 19 Dec 2008 21:22:44 -0000 From: Thomas Gleixner To: LKML Cc: Ingo Molnar , Steven Rostedt , Peter Zijlstra , Clark Williams , Gregory Haskins , Linux-rt Subject: [patch 1/7] ftrace: fix task state printout Content-Disposition: inline; filename=ftrace-fix-task-state-printout.patch Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Impact: tracer task state decoding is wrong, size check is buggy 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 --- kernel/trace/trace.c | 40 ++++++++++++++++++---------------------- 1 file changed, 18 insertions(+), 22 deletions(-) Index: linux-2.6.24/kernel/trace/trace.c =================================================================== --- linux-2.6.24.orig/kernel/trace/trace.c +++ linux-2.6.24/kernel/trace/trace.c @@ -1626,6 +1626,13 @@ lat_print_timestamp(struct trace_seq *s, 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] : '?'; +} + extern unsigned long sys_call_table[NR_syscalls]; #if defined(CONFIG_COMPAT) && defined(CONFIG_X86) @@ -1654,7 +1661,6 @@ print_lat_fmt(struct trace_iterator *ite char *comm; int S, T; int i; - unsigned state; if (!next_entry) next_entry = entry; @@ -1685,11 +1691,8 @@ print_lat_fmt(struct trace_iterator *ite break; case TRACE_CTX: case TRACE_WAKE: - T = entry->ctx.next_state < sizeof(state_to_char) ? - state_to_char[entry->ctx.next_state] : 'X'; - - state = entry->ctx.prev_state ? __ffs(entry->ctx.prev_state) + 1 : 0; - S = state < sizeof(state_to_char) - 1 ? state_to_char[state] : 'X'; + T = task_state_char(entry->ctx.next_state); + S = task_state_char(entry->ctx.prev_state); comm = trace_find_cmdline(entry->ctx.next_pid); trace_seq_printf(s, " %5d:%3d:%c %s %5d:%3d:%c %s\n", entry->ctx.prev_pid, @@ -1862,10 +1865,8 @@ static int print_trace_fmt(struct trace_ break; case TRACE_CTX: case TRACE_WAKE: - S = entry->ctx.prev_state < sizeof(state_to_char) ? - state_to_char[entry->ctx.prev_state] : 'X'; - T = entry->ctx.next_state < sizeof(state_to_char) ? - state_to_char[entry->ctx.next_state] : 'X'; + T = task_state_char(entry->ctx.next_state); + S = task_state_char(entry->ctx.prev_state); ret = trace_seq_printf(s, " %5d:%3d:%c %s %5d:%3d:%c\n", entry->ctx.prev_pid, entry->ctx.prev_prio, @@ -2012,12 +2013,10 @@ static int print_raw_fmt(struct trace_it break; case TRACE_CTX: case TRACE_WAKE: - S = entry->ctx.prev_state < sizeof(state_to_char) ? - state_to_char[entry->ctx.prev_state] : 'X'; - T = entry->ctx.next_state < sizeof(state_to_char) ? - state_to_char[entry->ctx.next_state] : 'X'; - if (entry->type == TRACE_WAKE) - S = '+'; + T = task_state_char(entry->ctx.next_state); + S = entry->type == TRACE_WAKE ? '+' : + task_state_char(entry->ctx.prev_state); + ret = trace_seq_printf(s, "%d %d %c %d %d %c\n", entry->ctx.prev_pid, entry->ctx.prev_prio, @@ -2073,12 +2072,9 @@ static int print_hex_fmt(struct trace_it break; case TRACE_CTX: case TRACE_WAKE: - S = entry->ctx.prev_state < sizeof(state_to_char) ? - state_to_char[entry->ctx.prev_state] : 'X'; - T = entry->ctx.next_state < sizeof(state_to_char) ? - state_to_char[entry->ctx.next_state] : 'X'; - if (entry->type == TRACE_WAKE) - S = '+'; + T = task_state_char(entry->ctx.next_state); + S = entry->type == TRACE_WAKE ? '+' : + task_state_char(entry->ctx.prev_state); SEQ_PUT_HEX_FIELD_RET(s, entry->ctx.prev_pid); SEQ_PUT_HEX_FIELD_RET(s, entry->ctx.prev_prio); SEQ_PUT_HEX_FIELD_RET(s, S); --