X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=blobdiff_plain;f=lustre%2Fldlm%2Fldlm_lockd.c;h=03ca051b95314d45066d97d316cfcced2ab28ad9;hp=de04b6d5a91dc2305bd16496882052f672042deb;hb=05e6ccd344e7eba44e43230fa2fa0a1b3b6115c4;hpb=45a64335d0e326a411fe6a68cce77e618924f59f diff --git a/lustre/ldlm/ldlm_lockd.c b/lustre/ldlm/ldlm_lockd.c index de04b6d..03ca051 100644 --- a/lustre/ldlm/ldlm_lockd.c +++ b/lustre/ldlm/ldlm_lockd.c @@ -27,7 +27,6 @@ */ /* * This file is part of Lustre, http://www.lustre.org/ - * Lustre is a trademark of Sun Microsystems, Inc. * * lustre/ldlm/ldlm_lockd.c * @@ -40,6 +39,7 @@ #include #include #include +#include #include #include #include @@ -72,12 +72,12 @@ static struct ldlm_state *ldlm_state; /* * timeout for initial callback (AST) reply (bz10399) * Due to having to send a 32 bit time value over the - * wire return it as time_t instead of time64_t + * wire return it as timeout_t instead of time64_t */ -static inline time_t ldlm_get_rq_timeout(void) +static inline timeout_t ldlm_get_rq_timeout(void) { /* Non-AT value */ - time_t timeout = min(ldlm_timeout, obd_timeout / 3); + timeout_t timeout = min(ldlm_timeout, obd_timeout / 3); return timeout < 1 ? 1 : timeout; } @@ -152,8 +152,8 @@ static int expired_lock_dump; static LIST_HEAD(expired_lock_list); static int ldlm_lock_busy(struct ldlm_lock *lock); -static int ldlm_add_waiting_lock(struct ldlm_lock *lock, time64_t timeout); -static int __ldlm_add_waiting_lock(struct ldlm_lock *lock, time64_t seconds); +static int ldlm_add_waiting_lock(struct ldlm_lock *lock, timeout_t timeout); +static int __ldlm_add_waiting_lock(struct ldlm_lock *lock, timeout_t timeout); static inline int have_expired_locks(void) { @@ -240,7 +240,7 @@ static int expired_lock_main(void *arg) /* Check if we need to prolong timeout */ if (!OBD_FAIL_CHECK(OBD_FAIL_PTLRPC_HPREQ_TIMEOUT) && - lock->l_callback_timeout != 0 && /* not AST error */ + lock->l_callback_timestamp != 0 && /* not AST error */ ldlm_lock_busy(lock)) { LDLM_DEBUG(lock, "prolong the busy lock"); lock_res_and_lock(lock); @@ -254,11 +254,12 @@ static int expired_lock_main(void *arg) LDLM_ERROR(lock, "lock callback timer expired after %llds: evicting client at %s ", - ktime_get_real_seconds() - + ktime_get_seconds() - lock->l_blast_sent, obd_export_nid2str(export)); ldlm_lock_to_ns(lock)->ns_timeouts++; - do_dump++; + if (do_dump_on_eviction(export->exp_obd)) + do_dump++; class_fail_export(export); } class_export_lock_put(export, lock); @@ -272,7 +273,7 @@ static int expired_lock_main(void *arg) } spin_unlock_bh(&waiting_locks_spinlock); - if (do_dump && obd_dump_on_eviction) { + if (do_dump) { CERROR("dump the log upon eviction\n"); libcfs_debug_dumplog(); } @@ -323,7 +324,7 @@ static void waiting_locks_callback(TIMER_DATA_TYPE unused) while (!list_empty(&waiting_locks_list)) { lock = list_entry(waiting_locks_list.next, struct ldlm_lock, l_pending_chain); - if (lock->l_callback_timeout > ktime_get_seconds() || + if (lock->l_callback_timestamp > ktime_get_seconds() || lock->l_req_mode == LCK_GROUP) break; @@ -349,12 +350,12 @@ static void waiting_locks_callback(TIMER_DATA_TYPE unused) */ if (!list_empty(&waiting_locks_list)) { time64_t now = ktime_get_seconds(); - time_t delta = 0; + timeout_t delta = 0; lock = list_entry(waiting_locks_list.next, struct ldlm_lock, l_pending_chain); - if (lock->l_callback_timeout - now > 0) - delta = lock->l_callback_timeout - now; + if (lock->l_callback_timestamp - now > 0) + delta = lock->l_callback_timestamp - now; mod_timer(&waiting_locks_timer, jiffies + cfs_time_seconds(delta)); } @@ -373,26 +374,27 @@ static void waiting_locks_callback(TIMER_DATA_TYPE unused) * * Called with the namespace lock held. */ -static int __ldlm_add_waiting_lock(struct ldlm_lock *lock, time64_t seconds) +static int __ldlm_add_waiting_lock(struct ldlm_lock *lock, timeout_t delay) { unsigned long timeout_jiffies = jiffies; - time64_t now = ktime_get_seconds(); time64_t deadline; - time_t timeout; + timeout_t timeout; + lock->l_blast_sent = ktime_get_seconds(); if (!list_empty(&lock->l_pending_chain)) return 0; if (OBD_FAIL_CHECK(OBD_FAIL_PTLRPC_HPREQ_NOTIMEOUT) || OBD_FAIL_CHECK(OBD_FAIL_PTLRPC_HPREQ_TIMEOUT)) - seconds = 1; + delay = 1; - deadline = now + seconds; - if (likely(deadline > lock->l_callback_timeout)) - lock->l_callback_timeout = deadline; + deadline = lock->l_blast_sent + delay; + if (likely(deadline > lock->l_callback_timestamp)) + lock->l_callback_timestamp = deadline; - timeout = clamp_t(time_t, lock->l_callback_timeout - now, - 0, seconds); + timeout = clamp_t(timeout_t, + lock->l_callback_timestamp - lock->l_blast_sent, + 0, delay); timeout_jiffies += cfs_time_seconds(timeout); if (time_before(timeout_jiffies, waiting_locks_timer.expires) || @@ -432,7 +434,7 @@ static void ldlm_add_blocked_lock(struct ldlm_lock *lock) obd_stale_export_adjust(lock->l_export); } -static int ldlm_add_waiting_lock(struct ldlm_lock *lock, time64_t timeout) +static int ldlm_add_waiting_lock(struct ldlm_lock *lock, timeout_t timeout) { int ret; @@ -467,7 +469,6 @@ static int ldlm_add_waiting_lock(struct ldlm_lock *lock, time64_t timeout) } ldlm_set_waited(lock); - lock->l_blast_sent = ktime_get_real_seconds(); ret = __ldlm_add_waiting_lock(lock, timeout); if (ret) { /* @@ -481,7 +482,7 @@ static int ldlm_add_waiting_lock(struct ldlm_lock *lock, time64_t timeout) if (ret) ldlm_add_blocked_lock(lock); - LDLM_DEBUG(lock, "%sadding to wait list(timeout: %lld, AT: %s)", + LDLM_DEBUG(lock, "%sadding to wait list(timeout: %d, AT: %s)", ret == 0 ? "not re-" : "", timeout, AT_OFF ? "off" : "on"); return ret; @@ -512,12 +513,12 @@ static int __ldlm_del_waiting_lock(struct ldlm_lock *lock) } else { time64_t now = ktime_get_seconds(); struct ldlm_lock *next; - time_t delta = 0; + timeout_t delta = 0; next = list_entry(list_next, struct ldlm_lock, l_pending_chain); - if (next->l_callback_timeout - now > 0) - delta = lock->l_callback_timeout - now; + if (next->l_callback_timestamp - now > 0) + delta = lock->l_callback_timestamp - now; mod_timer(&waiting_locks_timer, jiffies + cfs_time_seconds(delta)); @@ -565,7 +566,7 @@ int ldlm_del_waiting_lock(struct ldlm_lock *lock) * * Called with namespace lock held. */ -int ldlm_refresh_waiting_lock(struct ldlm_lock *lock, time64_t timeout) +int ldlm_refresh_waiting_lock(struct ldlm_lock *lock, timeout_t timeout) { if (lock->l_export == NULL) { /* We don't have a "waiting locks list" on clients. */ @@ -595,7 +596,7 @@ int ldlm_refresh_waiting_lock(struct ldlm_lock *lock, time64_t timeout) __ldlm_add_waiting_lock(lock, timeout); spin_unlock_bh(&waiting_locks_spinlock); - LDLM_DEBUG(lock, "refreshed"); + LDLM_DEBUG(lock, "refreshed to %ds", timeout); return 1; } EXPORT_SYMBOL(ldlm_refresh_waiting_lock); @@ -607,7 +608,7 @@ int ldlm_del_waiting_lock(struct ldlm_lock *lock) RETURN(0); } -int ldlm_refresh_waiting_lock(struct ldlm_lock *lock, time64_t timeout) +int ldlm_refresh_waiting_lock(struct ldlm_lock *lock, timeout_t timeout) { RETURN(0); } @@ -625,9 +626,9 @@ int ldlm_refresh_waiting_lock(struct ldlm_lock *lock, time64_t timeout) * * \retval timeout in seconds to wait for the client reply */ -time64_t ldlm_bl_timeout(struct ldlm_lock *lock) +timeout_t ldlm_bl_timeout(struct ldlm_lock *lock) { - time64_t timeout; + timeout_t timeout; if (AT_OFF) return obd_timeout / 2; @@ -639,7 +640,8 @@ time64_t ldlm_bl_timeout(struct ldlm_lock *lock) * lock callbacks too... */ timeout = at_get(&lock->l_export->exp_bl_lock_at); - return max(timeout + (timeout >> 1), (time64_t)ldlm_enqueue_min); + return max_t(timeout_t, timeout + (timeout >> 1), + (timeout_t)ldlm_enqueue_min); } EXPORT_SYMBOL(ldlm_bl_timeout); @@ -663,7 +665,8 @@ static void ldlm_failed_ast(struct ldlm_lock *lock, int rc, * the lock to the expired list */ LDLM_LOCK_GET(lock); - lock->l_callback_timeout = 0; /* differentiate it from expired locks */ + /* differentiate it from expired locks */ + lock->l_callback_timestamp = 0; list_add(&lock->l_pending_chain, &expired_lock_list); wake_up(&expired_lock_wait_queue); spin_unlock_bh(&waiting_locks_spinlock); @@ -941,6 +944,7 @@ int ldlm_server_blocking_ast(struct ldlm_lock *lock, body = req_capsule_client_get(&req->rq_pill, &RMF_DLM_REQ); body->lock_handle[0] = lock->l_remote_handle; + body->lock_handle[1].cookie = lock->l_handle.h_cookie; body->lock_desc = *desc; body->lock_flags |= ldlm_flags_to_wire(lock->l_flags & LDLM_FL_AST_MASK); @@ -1036,6 +1040,7 @@ int ldlm_server_completion_ast(struct ldlm_lock *lock, __u64 flags, void *data) body = req_capsule_client_get(&req->rq_pill, &RMF_DLM_REQ); body->lock_handle[0] = lock->l_remote_handle; + body->lock_handle[1].cookie = lock->l_handle.h_cookie; body->lock_flags = ldlm_flags_to_wire(flags); ldlm_lock2desc(lock, &body->lock_desc); if (lvb_len > 0) { @@ -1195,7 +1200,7 @@ int ldlm_glimpse_locks(struct ldlm_resource *res, rc = ldlm_run_ast_work(ldlm_res_to_ns(res), gl_work_list, LDLM_WORK_GL_AST); if (rc == -ERESTART) - ldlm_reprocess_all(res, NULL); + ldlm_reprocess_all(res, 0); RETURN(rc); } @@ -1356,11 +1361,14 @@ int ldlm_handle_enqueue0(struct ldlm_namespace *ns, dlm_req->lock_desc.l_resource.lr_type, &dlm_req->lock_desc.l_policy_data, &lock->l_policy_data); - if (dlm_req->lock_desc.l_resource.lr_type == LDLM_EXTENT) + if (dlm_req->lock_desc.l_resource.lr_type == LDLM_EXTENT) { lock->l_req_extent = lock->l_policy_data.l_extent; - else if (dlm_req->lock_desc.l_resource.lr_type == LDLM_IBITS) + } else if (dlm_req->lock_desc.l_resource.lr_type == LDLM_IBITS) { lock->l_policy_data.l_inodebits.try_bits = dlm_req->lock_desc.l_policy_data.l_inodebits.try_bits; + lock->l_policy_data.l_inodebits.li_gid = + dlm_req->lock_desc.l_policy_data.l_inodebits.li_gid; + } existing_lock: cookie = req; @@ -1459,9 +1467,9 @@ existing_lock: out: req->rq_status = rc ?: err; /* return either error - b=11190 */ if (!req->rq_packed_final) { - err = lustre_pack_reply(req, 1, NULL, NULL); + int rc1 = lustre_pack_reply(req, 1, NULL, NULL); if (rc == 0) - rc = err; + rc = rc1; } /* @@ -1539,13 +1547,14 @@ retry: ldlm_resource_unlink_lock(lock); ldlm_lock_destroy_nolock(lock); unlock_res_and_lock(lock); - } + ldlm_reprocess_all(lock->l_resource, lock->l_policy_data.l_inodebits.bits); } if (!err && !ldlm_is_cbpending(lock) && dlm_req->lock_desc.l_resource.lr_type != LDLM_FLOCK) - ldlm_reprocess_all(lock->l_resource, lock); + ldlm_reprocess_all(lock->l_resource, + lock->l_policy_data.l_inodebits.bits); LDLM_LOCK_RELEASE(lock); } @@ -1651,7 +1660,10 @@ int ldlm_handle_convert0(struct ptlrpc_request *req, ldlm_clear_blocking_data(lock); unlock_res_and_lock(lock); - ldlm_reprocess_all(lock->l_resource, NULL); + /* All old bits should be reprocessed to send new BL AST if + * it wasn't sent earlier due to LDLM_FL_AST_SENT bit set. + * */ + ldlm_reprocess_all(lock->l_resource, bits); } dlm_rep->lock_handle = lock->l_remote_handle; @@ -1725,7 +1737,7 @@ int ldlm_request_cancel(struct ptlrpc_request *req, */ if (res != pres) { if (pres != NULL) { - ldlm_reprocess_all(pres, NULL); + ldlm_reprocess_all(pres, 0); LDLM_RESOURCE_DELREF(pres); ldlm_resource_putref(pres); } @@ -1742,18 +1754,21 @@ int ldlm_request_cancel(struct ptlrpc_request *req, if ((flags & LATF_STATS) && ldlm_is_ast_sent(lock) && lock->l_blast_sent != 0) { - time64_t delay = ktime_get_real_seconds() - - lock->l_blast_sent; + timeout_t delay = 0; + + if (ktime_get_seconds() > lock->l_blast_sent) + delay = ktime_get_seconds() - + lock->l_blast_sent; LDLM_DEBUG(lock, - "server cancels blocked lock after %llds", - (s64)delay); + "server cancels blocked lock after %ds", + delay); at_measured(&lock->l_export->exp_bl_lock_at, delay); } ldlm_lock_cancel(lock); LDLM_LOCK_PUT(lock); } if (pres != NULL) { - ldlm_reprocess_all(pres, NULL); + ldlm_reprocess_all(pres, 0); LDLM_RESOURCE_DELREF(pres); ldlm_resource_putref(pres); } @@ -1921,7 +1936,7 @@ static int ldlm_handle_cp_callback(struct ptlrpc_request *req, ldlm_callback_reply(req, 0); while (to > 0) { - schedule_timeout_interruptible(to); + to = schedule_timeout_interruptible(to); if (ldlm_is_granted(lock) || ldlm_is_destroyed(lock)) break; @@ -2077,8 +2092,7 @@ static void ldlm_handle_gl_callback(struct ptlrpc_request *req, if (lock->l_granted_mode == LCK_PW && !lock->l_readers && !lock->l_writers && ktime_after(ktime_get(), - ktime_add(lock->l_last_used, - ktime_set(ns->ns_dirty_age_limit, 0)))) { + ktime_add(lock->l_last_used, ns->ns_dirty_age_limit))) { unlock_res_and_lock(lock); /* For MDS glimpse it is always DOM lock, set corresponding @@ -2138,7 +2152,7 @@ static inline void init_blwi(struct ldlm_bl_work_item *blwi, init_completion(&blwi->blwi_comp); INIT_LIST_HEAD(&blwi->blwi_head); - if (memory_pressure_get()) + if (current->flags & PF_MEMALLOC) blwi->blwi_mem_pressure = 1; blwi->blwi_ns = ns; @@ -2209,6 +2223,11 @@ int ldlm_bl_to_thread_list(struct ldlm_namespace *ns, struct ldlm_lock_desc *ld, return ldlm_bl_to_thread(ns, ld, NULL, cancels, count, cancel_flags); } +int ldlm_bl_to_thread_ns(struct ldlm_namespace *ns) +{ + return ldlm_bl_to_thread(ns, NULL, NULL, NULL, 0, LCF_ASYNC); +} + int ldlm_bl_thread_wakeup(void) { wake_up(&ldlm_state->ldlm_bl_pool->blp_waitq); @@ -2403,6 +2422,8 @@ static int ldlm_callback_handler(struct ptlrpc_request *req) ldlm_lock_remove_from_lru(lock); ldlm_set_bl_ast(lock); } + if (lock->l_remote_handle.cookie == 0) + lock->l_remote_handle = dlm_req->lock_handle[1]; unlock_res_and_lock(lock); /* @@ -2676,15 +2697,18 @@ static int ldlm_revoke_lock_cb(struct cfs_hash *hs, struct cfs_hash_bd *bd, void ldlm_revoke_export_locks(struct obd_export *exp) { + int rc; LIST_HEAD(rpc_list); - ENTRY; cfs_hash_for_each_nolock(exp->exp_lock_hash, ldlm_revoke_lock_cb, &rpc_list, 0); - ldlm_run_ast_work(exp->exp_obd->obd_namespace, &rpc_list, + rc = ldlm_run_ast_work(exp->exp_obd->obd_namespace, &rpc_list, LDLM_WORK_REVOKE_AST); + if (rc == -ERESTART) + ldlm_reprocess_recovery_done(exp->exp_obd->obd_namespace); + EXIT; } EXPORT_SYMBOL(ldlm_revoke_export_locks); @@ -2800,6 +2824,9 @@ static int ldlm_bl_thread_need_create(struct ldlm_bl_pool *blp, static int ldlm_bl_thread_blwi(struct ldlm_bl_pool *blp, struct ldlm_bl_work_item *blwi) { + /* '1' for consistency with code that checks !mpflag to restore */ + unsigned int mpflags = 1; + ENTRY; if (blwi->blwi_ns == NULL) @@ -2807,7 +2834,7 @@ static int ldlm_bl_thread_blwi(struct ldlm_bl_pool *blp, RETURN(LDLM_ITER_STOP); if (blwi->blwi_mem_pressure) - memory_pressure_set(); + mpflags = memalloc_noreclaim_save(); OBD_FAIL_TIMEOUT(OBD_FAIL_LDLM_PAUSE_CANCEL2, 4); @@ -2824,12 +2851,19 @@ static int ldlm_bl_thread_blwi(struct ldlm_bl_pool *blp, LCF_BL_AST); ldlm_cli_cancel_list(&blwi->blwi_head, count, NULL, blwi->blwi_flags); - } else { + } else if (blwi->blwi_lock) { ldlm_handle_bl_callback(blwi->blwi_ns, &blwi->blwi_ld, blwi->blwi_lock); + } else { + ldlm_pool_recalc(&blwi->blwi_ns->ns_pool, true); + spin_lock(&blwi->blwi_ns->ns_lock); + blwi->blwi_ns->ns_rpc_recalc = 0; + spin_unlock(&blwi->blwi_ns->ns_lock); + ldlm_namespace_put(blwi->blwi_ns); } + if (blwi->blwi_mem_pressure) - memory_pressure_clr(); + memalloc_noreclaim_restore(mpflags); if (blwi->blwi_flags & LCF_ASYNC) OBD_FREE(blwi, sizeof(*blwi)); @@ -3436,6 +3470,7 @@ void ldlm_exit(void) { if (ldlm_refcount) CERROR("ldlm_refcount is %d in ldlm_exit!\n", ldlm_refcount); + synchronize_rcu(); kmem_cache_destroy(ldlm_resource_slab); /* * ldlm_lock_put() use RCU to call ldlm_lock_free, so need call