diff options
author | Andrea Arcangeli <aarcange@redhat.com> | 2017-09-20 20:07:00 +0200 |
---|---|---|
committer | Andrea Arcangeli <aarcange@redhat.com> | 2018-01-09 15:30:12 +0100 |
commit | 25412491e9e43d27d9c50aea09a106e4876f108e (patch) | |
tree | a3100ce8969e56f921ddf8cfc4133fd7c84ce22f | |
parent | 6c954707b3c7dddbeca90750ee54d26b0095544c (diff) | |
download | aa-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.c | 2 |
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); |