Whamcloud - gitweb
b=16774 fix a issue caused by LDLM_POLICY_SKIP_LOCK
authorHongchao.Zhang@Sun.COM <Hongchao.Zhang@Sun.COM>
Wed, 16 Dec 2009 08:09:14 +0000 (16:09 +0800)
committerjohann <johann@granier.local>
Thu, 17 Dec 2009 12:37:06 +0000 (13:37 +0100)
introduce a new lock flag LDLM_FL_SKIPPED to avoid
checking locks repeatly in ldlm_cancel_lru_local()

i=oleg.drokin@sun.com
i=hongchao.zhang@sun.com

lustre/include/lustre_dlm.h
lustre/ldlm/ldlm_lock.c
lustre/ldlm/ldlm_request.c

index 1e661dd..9d0e35e 100644 (file)
@@ -195,6 +195,10 @@ typedef enum {
  * emulation + race with upcoming bl_ast.  */
 #define LDLM_FL_FAIL_LOC       0x100000000ULL
 
+/* Used while processing the unused list to know that we have already
+ * handled this lock and decided to skip it */
+#define LDLM_FL_SKIPPED        0x200000000ULL
+
 /* The blocking callback is overloaded to perform two functions.  These flags
  * indicate which operation should be performed. */
 #define LDLM_CB_BLOCKING    1
index 91ca903..bcd7566 100644 (file)
@@ -184,6 +184,8 @@ int ldlm_lock_remove_from_lru_nolock(struct ldlm_lock *lock)
                 struct ldlm_namespace *ns = lock->l_resource->lr_namespace;
                 LASSERT(lock->l_resource->lr_type != LDLM_FLOCK);
                 list_del_init(&lock->l_lru);
+                if (lock->l_flags & LDLM_FL_SKIPPED)
+                        lock->l_flags &= ~LDLM_FL_SKIPPED;
                 LASSERT(ns->ns_nr_unused > 0);
                 ns->ns_nr_unused--;
                 rc = 1;
index b3126df..81cb983 100644 (file)
@@ -1197,6 +1197,7 @@ static ldlm_policy_res_t ldlm_cancel_no_wait_policy(struct ldlm_namespace *ns,
                                 break;
                 default:
                         result = LDLM_POLICY_SKIP_LOCK;
+                        lock->l_flags |= LDLM_FL_SKIPPED;
                         break;
         }
 
@@ -1368,6 +1369,11 @@ int ldlm_cancel_lru_local(struct ldlm_namespace *ns, struct list_head *cancels,
                         /* No locks which got blocking requests. */
                         LASSERT(!(lock->l_flags & LDLM_FL_BL_AST));
 
+                        if (flags & LDLM_CANCEL_NO_WAIT &&
+                            lock->l_flags & LDLM_FL_SKIPPED)
+                                /* already processed */
+                                continue;
+
                         /* Somebody is already doing CANCEL. No need in this
                          * lock in lru, do not traverse it again. */
                         if (!(lock->l_flags & LDLM_FL_CANCELING))