From 168670f180b7f00c7d17afebad8c6ac1040f346d Mon Sep 17 00:00:00 2001 From: "Hongchao.Zhang@Sun.COM" Date: Wed, 16 Dec 2009 16:09:14 +0800 Subject: [PATCH] b=16774 fix a issue caused by LDLM_POLICY_SKIP_LOCK 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 | 4 ++++ lustre/ldlm/ldlm_lock.c | 2 ++ lustre/ldlm/ldlm_request.c | 6 ++++++ 3 files changed, 12 insertions(+) diff --git a/lustre/include/lustre_dlm.h b/lustre/include/lustre_dlm.h index 1e661dd..9d0e35e 100644 --- a/lustre/include/lustre_dlm.h +++ b/lustre/include/lustre_dlm.h @@ -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 diff --git a/lustre/ldlm/ldlm_lock.c b/lustre/ldlm/ldlm_lock.c index 91ca903..bcd7566 100644 --- a/lustre/ldlm/ldlm_lock.c +++ b/lustre/ldlm/ldlm_lock.c @@ -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; diff --git a/lustre/ldlm/ldlm_request.c b/lustre/ldlm/ldlm_request.c index b3126df..81cb983 100644 --- a/lustre/ldlm/ldlm_request.c +++ b/lustre/ldlm/ldlm_request.c @@ -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)) -- 1.8.3.1