--- include/linux/ipipe_trace.h | 3 - kernel/ipipe/tracer.c | 129 ++++++++++++++++++++++++++++++++++---------- 2 files changed, 102 insertions(+), 30 deletions(-) Index: linux-2.6.16.16/include/linux/ipipe_trace.h =================================================================== --- linux-2.6.16.16.orig/include/linux/ipipe_trace.h +++ linux-2.6.16.16/include/linux/ipipe_trace.h @@ -2,7 +2,7 @@ * include/linux/ipipe_trace.h * * Copyright (C) 2005 Luotao Fu. - * 2005 Jan Kiszka. + * 2005, 2006 Jan Kiszka. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -27,6 +27,7 @@ void ipipe_trace_begin(unsigned long v); void ipipe_trace_end(unsigned long v); void ipipe_trace_freeze(unsigned long v); void ipipe_trace_special(unsigned char special_id, unsigned long v); +void ipipe_trace_pid(pid_t pid, short prio); int ipipe_trace_max_reset(void); int ipipe_trace_frozen_reset(void); Index: linux-2.6.16.16/kernel/ipipe/tracer.c =================================================================== --- linux-2.6.16.16.orig/kernel/ipipe/tracer.c +++ linux-2.6.16.16/kernel/ipipe/tracer.c @@ -79,13 +79,17 @@ struct ipipe_trace_path{ enum ipipe_trace_type { - IPIPE_TRACE_FN = 0, + IPIPE_TRACE_FUNC = 0, IPIPE_TRACE_BEGIN, IPIPE_TRACE_END, IPIPE_TRACE_FREEZE, IPIPE_TRACE_SPECIAL, + IPIPE_TRACE_PID, }; +#define IPIPE_TYPE_MASK 0x0007 +#define IPIPE_TYPE_BITS 3 + #ifdef CONFIG_IPIPE_TRACE_VMALLOC #define IPIPE_DEFAULT_TRACE_STATE 0 @@ -471,11 +475,22 @@ void notrace ipipe_trace_special(unsigne { if (!ipipe_trace_enable) return; - __ipipe_trace(IPIPE_TRACE_SPECIAL + id, __BUILTIN_RETURN_ADDRESS0, + __ipipe_trace(IPIPE_TRACE_SPECIAL | (id << IPIPE_TYPE_BITS), + __BUILTIN_RETURN_ADDRESS0, __BUILTIN_RETURN_ADDRESS1, v); } EXPORT_SYMBOL(ipipe_trace_special); +void notrace ipipe_trace_pid(pid_t pid, short prio) +{ + if (!ipipe_trace_enable) + return; + __ipipe_trace(IPIPE_TRACE_PID | (prio << IPIPE_TYPE_BITS), + __BUILTIN_RETURN_ADDRESS0, + __BUILTIN_RETURN_ADDRESS1, pid); +} +EXPORT_SYMBOL(ipipe_trace_pid); + int ipipe_trace_max_reset(void) { int cpu_id; @@ -550,10 +565,43 @@ void ipipe_trace_panic_freeze(void) } EXPORT_SYMBOL(ipipe_trace_panic_freeze); +static void +__ipipe_get_task_info(char *task_info, struct ipipe_trace_point *point, + int trylock) +{ + struct task_struct *task = NULL; + char buf[8]; + int i; + int locked = 1; + + if (trylock && !read_trylock(&tasklist_lock)) + locked = 0; + else + read_lock(&tasklist_lock); + + if (locked) + task = find_task_by_pid((pid_t)point->v); + + if (task) + strncpy(task_info, task->comm, 11); + else + strcpy(task_info, "--"); + + if (locked) + read_unlock(&tasklist_lock); + + for (i = strlen(task_info); i < 11; i++) + task_info[i] = ' '; + + sprintf(buf, " %d ", point->type >> IPIPE_TYPE_BITS); + strcpy(task_info + (11 - strlen(buf)), buf); +} + void ipipe_trace_panic_dump(void) { int cnt = back_trace; int start, pos; + char task_info[11]; printk("I-pipe tracer log (%d points):\n", cnt); @@ -570,10 +618,20 @@ void ipipe_trace_panic_dump(void) __ipipe_trace_point_type(buf, point); printk(buf); - if (point->type != IPIPE_TRACE_FN) - printk("0x%08lx ", point->v); - else - printk(" "); + switch (point->type & IPIPE_TYPE_MASK) { + case IPIPE_TRACE_FUNC: + printk(" "); + break; + + case IPIPE_TRACE_PID: + __ipipe_get_task_info(task_info, + point, 1); + printk(task_info); + break; + + default: + printk("0x%08lx ", point->v); + } time = __ipipe_signed_tsc2us(point->timestamp - panic_path->point[start].timestamp); @@ -618,26 +676,31 @@ static long __ipipe_signed_tsc2us(long l static void __ipipe_trace_point_type(char *buf, struct ipipe_trace_point *point) { - switch (point->type) { - case IPIPE_TRACE_FN: - strcpy(buf, "fn "); + switch (point->type & IPIPE_TYPE_MASK) { + case IPIPE_TRACE_FUNC: + strcpy(buf, "func "); break; case IPIPE_TRACE_BEGIN: - strcpy(buf, "begin "); + strcpy(buf, "begin "); break; case IPIPE_TRACE_END: - strcpy(buf, "end "); + strcpy(buf, "end "); break; case IPIPE_TRACE_FREEZE: - strcpy(buf, "freeze "); + strcpy(buf, "freeze "); + break; + + case IPIPE_TRACE_SPECIAL: + sprintf(buf, "(0x%02x) ", + point->type >> IPIPE_TYPE_BITS); break; - default: /* IPIPE_TRACE_SPECIAL */ - sprintf(buf, "(0x%02x) ", - point->type - IPIPE_TRACE_SPECIAL); + case IPIPE_TRACE_PID: + sprintf(buf, "[%5d] ", (pid_t)point->v); + break; } } @@ -765,23 +828,23 @@ static void __ipipe_print_headline(struc " ||+--- %s\n" " |||+-- %s\n" " ||||+- %s%s\n" - " ||||| +---------- " + " ||||| +---------- " "Delay flag ('+': > %d us, '!': > %d us)\n" - " ||||| | +- " + " ||||| | +- " "NMI noise ('N')\n" - " ||||| | |\n" - " Type User Val. Time Delay Function " + " ||||| | |\n" + " Type User Val. Time Delay Function " "(Parent)\n", name[3], name[2], name[1], name[0], name[0] ? " ('*': domain stalled)" : "", IPIPE_DELAY_NOTE/1000, IPIPE_DELAY_WARN/1000); } else seq_printf(m, - " +-------------- Hard IRQs ('|': locked)\n" - " | +- Delay flag " + " +--------------- Hard IRQs ('|': locked)\n" + " | +- Delay flag " "('+': > %d us, '!': > %d us)\n" - " | |\n" - " Type Time Function (Parent)\n", + " | |\n" + " Type Time Function (Parent)\n", IPIPE_DELAY_NOTE/1000, IPIPE_DELAY_WARN/1000); } @@ -888,12 +951,20 @@ static int __ipipe_prtrace_show(struct s __ipipe_print_pathmark(m, point); __ipipe_trace_point_type(buf, point); seq_puts(m, buf); - if (verbose_trace) { - if (point->type != IPIPE_TRACE_FN) - seq_printf(m, "0x%08lx ", point->v); - else - seq_puts(m, " "); - } + if (verbose_trace) + switch (point->type & IPIPE_TYPE_MASK) { + case IPIPE_TRACE_FUNC: + seq_puts(m, " "); + break; + + case IPIPE_TRACE_PID: + __ipipe_get_task_info(buf, point, 0); + seq_puts(m, buf); + break; + + default: + seq_printf(m, "0x%08lx ", point->v); + } time = __ipipe_signed_tsc2us(point->timestamp - print_path->point[print_path->begin].timestamp);