Whamcloud - gitweb
Branch b1_6
authoryangsheng <yangsheng>
Fri, 20 Mar 2009 08:16:29 +0000 (08:16 +0000)
committeryangsheng <yangsheng>
Fri, 20 Mar 2009 08:16:29 +0000 (08:16 +0000)
b=11505

i=yangsheng, shadow

Change the watchdog for 2.6.27 kernel.

lnet/autoconf/lustre-lnet.m4
lnet/libcfs/linux/linux-debug.c
lnet/libcfs/watchdog.c

index 5f75b3f..2ba0af8 100644 (file)
@@ -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
 ])
 
 #
index b5d4da3..4735e0f 100644 (file)
@@ -206,6 +206,48 @@ void lbug_with_loc(const char *file, const char *func, const int line)
 
 #ifdef __KERNEL__
 
+#ifdef HAVE_DUMP_TRACE
+#include <linux/nmi.h>
+#include <asm/stacktrace.h>
+
+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();
index 2c0e718..9d9df75 100644 (file)
@@ -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)