Whamcloud - gitweb
LU-2332 osc: solve a race in client obd list lock
authorJinshan Xiong <jinshan.xiong@intel.com>
Thu, 15 Nov 2012 05:07:02 +0000 (21:07 -0800)
committerOleg Drokin <green@whamcloud.com>
Wed, 9 Jan 2013 00:38:20 +0000 (19:38 -0500)
In __client_obd_list_lock(), the lock may have been released before
printing the debug information.

Also, avoid calling osc_wake_cache_waiters() recrusively in
__osc_unreserve_grant().

Signed-off-by: Jinshan Xiong <jinshan.xiong@intel.com>
Change-Id: I4ada1f02feb56b7b25f2f87384551cee7265679e
Reviewed-on: http://review.whamcloud.com/4587
Reviewed-by: Prakash Surya <surya1@llnl.gov>
Reviewed-by: Andreas Dilger <andreas.dilger@intel.com>
Tested-by: Hudson
Tested-by: Maloo <whamcloud.maloo@gmail.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/include/linux/obd.h
lustre/osc/osc_cache.c

index cdec497..0be9fa1 100644 (file)
@@ -57,7 +57,10 @@ struct ll_iattr {
        unsigned int    ia_attr_flags;
 };
 
        unsigned int    ia_attr_flags;
 };
 
+#ifdef __KERNEL__
 #define CLIENT_OBD_LIST_LOCK_DEBUG 1
 #define CLIENT_OBD_LIST_LOCK_DEBUG 1
+#endif
+
 typedef struct {
        spinlock_t              lock;
 
 typedef struct {
        spinlock_t              lock;
 
@@ -71,8 +74,7 @@ typedef struct {
 
 #ifdef CLIENT_OBD_LIST_LOCK_DEBUG
 static inline void __client_obd_list_lock(client_obd_lock_t *lock,
 
 #ifdef CLIENT_OBD_LIST_LOCK_DEBUG
 static inline void __client_obd_list_lock(client_obd_lock_t *lock,
-                                          const char *func,
-                                          int line)
+                                          const char *func, int line)
 {
        unsigned long cur = jiffies;
        while (1) {
 {
        unsigned long cur = jiffies;
        while (1) {
@@ -87,20 +89,26 @@ static inline void __client_obd_list_lock(client_obd_lock_t *lock,
 
                 if ((jiffies - cur > 5 * CFS_HZ) &&
                     (jiffies - lock->time > 5 * CFS_HZ)) {
 
                 if ((jiffies - cur > 5 * CFS_HZ) &&
                     (jiffies - lock->time > 5 * CFS_HZ)) {
-                        LCONSOLE_WARN("LOCK UP! the lock %p was acquired"
-                                      " by <%s:%d:%s:%d> %lu time, I'm %s:%d\n",
-                                      lock, lock->task->comm, lock->task->pid,
+                       struct task_struct *task = lock->task;
+
+                       if (task == NULL)
+                               continue;
+
+                        LCONSOLE_WARN("%s:%d: lock %p was acquired"
+                                      " by <%s:%d:%s:%d> for %lu seconds.\n",
+                                     current->comm, current->pid,
+                                      lock, task->comm, task->pid,
                                       lock->func, lock->line,
                                       lock->func, lock->line,
-                                      (jiffies - lock->time),
-                                      current->comm, current->pid);
+                                      (jiffies - lock->time) / CFS_HZ);
                         LCONSOLE_WARN("====== for process holding the "
                                       "lock =====\n");
                         LCONSOLE_WARN("====== for process holding the "
                                       "lock =====\n");
-                        libcfs_debug_dumpstack(lock->task);
+                        libcfs_debug_dumpstack(task);
                         LCONSOLE_WARN("====== for current process =====\n");
                         libcfs_debug_dumpstack(NULL);
                         LCONSOLE_WARN("====== end =======\n");
                         cfs_pause(1000 * CFS_HZ);
                 }
                         LCONSOLE_WARN("====== for current process =====\n");
                         libcfs_debug_dumpstack(NULL);
                         LCONSOLE_WARN("====== end =======\n");
                         cfs_pause(1000 * CFS_HZ);
                 }
+               cpu_relax();
         }
 }
 
         }
 }
 
index 35da55c..469de7f 100644 (file)
@@ -1393,8 +1393,6 @@ static void __osc_unreserve_grant(struct client_obd *cli,
        } else {
                cli->cl_avail_grant += unused;
        }
        } else {
                cli->cl_avail_grant += unused;
        }
-       if (unused > 0)
-               osc_wake_cache_waiters(cli);
 }
 
 void osc_unreserve_grant(struct client_obd *cli,
 }
 
 void osc_unreserve_grant(struct client_obd *cli,
@@ -1402,6 +1400,8 @@ void osc_unreserve_grant(struct client_obd *cli,
 {
        client_obd_list_lock(&cli->cl_loi_list_lock);
        __osc_unreserve_grant(cli, reserved, unused);
 {
        client_obd_list_lock(&cli->cl_loi_list_lock);
        __osc_unreserve_grant(cli, reserved, unused);
+       if (unused > 0)
+               osc_wake_cache_waiters(cli);
        client_obd_list_unlock(&cli->cl_loi_list_lock);
 }
 
        client_obd_list_unlock(&cli->cl_loi_list_lock);
 }