aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorAndrea Arcangeli <aarcange@redhat.com>2017-09-20 20:07:00 +0200
committerAndrea Arcangeli <aarcange@redhat.com>2018-01-09 15:30:12 +0100
commit25412491e9e43d27d9c50aea09a106e4876f108e (patch)
treea3100ce8969e56f921ddf8cfc4133fd7c84ce22f
parent6c954707b3c7dddbeca90750ee54d26b0095544c (diff)
downloadaa-userfault.tar.gz
userfaultfd: switch to exclusive wakeup for blocking readsuserfault
The uffd can't short-read. Lengths not multiple of sizeof(struct uffd_msg) immediately return -EINVAL. The userfaults aren't broadcasted to all readers. read will return one or more events, sizeof(struct uffd_msg). Signal interruptions only are reported if it's about to block and it found nothing. Every new userfault blocking (and at max 1 event to read is generated for each new blocking userfaults) wakes one more reader, and each reader is guaranteed to be blocked only if the pending (pending as not read yet) waitqueue is truly empty. Signed-off-by: Andrea Arcangeli <aarcange@redhat.com>
-rw-r--r--fs/userfaultfd.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/fs/userfaultfd.c b/fs/userfaultfd.c
index f8e1a38adcd9c2..d3fbab1e22b0b3 100644
--- a/fs/userfaultfd.c
+++ b/fs/userfaultfd.c
@@ -1040,7 +1040,7 @@ static ssize_t userfaultfd_ctx_read(struct userfaultfd_ctx *ctx, int no_wait,
/* always take the fd_wqh lock before the fault_pending_wqh lock */
spin_lock(&ctx->fd_wqh.lock);
- __add_wait_queue(&ctx->fd_wqh, &wait);
+ __add_wait_queue_exclusive(&ctx->fd_wqh, &wait);
for (;;) {
set_current_state(TASK_INTERRUPTIBLE);
spin_lock(&ctx->fault_pending_wqh.lock);