From 8a5131183a2b353cb475ea5826623fe59013a5ac Mon Sep 17 00:00:00 2001 From: Vitaly Fertman Date: Wed, 16 Dec 2020 11:54:10 -0500 Subject: [PATCH] LU-11518 ldlm: cancel LRU improvement Add @batch parameter to cancel LRU, which means if at least 1 lock is cancelled, try to cancel at least a batch locks. This functionality will be used in later patches. Limit the LRU cancel by 1 thread only, however, not for those which have the @max limit given (ELC), as LRU may be left not cleaned up in full. Lustre-change: https://review.whamcloud.com/39561 Lustre-commit: 3d4b5dacb3053f39d79d59860a903a19e76b9318 Signed-off-by: Vitaly Fertman Change-Id: Ide21c4a2b2209b8a721249466ea1e651c8532c8a HPE-bug-id: LUS-8678 Reviewed-on: https://es-gerrit.dev.cray.com/157067 Reviewed-by: Andriy Skulysh Reviewed-by: Alexey Lyashkov Tested-by: Alexander Lezhoev Tested-by: jenkins Tested-by: Maloo Reviewed-by: Andreas Dilger Reviewed-by: Gu Zheng Reviewed-by: Oleg Drokin Reviewed-on: https://review.whamcloud.com/41007 Reviewed-by: Alexey Lyashkov --- lustre/include/lustre_dlm.h | 13 +++++++++++++ lustre/ldlm/ldlm_request.c | 31 ++++++++++++++++++++++++++++--- lustre/ldlm/ldlm_resource.c | 1 + 3 files changed, 42 insertions(+), 3 deletions(-) diff --git a/lustre/include/lustre_dlm.h b/lustre/include/lustre_dlm.h index f47a8ac..c6291b6 100644 --- a/lustre/include/lustre_dlm.h +++ b/lustre/include/lustre_dlm.h @@ -351,6 +351,14 @@ enum ldlm_ns_type { LDLM_NS_TYPE_MGT, /**< MGT namespace */ }; +enum ldlm_namespace_flags { + /** + * Flag to indicate the LRU cancel is in progress. + * Used to limit the process by 1 thread only. + */ + LDLM_LRU_CANCEL = 0 +}; + /** * LDLM Namespace. * @@ -531,6 +539,11 @@ struct ldlm_namespace { struct kobject ns_kobj; /* sysfs object */ struct completion ns_kobj_unregister; + + /** + * To avoid another ns_lock usage, a separate bitops field. + */ + unsigned long ns_flags; }; /** diff --git a/lustre/ldlm/ldlm_request.c b/lustre/ldlm/ldlm_request.c index a761407..ef7c7ba 100644 --- a/lustre/ldlm/ldlm_request.c +++ b/lustre/ldlm/ldlm_request.c @@ -1661,6 +1661,7 @@ ldlm_cancel_lru_policy(struct ldlm_namespace *ns, enum ldlm_lru_flags lru_flags) * redundant unused locks are canceled locally; * - also cancel locally unused aged locks; * - do not cancel more than \a max locks; + * - if some locks are cancelled, try to cancel at least \a batch locks * - GET the found locks and add them into the \a cancels list. * * A client lock can be added to the l_bl_ast list only when it is @@ -1685,7 +1686,8 @@ ldlm_cancel_lru_policy(struct ldlm_namespace *ns, enum ldlm_lru_flags lru_flags) * discard those pages. */ static int ldlm_prepare_lru_list(struct ldlm_namespace *ns, - struct list_head *cancels, int min, int max, + struct list_head *cancels, + int min, int max, int batch, enum ldlm_lru_flags lru_flags) { ldlm_cancel_lru_policy_t pf; @@ -1694,11 +1696,27 @@ static int ldlm_prepare_lru_list(struct ldlm_namespace *ns, ENTRY; + /* + * Let only 1 thread to proceed. However, not for those which have the + * @max limit given (ELC), as LRU may be left not cleaned up in full. + */ + if (max == 0) { + if (test_and_set_bit(LDLM_LRU_CANCEL, &ns->ns_flags)) + RETURN(0); + } else if (test_bit(LDLM_LRU_CANCEL, &ns->ns_flags)) + RETURN(0); + LASSERT(ergo(max, min <= max)); + /* No sense to give @batch for ELC */ + LASSERT(ergo(max, batch == 0)); if (!ns_connect_lru_resize(ns)) min = max_t(int, min, ns->ns_nr_unused - ns->ns_max_unused); + /* If at least 1 lock is to be cancelled, cancel at least @batch locks */ + if (min && min < batch) + min = batch; + pf = ldlm_cancel_lru_policy(ns, lru_flags); LASSERT(pf != NULL); @@ -1819,7 +1837,14 @@ static int ldlm_prepare_lru_list(struct ldlm_namespace *ns, unlock_res_and_lock(lock); lu_ref_del(&lock->l_reference, __FUNCTION__, current); added++; + /* Once a lock added, batch the requested amount */ + if (min == 0) + min = batch; } + + if (max == 0) + clear_bit(LDLM_LRU_CANCEL, &ns->ns_flags); + RETURN(added); } @@ -1830,7 +1855,7 @@ int ldlm_cancel_lru_local(struct ldlm_namespace *ns, struct list_head *cancels, { int added; - added = ldlm_prepare_lru_list(ns, cancels, min, max, lru_flags); + added = ldlm_prepare_lru_list(ns, cancels, min, max, 0, lru_flags); if (added <= 0) return added; @@ -1855,7 +1880,7 @@ int ldlm_cancel_lru(struct ldlm_namespace *ns, int min, /* Just prepare the list of locks, do not actually cancel them yet. * Locks are cancelled later in a separate thread. */ - count = ldlm_prepare_lru_list(ns, &cancels, min, 0, lru_flags); + count = ldlm_prepare_lru_list(ns, &cancels, min, 0, 0, lru_flags); rc = ldlm_bl_to_thread_list(ns, NULL, &cancels, count, cancel_flags); if (rc == 0) RETURN(count); diff --git a/lustre/ldlm/ldlm_resource.c b/lustre/ldlm/ldlm_resource.c index eb99ce6..835790f 100644 --- a/lustre/ldlm/ldlm_resource.c +++ b/lustre/ldlm/ldlm_resource.c @@ -988,6 +988,7 @@ struct ldlm_namespace *ldlm_namespace_new(struct obd_device *obd, char *name, ns->ns_stopping = 0; ns->ns_reclaim_start = 0; ns->ns_last_pos = &ns->ns_unused_list; + ns->ns_flags = 0; rc = ldlm_namespace_sysfs_register(ns); if (rc) { -- 1.8.3.1