staging: lustre: introduce and use l_wait_event_abortable()
lustre sometimes wants to wait for an event, but abort if one of a specific list of signals arrives. This is a little bit like wait_event_killable(), except that the signals are identified a different way. So introduce l_wait_event_abortable() which provides this functionality. Having separate functions for separate needs is more in line with the pattern set by include/linux/wait.h, than having a single function which tries to include all possible needs. Also introduce l_wait_event_abortable_exclusive(). Note that l_wait_event() return -EINTR on a signal, while Linux wait_event functions return -ERESTARTSYS. l_wait_event_{abortable_,}exclusive follow the Linux pattern. Reviewed-by: James Simmons <jsimmons@infradead.org> Signed-off-by: NeilBrown <neilb@suse.com> Reviewed-by: Patrick Farrell <paf@cray.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
98b0928044
commit
eb7e1f3a3b
|
@ -336,4 +336,28 @@ do { \
|
|||
/** @} lib */
|
||||
|
||||
|
||||
|
||||
/* l_wait_event_abortable() is a bit like wait_event_killable()
|
||||
* except there is a fixed set of signals which will abort:
|
||||
* LUSTRE_FATAL_SIGS
|
||||
*/
|
||||
#define l_wait_event_abortable(wq, condition) \
|
||||
({ \
|
||||
sigset_t __blocked; \
|
||||
int __ret = 0; \
|
||||
__blocked = cfs_block_sigsinv(LUSTRE_FATAL_SIGS); \
|
||||
__ret = wait_event_interruptible(wq, condition); \
|
||||
cfs_restore_sigs(__blocked); \
|
||||
__ret; \
|
||||
})
|
||||
|
||||
#define l_wait_event_abortable_exclusive(wq, condition) \
|
||||
({ \
|
||||
sigset_t __blocked; \
|
||||
int __ret = 0; \
|
||||
__blocked = cfs_block_sigsinv(LUSTRE_FATAL_SIGS); \
|
||||
__ret = wait_event_interruptible_exclusive(wq, condition); \
|
||||
cfs_restore_sigs(__blocked); \
|
||||
__ret; \
|
||||
})
|
||||
#endif /* _LUSTRE_LIB_H */
|
||||
|
|
|
@ -879,7 +879,6 @@ static int __ldlm_namespace_free(struct ldlm_namespace *ns, int force)
|
|||
ldlm_namespace_cleanup(ns, force ? LDLM_FL_LOCAL_ONLY : 0);
|
||||
|
||||
if (atomic_read(&ns->ns_bref) > 0) {
|
||||
struct l_wait_info lwi = LWI_INTR(LWI_ON_SIGNAL_NOOP, NULL);
|
||||
int rc;
|
||||
|
||||
CDEBUG(D_DLMTRACE,
|
||||
|
@ -887,11 +886,12 @@ static int __ldlm_namespace_free(struct ldlm_namespace *ns, int force)
|
|||
ldlm_ns_name(ns), atomic_read(&ns->ns_bref));
|
||||
force_wait:
|
||||
if (force)
|
||||
lwi = LWI_TIMEOUT(msecs_to_jiffies(obd_timeout *
|
||||
MSEC_PER_SEC) / 4, NULL, NULL);
|
||||
|
||||
rc = l_wait_event(ns->ns_waitq,
|
||||
atomic_read(&ns->ns_bref) == 0, &lwi);
|
||||
rc = wait_event_idle_timeout(ns->ns_waitq,
|
||||
atomic_read(&ns->ns_bref) == 0,
|
||||
obd_timeout * HZ / 4) ? 0 : -ETIMEDOUT;
|
||||
else
|
||||
rc = l_wait_event_abortable(ns->ns_waitq,
|
||||
atomic_read(&ns->ns_bref) == 0);
|
||||
|
||||
/* Forced cleanups should be able to reclaim all references,
|
||||
* so it's safe to wait forever... we can't leak locks...
|
||||
|
|
|
@ -986,16 +986,12 @@ void ll_put_super(struct super_block *sb)
|
|||
}
|
||||
|
||||
/* Wait for unstable pages to be committed to stable storage */
|
||||
if (!force) {
|
||||
struct l_wait_info lwi = LWI_INTR(LWI_ON_SIGNAL_NOOP, NULL);
|
||||
|
||||
rc = l_wait_event(sbi->ll_cache->ccc_unstable_waitq,
|
||||
!atomic_long_read(&sbi->ll_cache->ccc_unstable_nr),
|
||||
&lwi);
|
||||
}
|
||||
if (!force)
|
||||
rc = l_wait_event_abortable(sbi->ll_cache->ccc_unstable_waitq,
|
||||
!atomic_long_read(&sbi->ll_cache->ccc_unstable_nr));
|
||||
|
||||
ccc_count = atomic_long_read(&sbi->ll_cache->ccc_unstable_nr);
|
||||
if (!force && rc != -EINTR)
|
||||
if (!force && rc != -ERESTARTSYS)
|
||||
LASSERTF(!ccc_count, "count: %li\n", ccc_count);
|
||||
|
||||
/* We need to set force before the lov_disconnect in
|
||||
|
|
|
@ -1332,7 +1332,6 @@ static bool obd_request_slot_avail(struct client_obd *cli,
|
|||
int obd_get_request_slot(struct client_obd *cli)
|
||||
{
|
||||
struct obd_request_slot_waiter orsw;
|
||||
struct l_wait_info lwi;
|
||||
int rc;
|
||||
|
||||
spin_lock(&cli->cl_loi_list_lock);
|
||||
|
@ -1347,11 +1346,9 @@ int obd_get_request_slot(struct client_obd *cli)
|
|||
orsw.orsw_signaled = false;
|
||||
spin_unlock(&cli->cl_loi_list_lock);
|
||||
|
||||
lwi = LWI_INTR(LWI_ON_SIGNAL_NOOP, NULL);
|
||||
rc = l_wait_event(orsw.orsw_waitq,
|
||||
obd_request_slot_avail(cli, &orsw) ||
|
||||
orsw.orsw_signaled,
|
||||
&lwi);
|
||||
rc = l_wait_event_abortable(orsw.orsw_waitq,
|
||||
obd_request_slot_avail(cli, &orsw) ||
|
||||
orsw.orsw_signaled);
|
||||
|
||||
/*
|
||||
* Here, we must take the lock to avoid the on-stack 'orsw' to be
|
||||
|
|
|
@ -104,7 +104,6 @@ EXPORT_SYMBOL(__llog_ctxt_put);
|
|||
|
||||
int llog_cleanup(const struct lu_env *env, struct llog_ctxt *ctxt)
|
||||
{
|
||||
struct l_wait_info lwi = LWI_INTR(LWI_ON_SIGNAL_NOOP, NULL);
|
||||
struct obd_llog_group *olg;
|
||||
int rc, idx;
|
||||
|
||||
|
@ -129,8 +128,8 @@ int llog_cleanup(const struct lu_env *env, struct llog_ctxt *ctxt)
|
|||
CERROR("Error %d while cleaning up ctxt %p\n",
|
||||
rc, ctxt);
|
||||
|
||||
l_wait_event(olg->olg_waitq,
|
||||
llog_group_ctxt_null(olg, idx), &lwi);
|
||||
l_wait_event_abortable(olg->olg_waitq,
|
||||
llog_group_ctxt_null(olg, idx));
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
|
|
@ -759,7 +759,6 @@ out:
|
|||
static int osc_lru_alloc(const struct lu_env *env, struct client_obd *cli,
|
||||
struct osc_page *opg)
|
||||
{
|
||||
struct l_wait_info lwi = LWI_INTR(LWI_ON_SIGNAL_NOOP, NULL);
|
||||
struct osc_io *oio = osc_env_io(env);
|
||||
int rc = 0;
|
||||
|
||||
|
@ -782,9 +781,8 @@ static int osc_lru_alloc(const struct lu_env *env, struct client_obd *cli,
|
|||
|
||||
cond_resched();
|
||||
|
||||
rc = l_wait_event(osc_lru_waitq,
|
||||
atomic_long_read(cli->cl_lru_left) > 0,
|
||||
&lwi);
|
||||
rc = l_wait_event_abortable(osc_lru_waitq,
|
||||
atomic_long_read(cli->cl_lru_left) > 0);
|
||||
|
||||
if (rc < 0)
|
||||
break;
|
||||
|
|
|
@ -552,14 +552,12 @@ static int osc_destroy(const struct lu_env *env, struct obd_export *exp,
|
|||
|
||||
req->rq_interpret_reply = osc_destroy_interpret;
|
||||
if (!osc_can_send_destroy(cli)) {
|
||||
struct l_wait_info lwi = LWI_INTR(LWI_ON_SIGNAL_NOOP, NULL);
|
||||
|
||||
/*
|
||||
* Wait until the number of on-going destroy RPCs drops
|
||||
* under max_rpc_in_flight
|
||||
*/
|
||||
l_wait_event_exclusive(cli->cl_destroy_waitq,
|
||||
osc_can_send_destroy(cli), &lwi);
|
||||
l_wait_event_abortable_exclusive(cli->cl_destroy_waitq,
|
||||
osc_can_send_destroy(cli));
|
||||
}
|
||||
|
||||
/* Do not wait for response */
|
||||
|
|
Loading…
Reference in a new issue