From: Jinshan Xiong Date: Thu, 15 Nov 2012 05:07:02 +0000 (-0800) Subject: LU-2332 osc: solve a race in client obd list lock X-Git-Tag: 2.3.59~39 X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=commitdiff_plain;h=b74eb1a08d2a1cc1ee1b5b8aec268c05f8e7ac22;ds=sidebyside LU-2332 osc: solve a race in client obd list lock 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 Change-Id: I4ada1f02feb56b7b25f2f87384551cee7265679e Reviewed-on: http://review.whamcloud.com/4587 Reviewed-by: Prakash Surya Reviewed-by: Andreas Dilger Tested-by: Hudson Tested-by: Maloo Reviewed-by: Oleg Drokin --- diff --git a/lustre/include/linux/obd.h b/lustre/include/linux/obd.h index cdec497..0be9fa1 100644 --- a/lustre/include/linux/obd.h +++ b/lustre/include/linux/obd.h @@ -57,7 +57,10 @@ struct ll_iattr { unsigned int ia_attr_flags; }; +#ifdef __KERNEL__ #define CLIENT_OBD_LIST_LOCK_DEBUG 1 +#endif + 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, - const char *func, - int line) + const char *func, int line) { 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)) { - 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, - (jiffies - lock->time), - current->comm, current->pid); + (jiffies - lock->time) / CFS_HZ); 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); } + cpu_relax(); } } diff --git a/lustre/osc/osc_cache.c b/lustre/osc/osc_cache.c index 35da55c..469de7f 100644 --- a/lustre/osc/osc_cache.c +++ b/lustre/osc/osc_cache.c @@ -1393,8 +1393,6 @@ static void __osc_unreserve_grant(struct client_obd *cli, } else { cli->cl_avail_grant += unused; } - if (unused > 0) - osc_wake_cache_waiters(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); + if (unused > 0) + osc_wake_cache_waiters(cli); client_obd_list_unlock(&cli->cl_loi_list_lock); }