ldlm_completion_ast() calls l_wait_event() in two slightly different
ways depending on whether a timeout is defined.
As a non-NULL _on_signal handler in passed, the non-timed-out portion
of the wait allows signals (abortable). As the on_timeout handler
return zero, the timed-out portion of the wait is always followed by a
non-timedout portion.
So if no timeout is defined, we can simply wait with
l_wait_event_abortable().
If there is a timeout, we first wait with wait_event_idle_timeout()
and if that times out, we call ldlm_expired_completion_wait(), then
wait with l_wait_event_abortable().
Change-Id: I6874010085864764f2fc0e294dc0c67152cb2ad2
Signed-off-by: Mr NeilBrown <neilb@suse.com>
Reviewed-on: https://review.whamcloud.com/35985
Tested-by: jenkins <devops@whamcloud.com>
Reviewed-by: James Simmons <jsimmons@infradead.org>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Petros Koutoupis <pkoutoupis@cray.com>
Reviewed-by: Shaun Tancheff <shaun.tancheff@hpe.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
} while (0)
/* ldlm_request.c */
} while (0)
/* ldlm_request.c */
-int ldlm_expired_completion_wait(void *data);
/** \defgroup ldlm_local_ast Default AST handlers for local locks
* These AST handlers are typically used for server-side local locks and are
* also used by client-side lock handlers to perform minimum level base
/** \defgroup ldlm_local_ast Default AST handlers for local locks
* These AST handlers are typically used for server-side local locks and are
* also used by client-side lock handlers to perform minimum level base
/* in client side, whether the cached locks will be canceled before replay */
unsigned int ldlm_cancel_unused_locks_before_replay = 1;
/* in client side, whether the cached locks will be canceled before replay */
unsigned int ldlm_cancel_unused_locks_before_replay = 1;
-static void interrupted_completion_wait(void *data)
-{
-}
-
struct lock_wait_data {
struct ldlm_lock *lwd_lock;
__u32 lwd_conn_cnt;
struct lock_wait_data {
struct ldlm_lock *lwd_lock;
__u32 lwd_conn_cnt;
return sizeof(struct ldlm_request) + avail;
}
return sizeof(struct ldlm_request) + avail;
}
-int ldlm_expired_completion_wait(void *data)
+void ldlm_expired_completion_wait(struct lock_wait_data *lwd)
- struct lock_wait_data *lwd = data;
struct ldlm_lock *lock = lwd->lwd_lock;
struct obd_import *imp;
struct obd_device *obd;
struct ldlm_lock *lock = lwd->lwd_lock;
struct obd_import *imp;
struct obd_device *obd;
if (last_dump == 0)
libcfs_debug_dumplog();
}
if (last_dump == 0)
libcfs_debug_dumplog();
}
}
obd = lock->l_conn_export->exp_obd;
}
obd = lock->l_conn_export->exp_obd;
(s64)(ktime_get_real_seconds() - lock->l_activity),
obd2cli_tgt(obd), imp->imp_connection->c_remote_uuid.uuid);
(s64)(ktime_get_real_seconds() - lock->l_activity),
obd2cli_tgt(obd), imp->imp_connection->c_remote_uuid.uuid);
}
int is_granted_or_cancelled_nolock(struct ldlm_lock *lock)
}
int is_granted_or_cancelled_nolock(struct ldlm_lock *lock)
struct lock_wait_data lwd;
struct obd_device *obd;
struct obd_import *imp = NULL;
struct lock_wait_data lwd;
struct obd_device *obd;
struct obd_import *imp = NULL;
- struct l_wait_info lwi;
time64_t timeout;
int rc = 0;
time64_t timeout;
int rc = 0;
lwd.lwd_lock = lock;
lock->l_activity = ktime_get_real_seconds();
lwd.lwd_lock = lock;
lock->l_activity = ktime_get_real_seconds();
- if (ldlm_is_no_timeout(lock)) {
- LDLM_DEBUG(lock, "waiting indefinitely because of NO_TIMEOUT");
- lwi = LWI_INTR(interrupted_completion_wait, &lwd);
- } else {
- lwi = LWI_TIMEOUT_INTR(cfs_time_seconds(timeout),
- ldlm_expired_completion_wait,
- interrupted_completion_wait, &lwd);
- }
-
if (imp != NULL) {
spin_lock(&imp->imp_lock);
lwd.lwd_conn_cnt = imp->imp_conn_cnt;
if (imp != NULL) {
spin_lock(&imp->imp_lock);
lwd.lwd_conn_cnt = imp->imp_conn_cnt;
rc = -EINTR;
} else {
/* Go to sleep until the lock is granted or cancelled. */
rc = -EINTR;
} else {
/* Go to sleep until the lock is granted or cancelled. */
- rc = l_wait_event(lock->l_waitq,
- is_granted_or_cancelled(lock), &lwi);
+ if (ldlm_is_no_timeout(lock)) {
+ LDLM_DEBUG(lock, "waiting indefinitely because of NO_TIMEOUT");
+ rc = l_wait_event_abortable(
+ lock->l_waitq,
+ is_granted_or_cancelled(lock));
+ } else {
+ if (wait_event_idle_timeout(
+ lock->l_waitq,
+ is_granted_or_cancelled(lock),
+ cfs_time_seconds(timeout)) == 0) {
+ ldlm_expired_completion_wait(&lwd);
+ rc = l_wait_event_abortable(
+ lock->l_waitq,
+ is_granted_or_cancelled(lock));
+ }
+ }