summary |
shortlog |
log |
commit | commitdiff |
tree
raw |
patch |
inline | side by side (from parent 1:
ca6c35c)
There are a couple of interesting aspects of waiters on ->set_waitq.
One is the only usage of LWI_TIMEOUT_INTR_ALL(). This causes
l_wait_event() to enable "fatal" signals during the timeout
part of the wait. (normally signals are completely blocked when
there is a timeout).
This can be converted to l_wait_event_abortable_timeout().
Another is that ptlrpc_expired_set() is passed as the on_timeout
handler. As this always returns true, it cauess l_wait_event()
to quit after the timeout, and not go "back to sleep".
We can instead call this explicitly after the wait_event_timeout
returns 0 - which means that it timedout.
Due to this change in call pattern, we can change the function to
take a ptlrpc_request_set* instead of a void*, and to not return
anything.
Also, ptlrpc_interrupted_set() is sometimes passed as the on_signal
function. Instead we can explicitly call this when we get a negative
return from wait_event_abortable. Again, we can declare it as
taking the real type and not a void*.
The wait on set_waitq in ptlrpcd() might be a timedout wait or,
if timeout == 0, it is an indefinite wait. We make that explicit
with 2 separate cases.
So this patch:
- changes to wait_event_idle_timeout and
l_wait_event_abortable_timeout,
- calls ptlrpc_*_set explicitly based on return code
- changes signatures for ptlrpc_*_set()
Change-Id: Ieb97aa3ba9b1f988a30bb7a424588f87f75e8023
Signed-off-by: Mr NeilBrown <neilb@suse.de>
Reviewed-on: https://review.whamcloud.com/35982
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: James Simmons <jsimmons@infradead.org>
Reviewed-by: Alex Zhuravlev <bzzz@whamcloud.com>
Reviewed-by: Shaun Tancheff <shaun.tancheff@hpe.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
* Callback used when waiting on sets with l_wait_event.
* Always returns 1.
*/
* Callback used when waiting on sets with l_wait_event.
* Always returns 1.
*/
-int ptlrpc_expired_set(void *data)
+void ptlrpc_expired_set(struct ptlrpc_request_set *set)
- struct ptlrpc_request_set *set = data;
struct list_head *tmp;
time64_t now = ktime_get_real_seconds();
struct list_head *tmp;
time64_t now = ktime_get_real_seconds();
*/
ptlrpc_expire_one_request(req, 1);
}
*/
ptlrpc_expire_one_request(req, 1);
}
-
- /*
- * When waiting for a whole set, we always break out of the
- * sleep so we can recalculate the timeout, or enable interrupts
- * if everyone's timed out.
- */
- RETURN(1);
* Interrupts (sets interrupted flag) all uncompleted requests in
* a set \a data. Callback for l_wait_event for interruptible waits.
*/
* Interrupts (sets interrupted flag) all uncompleted requests in
* a set \a data. Callback for l_wait_event for interruptible waits.
*/
-static void ptlrpc_interrupted_set(void *data)
+static void ptlrpc_interrupted_set(struct ptlrpc_request_set *set)
- struct ptlrpc_request_set *set = data;
struct list_head *tmp;
LASSERT(set != NULL);
struct list_head *tmp;
LASSERT(set != NULL);
{
struct list_head *tmp;
struct ptlrpc_request *req;
{
struct list_head *tmp;
struct ptlrpc_request *req;
- struct l_wait_info lwi;
time64_t timeout;
int rc;
time64_t timeout;
int rc;
* We still want to block for a limited time,
* so we allow interrupts during the timeout.
*/
* We still want to block for a limited time,
* so we allow interrupts during the timeout.
*/
- lwi = LWI_TIMEOUT_INTR_ALL(
- cfs_time_seconds(timeout ? timeout : 1),
- ptlrpc_expired_set,
- ptlrpc_interrupted_set, set);
-
- rc = l_wait_event(set->set_waitq,
- ptlrpc_check_set(NULL, set), &lwi);
+ rc = l_wait_event_abortable_timeout(
+ set->set_waitq,
+ ptlrpc_check_set(NULL, set),
+ cfs_time_seconds(timeout ? timeout : 1));
+ if (rc == 0) {
+ rc = -ETIMEDOUT;
+ ptlrpc_expired_set(set);
+ } else if (rc < 0) {
+ rc = -EINTR;
+ ptlrpc_interrupted_set(set);
+ } else {
+ rc = 0;
+ }
} else {
/*
* At least one request is in flight, so no
* interrupts are allowed. Wait until all
* complete, or an in-flight req times out.
*/
} else {
/*
* At least one request is in flight, so no
* interrupts are allowed. Wait until all
* complete, or an in-flight req times out.
*/
- lwi = LWI_TIMEOUT(cfs_time_seconds(timeout ? timeout : 1),
- ptlrpc_expired_set, set);
-
- rc = l_wait_event(set->set_waitq,
- ptlrpc_check_set(NULL, set), &lwi);
+ rc = wait_event_idle_timeout(
+ set->set_waitq,
+ ptlrpc_check_set(NULL, set),
+ cfs_time_seconds(timeout ? timeout : 1));
+ if (rc == 0) {
+ ptlrpc_expired_set(set);
+ rc = -ETIMEDOUT;
+ } else {
+ rc = 0;
+ }
/*
* LU-769 - if we ignored the signal because
/*
* LU-769 - if we ignored the signal because
void ptlrpc_init_xid(void);
void ptlrpc_set_add_new_req(struct ptlrpcd_ctl *pc,
struct ptlrpc_request *req);
void ptlrpc_init_xid(void);
void ptlrpc_set_add_new_req(struct ptlrpcd_ctl *pc,
struct ptlrpc_request *req);
-int ptlrpc_expired_set(void *data);
+void ptlrpc_expired_set(struct ptlrpc_request_set *set);
time64_t ptlrpc_set_next_timeout(struct ptlrpc_request_set *);
void ptlrpc_resend_req(struct ptlrpc_request *request);
void ptlrpc_set_bulk_mbits(struct ptlrpc_request *req);
time64_t ptlrpc_set_next_timeout(struct ptlrpc_request_set *);
void ptlrpc_resend_req(struct ptlrpc_request *request);
void ptlrpc_set_bulk_mbits(struct ptlrpc_request *req);
* new_req_list and ptlrpcd_check() moves them into the set.
*/
do {
* new_req_list and ptlrpcd_check() moves them into the set.
*/
do {
- struct l_wait_info lwi;
time64_t timeout;
timeout = ptlrpc_set_next_timeout(set);
time64_t timeout;
timeout = ptlrpc_set_next_timeout(set);
- lwi = LWI_TIMEOUT(cfs_time_seconds(timeout),
- ptlrpc_expired_set, set);
lu_context_enter(&env.le_ctx);
lu_context_enter(env.le_ses);
lu_context_enter(&env.le_ctx);
lu_context_enter(env.le_ses);
- l_wait_event(set->set_waitq, ptlrpcd_check(&env, pc), &lwi);
+ if (timeout == 0)
+ wait_event_idle(set->set_waitq,
+ ptlrpcd_check(&env, pc));
+ else if (wait_event_idle_timeout(set->set_waitq,
+ ptlrpcd_check(&env, pc),
+ cfs_time_seconds(timeout))
+ == 0)
+ ptlrpc_expired_set(set);
lu_context_exit(&env.le_ctx);
lu_context_exit(env.le_ses);
lu_context_exit(&env.le_ctx);
lu_context_exit(env.le_ses);