@@ -1039,6 +1039,7 @@ static ssize_t userfaultfd_ctx_read(struct userfaultfd_ctx *ctx, int no_wait,
set_current_state(TASK_INTERRUPTIBLE);
spin_lock(&ctx->fault_pending_wqh.lock);
uwq = find_userfault(ctx);
+ ret = -EAGAIN;
if (uwq) {
/*
* Use a seqcount to repeat the lockless check
@@ -1077,11 +1078,11 @@ static ssize_t userfaultfd_ctx_read(struct userfaultfd_ctx *ctx, int no_wait,
/* careful to always initialize msg if ret == 0 */
*msg = uwq->msg;
- spin_unlock(&ctx->fault_pending_wqh.lock);
ret = 0;
- break;
}
spin_unlock(&ctx->fault_pending_wqh.lock);
+ if (!ret)
+ break;
spin_lock(&ctx->event_wqh.lock);
uwq = find_userfault_evt(ctx);
@@ -1099,17 +1100,14 @@ static ssize_t userfaultfd_ctx_read(struct userfaultfd_ctx *ctx, int no_wait,
* reference on it.
*/
userfaultfd_ctx_get(fork_nctx);
- spin_unlock(&ctx->event_wqh.lock);
- ret = 0;
- break;
+ } else {
+ userfaultfd_event_complete(ctx, uwq);
}
-
- userfaultfd_event_complete(ctx, uwq);
- spin_unlock(&ctx->event_wqh.lock);
ret = 0;
- break;
}
spin_unlock(&ctx->event_wqh.lock);
+ if (!ret)
+ break;
if (signal_pending(current)) {
ret = -ERESTARTSYS;