Whamcloud - gitweb
b=2322
authorphil <phil>
Wed, 3 Dec 2003 10:58:26 +0000 (10:58 +0000)
committerphil <phil>
Wed, 3 Dec 2003 10:58:26 +0000 (10:58 +0000)
In ldlm_process_{plain,extent}_lock, we used to remove and re-add the
lock to the waiting list after every -ERESTART loop.  But because of
the logic in the ldlm_*_compat_queue functions, in a very rare case,
this could lead to lock re-ordering and subsequent deadlock.

lustre/ChangeLog
lustre/ldlm/ldlm_extent.c
lustre/ldlm/ldlm_plain.c

index 0126cbe..95d6dd9 100644 (file)
@@ -16,6 +16,7 @@ tbd         Cluster File Systems, Inc. <info@clusterfs.com>
        - x86-64 compile warning fixes
        - fix gateway LMC keyword conflict (2318)
        - fix MDS lock inversions in getattr/reint paths (1844)
+       - fix a rare lock re-ordering bug, which caused deadlock (2322)
        * miscellania
        - allow configurable automake binary, for testing new versions
        - small update to the lfs documentation
index 8e62496..246ed17 100644 (file)
@@ -190,9 +190,13 @@ int ldlm_process_extent_lock(struct ldlm_lock *lock, int *flags, int first_enq,
 
         if (rc != 2) {
                 /* If either of the compat_queue()s returned 0, then we
-                 * have ASTs to send and must go onto the waiting list. */
-                ldlm_resource_unlink_lock(lock);
-                ldlm_resource_add_lock(res, &res->lr_waiting, lock);
+                 * have ASTs to send and must go onto the waiting list.
+                 *
+                 * bug 2322: we used to unlink and re-add here, which was a
+                 * terrible folly -- if we goto restart, we could get
+                 * re-ordered!  Causes deadlock, because ASTs aren't sent! */
+                if (list_empty(&lock->l_res_link))
+                        ldlm_resource_add_lock(res, &res->lr_waiting, lock);
                 l_unlock(&res->lr_namespace->ns_lock);
                 rc = ldlm_run_ast_work(res->lr_namespace, &rpc_list);
                 l_lock(&res->lr_namespace->ns_lock);
index a9d7702..9b2af34 100644 (file)
@@ -105,9 +105,13 @@ int ldlm_process_plain_lock(struct ldlm_lock *lock, int *flags, int first_enq,
 
         if (rc != 2) {
                 /* If either of the compat_queue()s returned 0, then we
-                 * have ASTs to send and must go onto the waiting list. */
-                ldlm_resource_unlink_lock(lock);
-                ldlm_resource_add_lock(res, &res->lr_waiting, lock);
+                 * have ASTs to send and must go onto the waiting list.
+                 *
+                 * bug 2322: we used to unlink and re-add here, which was a
+                 * terrible folly -- if we goto restart, we could get
+                 * re-ordered!  Causes deadlock, because ASTs aren't sent! */
+                if (list_empty(&lock->l_res_link))
+                        ldlm_resource_add_lock(res, &res->lr_waiting, lock);
                 l_unlock(&res->lr_namespace->ns_lock);
                 rc = ldlm_run_ast_work(res->lr_namespace, &rpc_list);
                 l_lock(&res->lr_namespace->ns_lock);