From: Andriy Skulysh <[email protected]>

Deadlock isn't detected if 2 threads are trying to
grant 2 locks which deadlock on each other.
They call ldlm_flock_deadlock() simultaneously
and deadlock ins't detected.

The soulition is to add lock to blocking list before
calling ldlm_flock_deadlock()

Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-1602
Lustre-change: http://review.whamcloud.com/3277
Signed-off-by: Andriy Skulysh <[email protected]>
Reviewed-by: Vitaly Fertman <[email protected]>
Reviewed-by: Bruce Korb <[email protected]>
Reviewed-by: Keith Mannthey <[email protected]>
Reviewed-by: Oleg Drokin <[email protected]>
Signed-off-by: Peng Tao <[email protected]>
Signed-off-by: Andreas Dilger <[email protected]>
---
 drivers/staging/lustre/lustre/ldlm/ldlm_flock.c |   16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/drivers/staging/lustre/lustre/ldlm/ldlm_flock.c 
b/drivers/staging/lustre/lustre/ldlm/ldlm_flock.c
index aca1073..39973cb 100644
--- a/drivers/staging/lustre/lustre/ldlm/ldlm_flock.c
+++ b/drivers/staging/lustre/lustre/ldlm/ldlm_flock.c
@@ -198,6 +198,7 @@ ldlm_flock_deadlock(struct ldlm_lock *req, struct ldlm_lock 
*bl_lock)
                if (lock == NULL)
                        break;
 
+               LASSERT(req != lock);
                flock = &lock->l_policy_data.l_flock;
                LASSERT(flock->owner == bl_owner);
                bl_owner = flock->blocking_owner;
@@ -329,18 +330,21 @@ reprocess:
                                RETURN(LDLM_ITER_STOP);
                        }
 
-                       if (ldlm_flock_deadlock(req, lock)) {
-                               ldlm_flock_destroy(req, mode, *flags);
-                               *err = -EDEADLK;
-                               RETURN(LDLM_ITER_STOP);
-                       }
-
+                       /* add lock to blocking list before deadlock
+                        * check to prevent race */
                        rc = ldlm_flock_blocking_link(req, lock);
                        if (rc) {
                                ldlm_flock_destroy(req, mode, *flags);
                                *err = rc;
                                RETURN(LDLM_ITER_STOP);
                        }
+                       if (ldlm_flock_deadlock(req, lock)) {
+                               ldlm_flock_blocking_unlink(req);
+                               ldlm_flock_destroy(req, mode, *flags);
+                               *err = -EDEADLK;
+                               RETURN(LDLM_ITER_STOP);
+                       }
+
                        ldlm_resource_add_lock(res, &res->lr_waiting, req);
                        *flags |= LDLM_FL_BLOCK_GRANTED;
                        RETURN(LDLM_ITER_STOP);
-- 
1.7.9.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to