From bfae5a4e4a37e4057200bcc70dbff14e18a00797 Mon Sep 17 00:00:00 2001 From: Jinshan Xiong Date: Thu, 6 Feb 2014 23:03:25 -0800 Subject: [PATCH] LU-4300 ldlm: ELC picks locks in a safer policy Change the policy of ELC to pick locks that have no dirty pages, no page in writeback state, and no locked pages. Signed-off-by: Jinshan Xiong Change-Id: Ie73130c4100e3b91c211635f6a72fe5dad994426 Reviewed-on: http://review.whamcloud.com/9175 Tested-by: Jenkins Reviewed-by: Andreas Dilger Tested-by: Maloo Reviewed-by: Bobi Jam Reviewed-by: Oleg Drokin --- lustre/include/lustre_dlm.h | 15 ++++++++------ lustre/ldlm/ldlm_request.c | 49 +++++++++++++++++++++++++++------------------ lustre/mdc/mdc_request.c | 20 +++++++++--------- lustre/osc/osc_lock.c | 6 +++++- lustre/osc/osc_request.c | 24 +++++++++------------- 5 files changed, 63 insertions(+), 51 deletions(-) diff --git a/lustre/include/lustre_dlm.h b/lustre/include/lustre_dlm.h index 22d32f4..bd3e589 100644 --- a/lustre/include/lustre_dlm.h +++ b/lustre/include/lustre_dlm.h @@ -279,7 +279,7 @@ typedef int (*ldlm_res_policy)(struct ldlm_namespace *, struct ldlm_lock **, void *req_cookie, ldlm_mode_t mode, __u64 flags, void *data); -typedef int (*ldlm_cancel_for_recovery)(struct ldlm_lock *lock); +typedef int (*ldlm_cancel_cbt)(struct ldlm_lock *lock); /** * LVB operations. @@ -500,8 +500,11 @@ struct ldlm_namespace { /** Limit of parallel AST RPC count. */ unsigned ns_max_parallel_ast; - /** Callback to cancel locks before replaying it during recovery. */ - ldlm_cancel_for_recovery ns_cancel_for_recovery; + /** + * Callback to check if a lock is good to be canceled by ELC or + * during recovery. + */ + ldlm_cancel_cbt ns_cancel; /** LDLM lock stats */ struct lprocfs_stats *ns_stats; @@ -558,10 +561,10 @@ static inline int ns_connect_lru_resize(struct ldlm_namespace *ns) } static inline void ns_register_cancel(struct ldlm_namespace *ns, - ldlm_cancel_for_recovery arg) + ldlm_cancel_cbt arg) { - LASSERT(ns != NULL); - ns->ns_cancel_for_recovery = arg; + LASSERT(ns != NULL); + ns->ns_cancel = arg; } struct ldlm_lock; diff --git a/lustre/ldlm/ldlm_request.c b/lustre/ldlm/ldlm_request.c index a90d452..59723ae 100644 --- a/lustre/ldlm/ldlm_request.c +++ b/lustre/ldlm/ldlm_request.c @@ -1449,7 +1449,6 @@ static ldlm_policy_res_t ldlm_cancel_no_wait_policy(struct ldlm_namespace *ns, int count) { ldlm_policy_res_t result = LDLM_POLICY_CANCEL_LOCK; - ldlm_cancel_for_recovery cb = ns->ns_cancel_for_recovery; /* don't check added & count since we want to process all locks * from unused list. @@ -1458,7 +1457,7 @@ static ldlm_policy_res_t ldlm_cancel_no_wait_policy(struct ldlm_namespace *ns, switch (lock->l_resource->lr_type) { case LDLM_EXTENT: case LDLM_IBITS: - if (cb && cb(lock)) + if (ns->ns_cancel != NULL && ns->ns_cancel(lock) != 0) break; default: result = LDLM_POLICY_SKIP_LOCK; @@ -1485,20 +1484,20 @@ static ldlm_policy_res_t ldlm_cancel_lrur_policy(struct ldlm_namespace *ns, int unused, int added, int count) { - cfs_time_t cur = cfs_time_current(); - struct ldlm_pool *pl = &ns->ns_pool; - __u64 slv, lvf, lv; - cfs_time_t la; + cfs_time_t cur = cfs_time_current(); + struct ldlm_pool *pl = &ns->ns_pool; + __u64 slv, lvf, lv; + cfs_time_t la; /* Stop LRU processing when we reach past @count or have checked all * locks in LRU. */ - if (count && added >= count) - return LDLM_POLICY_KEEP_LOCK; + if (count && added >= count) + return LDLM_POLICY_KEEP_LOCK; - slv = ldlm_pool_get_slv(pl); - lvf = ldlm_pool_get_lvf(pl); - la = cfs_duration_sec(cfs_time_sub(cur, - lock->l_last_used)); + slv = ldlm_pool_get_slv(pl); + lvf = ldlm_pool_get_lvf(pl); + la = cfs_duration_sec(cfs_time_sub(cur, + lock->l_last_used)); lv = lvf * la * unused; /* Inform pool about current CLV to see it via proc. */ @@ -1506,8 +1505,13 @@ static ldlm_policy_res_t ldlm_cancel_lrur_policy(struct ldlm_namespace *ns, /* Stop when SLV is not yet come from server or lv is smaller than * it is. */ - return (slv == 0 || lv < slv) ? - LDLM_POLICY_KEEP_LOCK : LDLM_POLICY_CANCEL_LOCK; + if (slv == 0 || lv < slv) + return LDLM_POLICY_KEEP_LOCK; + + if (ns->ns_cancel != NULL && ns->ns_cancel(lock) == 0) + return LDLM_POLICY_KEEP_LOCK; + + return LDLM_POLICY_CANCEL_LOCK; } /** @@ -1544,12 +1548,17 @@ static ldlm_policy_res_t ldlm_cancel_aged_policy(struct ldlm_namespace *ns, int unused, int added, int count) { - /* Stop LRU processing if young lock is found and we reach past count */ - return ((added >= count) && - cfs_time_before(cfs_time_current(), - cfs_time_add(lock->l_last_used, - ns->ns_max_age))) ? - LDLM_POLICY_KEEP_LOCK : LDLM_POLICY_CANCEL_LOCK; + if (added >= count) + return LDLM_POLICY_KEEP_LOCK; + + if (cfs_time_before(cfs_time_current(), + cfs_time_add(lock->l_last_used, ns->ns_max_age))) + return LDLM_POLICY_KEEP_LOCK; + + if (ns->ns_cancel != NULL && ns->ns_cancel(lock) == 0) + return LDLM_POLICY_KEEP_LOCK; + + return LDLM_POLICY_CANCEL_LOCK; } /** diff --git a/lustre/mdc/mdc_request.c b/lustre/mdc/mdc_request.c index 77c76c6..85fd541 100644 --- a/lustre/mdc/mdc_request.c +++ b/lustre/mdc/mdc_request.c @@ -3050,18 +3050,18 @@ struct obd_uuid *mdc_get_uuid(struct obd_export *exp) { * recovery, non zero value will be return if the lock can be canceled, * or zero returned for not */ -static int mdc_cancel_for_recovery(struct ldlm_lock *lock) +static int mdc_cancel_weight(struct ldlm_lock *lock) { - if (lock->l_resource->lr_type != LDLM_IBITS) - RETURN(0); + if (lock->l_resource->lr_type != LDLM_IBITS) + RETURN(0); - /* FIXME: if we ever get into a situation where there are too many - * opened files with open locks on a single node, then we really - * should replay these open locks to reget it */ - if (lock->l_policy_data.l_inodebits.bits & MDS_INODELOCK_OPEN) - RETURN(0); + /* FIXME: if we ever get into a situation where there are too many + * opened files with open locks on a single node, then we really + * should replay these open locks to reget it */ + if (lock->l_policy_data.l_inodebits.bits & MDS_INODELOCK_OPEN) + RETURN(0); - RETURN(1); + RETURN(1); } static int mdc_resource_inode_free(struct ldlm_resource *res) @@ -3107,7 +3107,7 @@ static int mdc_setup(struct obd_device *obd, struct lustre_cfg *cfg) sptlrpc_lprocfs_cliobd_attach(obd); ptlrpc_lprocfs_register_obd(obd); - ns_register_cancel(obd->obd_namespace, mdc_cancel_for_recovery); + ns_register_cancel(obd->obd_namespace, mdc_cancel_weight); obd->obd_namespace->ns_lvbo = &inode_lvbo; diff --git a/lustre/osc/osc_lock.c b/lustre/osc/osc_lock.c index 749b970..3422d54 100644 --- a/lustre/osc/osc_lock.c +++ b/lustre/osc/osc_lock.c @@ -908,7 +908,11 @@ static int weigh_cb(const struct lu_env *env, struct cl_io *io, { struct cl_page *page = ops->ops_cl.cpl_page; - if (cl_page_is_vmlocked(env, page)) { + if (cl_page_is_vmlocked(env, page) +#if defined(__KERNEL__) + || PageDirty(page->cp_vmpage) || PageWriteback(page->cp_vmpage) +#endif + ) { (*(unsigned long *)cbdata)++; return CLP_GANG_ABORT; } diff --git a/lustre/osc/osc_request.c b/lustre/osc/osc_request.c index 0884aaf..ed8b962 100644 --- a/lustre/osc/osc_request.c +++ b/lustre/osc/osc_request.c @@ -2620,14 +2620,13 @@ int osc_enqueue_base(struct obd_export *exp, struct ldlm_res_id *res_id, no_match: if (intent) { - CFS_LIST_HEAD(cancels); - req = ptlrpc_request_alloc(class_exp2cliimp(exp), - &RQF_LDLM_ENQUEUE_LVB); - if (req == NULL) - RETURN(-ENOMEM); + req = ptlrpc_request_alloc(class_exp2cliimp(exp), + &RQF_LDLM_ENQUEUE_LVB); + if (req == NULL) + RETURN(-ENOMEM); - rc = ldlm_prep_enqueue_req(exp, req, &cancels, 0); - if (rc) { + rc = ptlrpc_request_pack(req, LUSTRE_DLM_VERSION, LDLM_ENQUEUE); + if (rc < 0) { ptlrpc_request_free(req); RETURN(rc); } @@ -3493,16 +3492,13 @@ static int osc_import_event(struct obd_device *obd, * \retval zero the lock can't be canceled * \retval other ok to cancel */ -static int osc_cancel_for_recovery(struct ldlm_lock *lock) +static int osc_cancel_weight(struct ldlm_lock *lock) { /* - * Cancel all unused extent lock in granted mode LCK_PR or LCK_CR. - * - * XXX as a future improvement, we can also cancel unused write lock - * if it doesn't have dirty data and active mmaps. + * Cancel all unused and granted extent lock. */ if (lock->l_resource->lr_type == LDLM_EXTENT && - (lock->l_granted_mode == LCK_PR || lock->l_granted_mode == LCK_CR)&& + lock->l_granted_mode == lock->l_req_mode && osc_ldlm_weigh_ast(lock) == 0) RETURN(1); @@ -3569,7 +3565,7 @@ int osc_setup(struct obd_device *obd, struct lustre_cfg *lcfg) ptlrpc_add_rqs_to_pool); CFS_INIT_LIST_HEAD(&cli->cl_grant_shrink_list); - ns_register_cancel(obd->obd_namespace, osc_cancel_for_recovery); + ns_register_cancel(obd->obd_namespace, osc_cancel_weight); RETURN(rc); out_ptlrpcd_work: -- 1.8.3.1