From ac5abd46e95edd97316ff0e9563288636e7c42bc Mon Sep 17 00:00:00 2001 From: Vitaly Fertman Date: Thu, 2 Apr 2015 20:35:32 +0300 Subject: [PATCH] LU-6390 ldlm: restore the ELC for enqueue after LU-4300 enqueue does not ELC anymore, however if enqueue is agressive (ls -la of a large dir) we may exceed lru-resize limit quickly because LRUR shrinker and recalc are called not so often. ELC is to be restored in enqueue. ELC also should check for the lock weight, in addition to LRUR. ELC can also keep "skipped" locks, i.e. once checked for the weight and left in the lru - let LRUR take care about them later. LRUR is to be left untouched, no weight logic, otherwise LU-5727 appears and OPEN locks do not get canceled. Xyratex-bug-id: MRP-2550 Signed-off-by: Vitaly Fertman Change-Id: I19fb7c367d9d38107a4fb6d100a47c2e7b7ad640 Reviewed-on: http://review.whamcloud.com/14342 Reviewed-by: Jinshan Xiong Tested-by: Jenkins Reviewed-by: Niu Yawei Tested-by: Maloo Reviewed-by: Andreas Dilger Reviewed-by: Oleg Drokin --- lustre/ldlm/ldlm_internal.h | 11 ++++++----- lustre/ldlm/ldlm_request.c | 29 +++++++++++++++++++++++------ lustre/osc/osc_request.c | 4 ++-- 3 files changed, 31 insertions(+), 13 deletions(-) diff --git a/lustre/ldlm/ldlm_internal.h b/lustre/ldlm/ldlm_internal.h index c5eef19..e0e4e66 100644 --- a/lustre/ldlm/ldlm_internal.h +++ b/lustre/ldlm/ldlm_internal.h @@ -98,12 +98,13 @@ struct ldlm_namespace *ldlm_namespace_first_locked(ldlm_side_t); /* ldlm_request.c */ /* Cancel lru flag, it indicates we cancel aged locks. */ enum { - LDLM_CANCEL_AGED = 1 << 0, /* Cancel aged locks (non lru resize). */ - LDLM_CANCEL_PASSED = 1 << 1, /* Cancel passed number of locks. */ - LDLM_CANCEL_SHRINK = 1 << 2, /* Cancel locks from shrinker. */ - LDLM_CANCEL_LRUR = 1 << 3, /* Cancel locks from lru resize. */ - LDLM_CANCEL_NO_WAIT = 1 << 4 /* Cancel locks w/o blocking (neither + LDLM_CANCEL_AGED = 1 << 0, /* Cancel aged locks (non lru resize). */ + LDLM_CANCEL_PASSED = 1 << 1, /* Cancel passed number of locks. */ + LDLM_CANCEL_SHRINK = 1 << 2, /* Cancel locks from shrinker. */ + LDLM_CANCEL_LRUR = 1 << 3, /* Cancel locks from lru resize. */ + LDLM_CANCEL_NO_WAIT = 1 << 4,/* Cancel locks w/o blocking (neither * sending nor waiting for any rpcs) */ + LDLM_CANCEL_LRUR_NO_WAIT = 1 << 5, /* LRUR + NO_WAIT */ }; int ldlm_cancel_lru(struct ldlm_namespace *ns, int nr, diff --git a/lustre/ldlm/ldlm_request.c b/lustre/ldlm/ldlm_request.c index 1a5d7dd..833078a 100644 --- a/lustre/ldlm/ldlm_request.c +++ b/lustre/ldlm/ldlm_request.c @@ -782,10 +782,10 @@ int ldlm_prep_elc_req(struct obd_export *exp, struct ptlrpc_request *req, req_capsule_filled_sizes(pill, RCL_CLIENT); avail = ldlm_capsule_handles_avail(pill, RCL_CLIENT, canceloff); - flags = ns_connect_lru_resize(ns) ? - LDLM_CANCEL_LRUR : LDLM_CANCEL_AGED; - to_free = !ns_connect_lru_resize(ns) && - opc == LDLM_ENQUEUE ? 1 : 0; + flags = ns_connect_lru_resize(ns) ? + LDLM_CANCEL_LRUR_NO_WAIT : LDLM_CANCEL_AGED; + to_free = !ns_connect_lru_resize(ns) && + opc == LDLM_ENQUEUE ? 1 : 0; /* Cancel LRU locks here _only_ if the server supports * EARLY_CANCEL. Otherwise we have to send extra CANCEL @@ -1503,6 +1503,21 @@ static ldlm_policy_res_t ldlm_cancel_lrur_policy(struct ldlm_namespace *ns, return LDLM_POLICY_CANCEL_LOCK; } +static ldlm_policy_res_t +ldlm_cancel_lrur_no_wait_policy(struct ldlm_namespace *ns, + struct ldlm_lock *lock, + int unused, int added, + int count) +{ + ldlm_policy_res_t result; + + result = ldlm_cancel_lrur_policy(ns, lock, unused, added, count); + if (result == LDLM_POLICY_KEEP_LOCK) + return result; + + return ldlm_cancel_no_wait_policy(ns, lock, unused, added, count); +} + /** * Callback function for proc used policy. Makes decision whether to keep * \a lock in LRU for current \a LRU size \a unused, added in current scan \a @@ -1583,6 +1598,8 @@ ldlm_cancel_lru_policy(struct ldlm_namespace *ns, int flags) return ldlm_cancel_lrur_policy; else if (flags & LDLM_CANCEL_PASSED) return ldlm_cancel_passed_policy; + else if (flags & LDLM_CANCEL_LRUR_NO_WAIT) + return ldlm_cancel_lrur_no_wait_policy; } else { if (flags & LDLM_CANCEL_AGED) return ldlm_cancel_aged_policy; @@ -1631,6 +1648,7 @@ static int ldlm_prepare_lru_list(struct ldlm_namespace *ns, ldlm_cancel_lru_policy_t pf; struct ldlm_lock *lock, *next; int added = 0, unused, remained; + int no_wait = flags & (LDLM_CANCEL_NO_WAIT | LDLM_CANCEL_LRUR_NO_WAIT); ENTRY; spin_lock(&ns->ns_lock); @@ -1660,8 +1678,7 @@ static int ldlm_prepare_lru_list(struct ldlm_namespace *ns, /* No locks which got blocking requests. */ LASSERT(!ldlm_is_bl_ast(lock)); - if (flags & LDLM_CANCEL_NO_WAIT && - ldlm_is_skipped(lock)) + if (no_wait && ldlm_is_skipped(lock)) /* already processed */ continue; diff --git a/lustre/osc/osc_request.c b/lustre/osc/osc_request.c index a7b5dc5..009280b 100644 --- a/lustre/osc/osc_request.c +++ b/lustre/osc/osc_request.c @@ -2043,8 +2043,8 @@ no_match: if (req == NULL) RETURN(-ENOMEM); - rc = ptlrpc_request_pack(req, LUSTRE_DLM_VERSION, LDLM_ENQUEUE); - if (rc < 0) { + rc = ldlm_prep_enqueue_req(exp, req, NULL, 0); + if (rc) { ptlrpc_request_free(req); RETURN(rc); } -- 1.8.3.1