From 30d302a2bcbac13b6ba2d97d5e6deb96caf4c792 Mon Sep 17 00:00:00 2001 From: yangsheng Date: Fri, 20 Mar 2009 08:16:29 +0000 Subject: [PATCH] Branch b1_6 b=11505 i=yangsheng, shadow Change the watchdog for 2.6.27 kernel. --- lnet/autoconf/lustre-lnet.m4 | 14 ++++++++++++ lnet/libcfs/linux/linux-debug.c | 50 +++++++++++++++++++++++++++++++++++++++++ lnet/libcfs/watchdog.c | 19 ++++++---------- 3 files changed, 71 insertions(+), 12 deletions(-) diff --git a/lnet/autoconf/lustre-lnet.m4 b/lnet/autoconf/lustre-lnet.m4 index 5f75b3f..2ba0af8 100644 --- a/lnet/autoconf/lustre-lnet.m4 +++ b/lnet/autoconf/lustre-lnet.m4 @@ -1380,6 +1380,19 @@ LB_LINUX_TRY_COMPILE([ ]) ]) +# +# LN_FUNC_DUMP_TRACE +# +# 2.6.27 exports dump_trace() so we can dump_stack() on any task +# +AC_DEFUN([LN_FUNC_DUMP_TRACE], +[LB_CHECK_SYMBOL_EXPORT([dump_trace], +[kernel/ksyms.c arch/${LINUX_ARCH%_64}/kernel/traps_64.c],[ + AC_DEFINE(HAVE_DUMP_TRACE, 1, [dump_trace is exported]) +],[ +]) +]) + # 2.6.27 have second argument to sock_map_fd AC_DEFUN([LN_SOCK_MAP_FD_2ARG], [AC_MSG_CHECKING([sock_map_fd have second argument]) @@ -1447,6 +1460,7 @@ LN_SCATTERLIST_SETPAGE LN_SEM_COUNT # 2.6.27 LN_SOCK_MAP_FD_2ARG +LN_FUNC_DUMP_TRACE ]) # diff --git a/lnet/libcfs/linux/linux-debug.c b/lnet/libcfs/linux/linux-debug.c index b5d4da3..4735e0f 100644 --- a/lnet/libcfs/linux/linux-debug.c +++ b/lnet/libcfs/linux/linux-debug.c @@ -206,6 +206,48 @@ void lbug_with_loc(const char *file, const char *func, const int line) #ifdef __KERNEL__ +#ifdef HAVE_DUMP_TRACE +#include +#include + +static void +print_trace_warning_symbol(void *data, char *msg, unsigned long symbol) +{ + printk(data); + print_symbol(msg, symbol); + printk("\n"); +} + +static void print_trace_warning(void *data, char *msg) +{ + printk("%s%s\n", (char *)data, msg); +} + +static int print_trace_stack(void *data, char *name) +{ + printk(" <%s> ", name); + return 0; +} + +void printk_address(unsigned long address, int reliable) +{ + printk(" [<%016lx>] %s%pS\n", address, reliable ? "": "? ", (void *) address); +} + +static void print_trace_address(void *data, unsigned long addr, int reliable) +{ + touch_nmi_watchdog(); + printk_address(addr, reliable); +} + +static const struct stacktrace_ops print_trace_ops = { + .warning = print_trace_warning, + .warning_symbol = print_trace_warning_symbol, + .stack = print_trace_stack, + .address = print_trace_address, +}; +#endif + void libcfs_debug_dumpstack(struct task_struct *tsk) { #if defined(__arch_um__) @@ -221,6 +263,14 @@ void libcfs_debug_dumpstack(struct task_struct *tsk) tsk = current; CWARN("showing stack for process %d\n", tsk->pid); show_task(tsk); +#elif defined(HAVE_DUMP_TRACE) + /* dump_stack() */ + /* show_trace() */ + printk("Pid: %d, comm: %.20s\n", current->pid, current->comm); + /* show_trace_log_lvl() */ + printk("\nCall Trace:\n"); + dump_trace(tsk, NULL, NULL, 0, &print_trace_ops, ""); + printk("\n"); #else if ((tsk == NULL) || (tsk == current)) dump_stack(); diff --git a/lnet/libcfs/watchdog.c b/lnet/libcfs/watchdog.c index 2c0e718..9d9df75 100644 --- a/lnet/libcfs/watchdog.c +++ b/lnet/libcfs/watchdog.c @@ -105,27 +105,22 @@ static spinlock_t lcw_last_watchdog_lock = SPIN_LOCK_UNLOCKED; static void lcw_dump(struct lc_watchdog *lcw) { - cfs_task_t *tsk; + ENTRY; + #if defined(HAVE_TASKLIST_LOCK) read_lock(&tasklist_lock); #elif defined(HAVE_TASK_RCU) rcu_read_lock(); #else CERROR("unable to dump stack because of missing export\n"); - return; + RETURN_EXIT; #endif - ENTRY; - - tsk = find_task_by_pid(lcw->lcw_pid); - - if (tsk == NULL) { + if (lcw->lcw_task == NULL) { CWARN("Process %d was not found in the task list; " - "watchdog callback may be incomplete\n", (int)lcw->lcw_pid); - } else if (tsk != lcw->lcw_task) { - CWARN("The current process %d did not set the watchdog; " - "watchdog callback may be incomplete\n", (int)lcw->lcw_pid); + "watchdog callback may be incomplete\n", + (int)lcw->lcw_pid); } else { - libcfs_debug_dumpstack(tsk); + libcfs_debug_dumpstack(lcw->lcw_task); } #if defined(HAVE_TASKLIST_LOCK) -- 1.8.3.1