From 52b4a5cc0ed4ef2a5981366a931e1e1c1fdcbb4f Mon Sep 17 00:00:00 2001
From: yangsheng <yangsheng>
Date: Fri, 13 Feb 2009 16:14:59 +0000
Subject: [PATCH] Branch HEAD b=16759

i=shadow, zhen.liang

Use RCU lock to enable stack dump when tasklist_lock unexport.
---
 libcfs/autoconf/lustre-libcfs.m4 | 19 +++++++++++++++++++
 libcfs/libcfs/watchdog.c         | 23 +++++++++++++----------
 2 files changed, 32 insertions(+), 10 deletions(-)

diff --git a/libcfs/autoconf/lustre-libcfs.m4 b/libcfs/autoconf/lustre-libcfs.m4
index e536a79ed1..492b0e73ec 100644
--- a/libcfs/autoconf/lustre-libcfs.m4
+++ b/libcfs/autoconf/lustre-libcfs.m4
@@ -241,6 +241,24 @@ CFLAGS="$tmp_flags"
 ])
 
 
+# check if task_struct with rcu memeber
+AC_DEFUN([LIBCFS_TASK_RCU],
+[AC_MSG_CHECKING([if task_struct has a rcu field])
+LB_LINUX_TRY_COMPILE([
+	#include <linux/sched.h>
+],[
+        struct task_struct tsk;
+
+        tsk.rcu.next = NULL;
+],[
+        AC_MSG_RESULT([yes])
+        AC_DEFINE(HAVE_TASK_RCU, 1,
+                  [task_struct has rcu field])
+],[
+        AC_MSG_RESULT([no])
+])
+])
+
 # LIBCFS_TASKLIST_LOCK
 # 2.6.18 remove tasklist_lock export
 AC_DEFUN([LIBCFS_TASKLIST_LOCK],
@@ -434,6 +452,7 @@ LIBCFS_FUNC_SHOW_TASK
 LIBCFS_U64_LONG_LONG
 LIBCFS_SSIZE_T_LONG
 LIBCFS_SIZE_T_LONG
+LIBCFS_TASK_RCU
 # 2.6.18
 LIBCFS_TASKLIST_LOCK
 # 2.6.19
diff --git a/libcfs/libcfs/watchdog.c b/libcfs/libcfs/watchdog.c
index 47098317da..4e5cc421cd 100644
--- a/libcfs/libcfs/watchdog.c
+++ b/libcfs/libcfs/watchdog.c
@@ -101,14 +101,20 @@ static cfs_time_t lcw_last_watchdog_time;
 static int lcw_recent_watchdog_count;
 static spinlock_t lcw_last_watchdog_lock = SPIN_LOCK_UNLOCKED;
 
-#ifdef HAVE_TASKLIST_LOCK
 static void
 lcw_dump(struct lc_watchdog *lcw)
 {
         cfs_task_t *tsk;
+#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;
+#endif
         ENTRY;
 
-        read_lock(&tasklist_lock);
         tsk = find_task_by_pid(lcw->lcw_pid);
 
         if (tsk == NULL) {
@@ -120,17 +126,14 @@ lcw_dump(struct lc_watchdog *lcw)
         } else {
                 libcfs_debug_dumpstack(tsk);
         }
-        
+
+#if defined(HAVE_TASKLIST_LOCK)
         read_unlock(&tasklist_lock);
+#elif defined(HAVE_TASK_RCU)
+        rcu_read_unlock();
+#endif
         EXIT;
 }
-#else
-static void
-lcw_dump(struct lc_watchdog *lcw)
-{
-        CERROR("unable to dump stack because of missing export\n");
-}
-#endif
 
 static void lcw_cb(ulong_ptr_t data)
 {
-- 
GitLab