Merge branch 'io_uring-5.8' into for-5.9/io_uring
[linux-2.6-microblaze.git] / fs / io_uring.c
index d37d7ea..7426e4f 100644 (file)
@@ -78,6 +78,7 @@
 #include <linux/fs_struct.h>
 #include <linux/splice.h>
 #include <linux/task_work.h>
+#include <linux/pagemap.h>
 
 #define CREATE_TRACE_POINTS
 #include <trace/events/io_uring.h>
@@ -226,7 +227,7 @@ struct io_ring_ctx {
        struct {
                unsigned int            flags;
                unsigned int            compat: 1;
-               unsigned int            account_mem: 1;
+               unsigned int            limit_mem: 1;
                unsigned int            cq_overflow_flushed: 1;
                unsigned int            drain_next: 1;
                unsigned int            eventfd_async: 1;
@@ -503,6 +504,8 @@ struct io_async_rw {
        struct iovec                    *iov;
        ssize_t                         nr_segs;
        ssize_t                         size;
+       struct wait_page_queue          wpq;
+       struct callback_head            task_work;
 };
 
 struct io_async_ctx {
@@ -523,16 +526,12 @@ enum {
        REQ_F_BUFFER_SELECT_BIT = IOSQE_BUFFER_SELECT_BIT,
 
        REQ_F_LINK_HEAD_BIT,
-       REQ_F_LINK_NEXT_BIT,
        REQ_F_FAIL_LINK_BIT,
        REQ_F_INFLIGHT_BIT,
        REQ_F_CUR_POS_BIT,
        REQ_F_NOWAIT_BIT,
        REQ_F_LINK_TIMEOUT_BIT,
-       REQ_F_TIMEOUT_BIT,
        REQ_F_ISREG_BIT,
-       REQ_F_MUST_PUNT_BIT,
-       REQ_F_TIMEOUT_NOSEQ_BIT,
        REQ_F_COMP_LOCKED_BIT,
        REQ_F_NEED_CLEANUP_BIT,
        REQ_F_OVERFLOW_BIT,
@@ -563,8 +562,6 @@ enum {
 
        /* head of a link */
        REQ_F_LINK_HEAD         = BIT(REQ_F_LINK_HEAD_BIT),
-       /* already grabbed next link */
-       REQ_F_LINK_NEXT         = BIT(REQ_F_LINK_NEXT_BIT),
        /* fail rest of links */
        REQ_F_FAIL_LINK         = BIT(REQ_F_FAIL_LINK_BIT),
        /* on inflight list */
@@ -575,14 +572,8 @@ enum {
        REQ_F_NOWAIT            = BIT(REQ_F_NOWAIT_BIT),
        /* has linked timeout */
        REQ_F_LINK_TIMEOUT      = BIT(REQ_F_LINK_TIMEOUT_BIT),
-       /* timeout request */
-       REQ_F_TIMEOUT           = BIT(REQ_F_TIMEOUT_BIT),
        /* regular file */
        REQ_F_ISREG             = BIT(REQ_F_ISREG_BIT),
-       /* must be punted even for NONBLOCK */
-       REQ_F_MUST_PUNT         = BIT(REQ_F_MUST_PUNT_BIT),
-       /* no timeout sequence */
-       REQ_F_TIMEOUT_NOSEQ     = BIT(REQ_F_TIMEOUT_NOSEQ_BIT),
        /* completion under lock */
        REQ_F_COMP_LOCKED       = BIT(REQ_F_COMP_LOCKED_BIT),
        /* needs cleanup */
@@ -668,17 +659,22 @@ struct io_kiocb {
                 * restore the work, if needed.
                 */
                struct {
-                       struct callback_head    task_work;
                        struct hlist_node       hash_node;
                        struct async_poll       *apoll;
                };
                struct io_wq_work       work;
        };
+       struct callback_head    task_work;
 };
 
-#define IO_PLUG_THRESHOLD              2
 #define IO_IOPOLL_BATCH                        8
 
+struct io_comp_state {
+       unsigned int            nr;
+       struct list_head        list;
+       struct io_ring_ctx      *ctx;
+};
+
 struct io_submit_state {
        struct blk_plug         plug;
 
@@ -688,6 +684,11 @@ struct io_submit_state {
        void                    *reqs[IO_IOPOLL_BATCH];
        unsigned int            free_reqs;
 
+       /*
+        * Batch completion logic
+        */
+       struct io_comp_state    comp;
+
        /*
         * File reference cache
         */
@@ -880,9 +881,15 @@ static const struct io_op_def io_op_defs[] = {
        },
 };
 
-static void io_wq_submit_work(struct io_wq_work **workptr);
+enum io_mem_account {
+       ACCT_LOCKED,
+       ACCT_PINNED,
+};
+
+static bool io_rw_reissue(struct io_kiocb *req, long res);
 static void io_cqring_fill_event(struct io_kiocb *req, long res);
 static void io_put_req(struct io_kiocb *req);
+static void io_double_put_req(struct io_kiocb *req);
 static void __io_double_put_req(struct io_kiocb *req);
 static struct io_kiocb *io_prep_linked_timeout(struct io_kiocb *req);
 static void io_queue_linked_timeout(struct io_kiocb *req);
@@ -890,12 +897,21 @@ static int __io_sqe_files_update(struct io_ring_ctx *ctx,
                                 struct io_uring_files_update *ip,
                                 unsigned nr_args);
 static int io_grab_files(struct io_kiocb *req);
-static void io_complete_rw_common(struct kiocb *kiocb, long res);
+static void io_complete_rw_common(struct kiocb *kiocb, long res,
+                                 struct io_comp_state *cs);
 static void io_cleanup_req(struct io_kiocb *req);
 static int io_file_get(struct io_submit_state *state, struct io_kiocb *req,
                       int fd, struct file **out_file, bool fixed);
 static void __io_queue_sqe(struct io_kiocb *req,
-                          const struct io_uring_sqe *sqe);
+                          const struct io_uring_sqe *sqe,
+                          struct io_comp_state *cs);
+
+static ssize_t io_import_iovec(int rw, struct io_kiocb *req,
+                              struct iovec **iovec, struct iov_iter *iter,
+                              bool needs_lock);
+static int io_setup_async_rw(struct io_kiocb *req, ssize_t io_size,
+                            struct iovec *iovec, struct iovec *fast_iov,
+                            struct iov_iter *iter);
 
 static struct kmem_cache *req_cachep;
 
@@ -929,6 +945,41 @@ static void __io_put_req_task(struct io_kiocb *req)
                put_task_struct(req->task);
 }
 
+static void io_sq_thread_drop_mm(struct io_ring_ctx *ctx)
+{
+       struct mm_struct *mm = current->mm;
+
+       if (mm) {
+               kthread_unuse_mm(mm);
+               mmput(mm);
+       }
+}
+
+static int __io_sq_thread_acquire_mm(struct io_ring_ctx *ctx)
+{
+       if (!current->mm) {
+               if (unlikely(!ctx->sqo_mm || !mmget_not_zero(ctx->sqo_mm)))
+                       return -EFAULT;
+               kthread_use_mm(ctx->sqo_mm);
+       }
+
+       return 0;
+}
+
+static int io_sq_thread_acquire_mm(struct io_ring_ctx *ctx,
+                                  struct io_kiocb *req)
+{
+       if (!io_op_defs[req->opcode].needs_mm)
+               return 0;
+       return __io_sq_thread_acquire_mm(ctx);
+}
+
+static inline void req_set_fail_links(struct io_kiocb *req)
+{
+       if ((req->flags & (REQ_F_LINK | REQ_F_HARDLINK)) == REQ_F_LINK)
+               req->flags |= REQ_F_FAIL_LINK;
+}
+
 static void io_file_put_work(struct work_struct *work);
 
 /*
@@ -956,6 +1007,11 @@ static void io_ring_ctx_ref_free(struct percpu_ref *ref)
        complete(&ctx->ref_comp);
 }
 
+static inline bool io_is_timeout_noseq(struct io_kiocb *req)
+{
+       return !req->timeout.off;
+}
+
 static struct io_ring_ctx *io_ring_ctx_alloc(struct io_uring_params *p)
 {
        struct io_ring_ctx *ctx;
@@ -1045,9 +1101,12 @@ static void __io_commit_cqring(struct io_ring_ctx *ctx)
        }
 }
 
-static inline void io_req_work_grab_env(struct io_kiocb *req,
-                                       const struct io_op_def *def)
+static void io_req_work_grab_env(struct io_kiocb *req)
 {
+       const struct io_op_def *def = &io_op_defs[req->opcode];
+
+       io_req_init_async(req);
+
        if (!req->work.mm && def->needs_mm) {
                mmgrab(current->mm);
                req->work.mm = current->mm;
@@ -1091,8 +1150,7 @@ static inline void io_req_work_drop_env(struct io_kiocb *req)
        }
 }
 
-static inline void io_prep_async_work(struct io_kiocb *req,
-                                     struct io_kiocb **link)
+static void io_prep_async_work(struct io_kiocb *req)
 {
        const struct io_op_def *def = &io_op_defs[req->opcode];
 
@@ -1104,18 +1162,23 @@ static inline void io_prep_async_work(struct io_kiocb *req,
                        req->work.flags |= IO_WQ_WORK_UNBOUND;
        }
 
-       io_req_init_async(req);
-       io_req_work_grab_env(req, def);
+       io_req_work_grab_env(req);
+}
+
+static void io_prep_async_link(struct io_kiocb *req)
+{
+       struct io_kiocb *cur;
 
-       *link = io_prep_linked_timeout(req);
+       io_prep_async_work(req);
+       if (req->flags & REQ_F_LINK_HEAD)
+               list_for_each_entry(cur, &req->link_list, link_list)
+                       io_prep_async_work(cur);
 }
 
-static inline void io_queue_async_work(struct io_kiocb *req)
+static void __io_queue_async_work(struct io_kiocb *req)
 {
        struct io_ring_ctx *ctx = req->ctx;
-       struct io_kiocb *link;
-
-       io_prep_async_work(req, &link);
+       struct io_kiocb *link = io_prep_linked_timeout(req);
 
        trace_io_uring_queue_async_work(ctx, io_wq_is_hashed(&req->work), req,
                                        &req->work, req->flags);
@@ -1125,6 +1188,13 @@ static inline void io_queue_async_work(struct io_kiocb *req)
                io_queue_linked_timeout(link);
 }
 
+static void io_queue_async_work(struct io_kiocb *req)
+{
+       /* init ->work of the whole link before punting */
+       io_prep_async_link(req);
+       __io_queue_async_work(req);
+}
+
 static void io_kill_timeout(struct io_kiocb *req)
 {
        int ret;
@@ -1158,7 +1228,8 @@ static void __io_queue_deferred(struct io_ring_ctx *ctx)
                if (req_need_defer(req))
                        break;
                list_del_init(&req->list);
-               io_queue_async_work(req);
+               /* punt-init is done before queueing for defer */
+               __io_queue_async_work(req);
        } while (!list_empty(&ctx->defer_list));
 }
 
@@ -1168,7 +1239,7 @@ static void io_flush_timeouts(struct io_ring_ctx *ctx)
                struct io_kiocb *req = list_first_entry(&ctx->timeout_list,
                                                        struct io_kiocb, list);
 
-               if (req->flags & REQ_F_TIMEOUT_NOSEQ)
+               if (io_is_timeout_noseq(req))
                        break;
                if (req->timeout.target_seq != ctx->cached_cq_tail
                                        - atomic_read(&ctx->cq_timeouts))
@@ -1325,7 +1396,7 @@ static void io_cqring_fill_event(struct io_kiocb *req, long res)
        __io_cqring_fill_event(req, res, 0);
 }
 
-static void __io_cqring_add_event(struct io_kiocb *req, long res, long cflags)
+static void io_cqring_add_event(struct io_kiocb *req, long res, long cflags)
 {
        struct io_ring_ctx *ctx = req->ctx;
        unsigned long flags;
@@ -1338,9 +1409,50 @@ static void __io_cqring_add_event(struct io_kiocb *req, long res, long cflags)
        io_cqring_ev_posted(ctx);
 }
 
-static void io_cqring_add_event(struct io_kiocb *req, long res)
+static void io_submit_flush_completions(struct io_comp_state *cs)
+{
+       struct io_ring_ctx *ctx = cs->ctx;
+
+       spin_lock_irq(&ctx->completion_lock);
+       while (!list_empty(&cs->list)) {
+               struct io_kiocb *req;
+
+               req = list_first_entry(&cs->list, struct io_kiocb, list);
+               list_del(&req->list);
+               io_cqring_fill_event(req, req->result);
+               if (!(req->flags & REQ_F_LINK_HEAD)) {
+                       req->flags |= REQ_F_COMP_LOCKED;
+                       io_put_req(req);
+               } else {
+                       spin_unlock_irq(&ctx->completion_lock);
+                       io_put_req(req);
+                       spin_lock_irq(&ctx->completion_lock);
+               }
+       }
+       io_commit_cqring(ctx);
+       spin_unlock_irq(&ctx->completion_lock);
+
+       io_cqring_ev_posted(ctx);
+       cs->nr = 0;
+}
+
+static void __io_req_complete(struct io_kiocb *req, long res, unsigned cflags,
+                             struct io_comp_state *cs)
 {
-       __io_cqring_add_event(req, res, 0);
+       if (!cs) {
+               io_cqring_add_event(req, res, cflags);
+               io_put_req(req);
+       } else {
+               req->result = res;
+               list_add_tail(&req->list, &cs->list);
+               if (++cs->nr >= 32)
+                       io_submit_flush_completions(cs);
+       }
+}
+
+static void io_req_complete(struct io_kiocb *req, long res)
+{
+       __io_req_complete(req, res, 0, NULL);
 }
 
 static inline bool io_is_fallback_req(struct io_kiocb *req)
@@ -1366,11 +1478,7 @@ static struct io_kiocb *io_alloc_req(struct io_ring_ctx *ctx,
        gfp_t gfp = GFP_KERNEL | __GFP_NOWARN;
        struct io_kiocb *req;
 
-       if (!state) {
-               req = kmem_cache_alloc(req_cachep, gfp);
-               if (unlikely(!req))
-                       goto fallback;
-       } else if (!state->free_reqs) {
+       if (!state->free_reqs) {
                size_t sz;
                int ret;
 
@@ -1408,7 +1516,7 @@ static inline void io_put_file(struct io_kiocb *req, struct file *file,
                fput(file);
 }
 
-static void __io_req_aux_free(struct io_kiocb *req)
+static void io_dismantle_req(struct io_kiocb *req)
 {
        if (req->flags & REQ_F_NEED_CLEANUP)
                io_cleanup_req(req);
@@ -1418,11 +1526,6 @@ static void __io_req_aux_free(struct io_kiocb *req)
                io_put_file(req, req->file, (req->flags & REQ_F_FIXED_FILE));
        __io_put_req_task(req);
        io_req_work_drop_env(req);
-}
-
-static void __io_free_req(struct io_kiocb *req)
-{
-       __io_req_aux_free(req);
 
        if (req->flags & REQ_F_INFLIGHT) {
                struct io_ring_ctx *ctx = req->ctx;
@@ -1434,57 +1537,19 @@ static void __io_free_req(struct io_kiocb *req)
                        wake_up(&ctx->inflight_wait);
                spin_unlock_irqrestore(&ctx->inflight_lock, flags);
        }
-
-       percpu_ref_put(&req->ctx->refs);
-       if (likely(!io_is_fallback_req(req)))
-               kmem_cache_free(req_cachep, req);
-       else
-               clear_bit_unlock(0, (unsigned long *) &req->ctx->fallback_req);
 }
 
-struct req_batch {
-       void *reqs[IO_IOPOLL_BATCH];
-       int to_free;
-       int need_iter;
-};
-
-static void io_free_req_many(struct io_ring_ctx *ctx, struct req_batch *rb)
+static void __io_free_req(struct io_kiocb *req)
 {
-       if (!rb->to_free)
-               return;
-       if (rb->need_iter) {
-               int i, inflight = 0;
-               unsigned long flags;
-
-               for (i = 0; i < rb->to_free; i++) {
-                       struct io_kiocb *req = rb->reqs[i];
-
-                       if (req->flags & REQ_F_INFLIGHT)
-                               inflight++;
-                       __io_req_aux_free(req);
-               }
-               if (!inflight)
-                       goto do_free;
-
-               spin_lock_irqsave(&ctx->inflight_lock, flags);
-               for (i = 0; i < rb->to_free; i++) {
-                       struct io_kiocb *req = rb->reqs[i];
-
-                       if (req->flags & REQ_F_INFLIGHT) {
-                               list_del(&req->inflight_entry);
-                               if (!--inflight)
-                                       break;
-                       }
-               }
-               spin_unlock_irqrestore(&ctx->inflight_lock, flags);
+       struct io_ring_ctx *ctx;
 
-               if (waitqueue_active(&ctx->inflight_wait))
-                       wake_up(&ctx->inflight_wait);
-       }
-do_free:
-       kmem_cache_free_bulk(req_cachep, rb->to_free, rb->reqs);
-       percpu_ref_put_many(&ctx->refs, rb->to_free);
-       rb->to_free = rb->need_iter = 0;
+       io_dismantle_req(req);
+       ctx = req->ctx;
+       if (likely(!io_is_fallback_req(req)))
+               kmem_cache_free(req_cachep, req);
+       else
+               clear_bit_unlock(0, (unsigned long *) &ctx->fallback_req);
+       percpu_ref_put(&ctx->refs);
 }
 
 static bool io_link_cancel_timeout(struct io_kiocb *req)
@@ -1504,53 +1569,67 @@ static bool io_link_cancel_timeout(struct io_kiocb *req)
        return false;
 }
 
-static void io_req_link_next(struct io_kiocb *req, struct io_kiocb **nxtptr)
+static bool __io_kill_linked_timeout(struct io_kiocb *req)
+{
+       struct io_kiocb *link;
+       bool wake_ev;
+
+       if (list_empty(&req->link_list))
+               return false;
+       link = list_first_entry(&req->link_list, struct io_kiocb, link_list);
+       if (link->opcode != IORING_OP_LINK_TIMEOUT)
+               return false;
+
+       list_del_init(&link->link_list);
+       wake_ev = io_link_cancel_timeout(link);
+       req->flags &= ~REQ_F_LINK_TIMEOUT;
+       return wake_ev;
+}
+
+static void io_kill_linked_timeout(struct io_kiocb *req)
 {
        struct io_ring_ctx *ctx = req->ctx;
-       bool wake_ev = false;
+       bool wake_ev;
 
-       /* Already got next link */
-       if (req->flags & REQ_F_LINK_NEXT)
-               return;
+       if (!(req->flags & REQ_F_COMP_LOCKED)) {
+               unsigned long flags;
+
+               spin_lock_irqsave(&ctx->completion_lock, flags);
+               wake_ev = __io_kill_linked_timeout(req);
+               spin_unlock_irqrestore(&ctx->completion_lock, flags);
+       } else {
+               wake_ev = __io_kill_linked_timeout(req);
+       }
+
+       if (wake_ev)
+               io_cqring_ev_posted(ctx);
+}
+
+static struct io_kiocb *io_req_link_next(struct io_kiocb *req)
+{
+       struct io_kiocb *nxt;
 
        /*
         * The list should never be empty when we are called here. But could
         * potentially happen if the chain is messed up, check to be on the
         * safe side.
         */
-       while (!list_empty(&req->link_list)) {
-               struct io_kiocb *nxt = list_first_entry(&req->link_list,
-                                               struct io_kiocb, link_list);
-
-               if (unlikely((req->flags & REQ_F_LINK_TIMEOUT) &&
-                            (nxt->flags & REQ_F_TIMEOUT))) {
-                       list_del_init(&nxt->link_list);
-                       wake_ev |= io_link_cancel_timeout(nxt);
-                       req->flags &= ~REQ_F_LINK_TIMEOUT;
-                       continue;
-               }
-
-               list_del_init(&req->link_list);
-               if (!list_empty(&nxt->link_list))
-                       nxt->flags |= REQ_F_LINK_HEAD;
-               *nxtptr = nxt;
-               break;
-       }
+       if (unlikely(list_empty(&req->link_list)))
+               return NULL;
 
-       req->flags |= REQ_F_LINK_NEXT;
-       if (wake_ev)
-               io_cqring_ev_posted(ctx);
+       nxt = list_first_entry(&req->link_list, struct io_kiocb, link_list);
+       list_del_init(&req->link_list);
+       if (!list_empty(&nxt->link_list))
+               nxt->flags |= REQ_F_LINK_HEAD;
+       return nxt;
 }
 
 /*
  * Called if REQ_F_LINK_HEAD is set, and we fail the head request
  */
-static void io_fail_links(struct io_kiocb *req)
+static void __io_fail_links(struct io_kiocb *req)
 {
        struct io_ring_ctx *ctx = req->ctx;
-       unsigned long flags;
-
-       spin_lock_irqsave(&ctx->completion_lock, flags);
 
        while (!list_empty(&req->link_list)) {
                struct io_kiocb *link = list_first_entry(&req->link_list,
@@ -1559,25 +1638,37 @@ static void io_fail_links(struct io_kiocb *req)
                list_del_init(&link->link_list);
                trace_io_uring_fail_link(req, link);
 
-               if ((req->flags & REQ_F_LINK_TIMEOUT) &&
-                   link->opcode == IORING_OP_LINK_TIMEOUT) {
-                       io_link_cancel_timeout(link);
-               } else {
-                       io_cqring_fill_event(link, -ECANCELED);
-                       __io_double_put_req(link);
-               }
+               io_cqring_fill_event(link, -ECANCELED);
+               __io_double_put_req(link);
                req->flags &= ~REQ_F_LINK_TIMEOUT;
        }
 
        io_commit_cqring(ctx);
-       spin_unlock_irqrestore(&ctx->completion_lock, flags);
        io_cqring_ev_posted(ctx);
 }
 
-static void io_req_find_next(struct io_kiocb *req, struct io_kiocb **nxt)
+static void io_fail_links(struct io_kiocb *req)
 {
-       if (likely(!(req->flags & REQ_F_LINK_HEAD)))
-               return;
+       struct io_ring_ctx *ctx = req->ctx;
+
+       if (!(req->flags & REQ_F_COMP_LOCKED)) {
+               unsigned long flags;
+
+               spin_lock_irqsave(&ctx->completion_lock, flags);
+               __io_fail_links(req);
+               spin_unlock_irqrestore(&ctx->completion_lock, flags);
+       } else {
+               __io_fail_links(req);
+       }
+
+       io_cqring_ev_posted(ctx);
+}
+
+static struct io_kiocb *__io_req_find_next(struct io_kiocb *req)
+{
+       req->flags &= ~REQ_F_LINK_HEAD;
+       if (req->flags & REQ_F_LINK_TIMEOUT)
+               io_kill_linked_timeout(req);
 
        /*
         * If LINK is set, we have dependent requests in this chain. If we
@@ -1585,62 +1676,139 @@ static void io_req_find_next(struct io_kiocb *req, struct io_kiocb **nxt)
         * dependencies to the next request. In case of failure, fail the rest
         * of the chain.
         */
-       if (req->flags & REQ_F_FAIL_LINK) {
-               io_fail_links(req);
-       } else if ((req->flags & (REQ_F_LINK_TIMEOUT | REQ_F_COMP_LOCKED)) ==
-                       REQ_F_LINK_TIMEOUT) {
-               struct io_ring_ctx *ctx = req->ctx;
-               unsigned long flags;
+       if (likely(!(req->flags & REQ_F_FAIL_LINK)))
+               return io_req_link_next(req);
+       io_fail_links(req);
+       return NULL;
+}
 
-               /*
-                * If this is a timeout link, we could be racing with the
-                * timeout timer. Grab the completion lock for this case to
-                * protect against that.
-                */
-               spin_lock_irqsave(&ctx->completion_lock, flags);
-               io_req_link_next(req, nxt);
-               spin_unlock_irqrestore(&ctx->completion_lock, flags);
+static struct io_kiocb *io_req_find_next(struct io_kiocb *req)
+{
+       if (likely(!(req->flags & REQ_F_LINK_HEAD)))
+               return NULL;
+       return __io_req_find_next(req);
+}
+
+static void __io_req_task_cancel(struct io_kiocb *req, int error)
+{
+       struct io_ring_ctx *ctx = req->ctx;
+
+       spin_lock_irq(&ctx->completion_lock);
+       io_cqring_fill_event(req, error);
+       io_commit_cqring(ctx);
+       spin_unlock_irq(&ctx->completion_lock);
+
+       io_cqring_ev_posted(ctx);
+       req_set_fail_links(req);
+       io_double_put_req(req);
+}
+
+static void io_req_task_cancel(struct callback_head *cb)
+{
+       struct io_kiocb *req = container_of(cb, struct io_kiocb, task_work);
+
+       __io_req_task_cancel(req, -ECANCELED);
+}
+
+static void __io_req_task_submit(struct io_kiocb *req)
+{
+       struct io_ring_ctx *ctx = req->ctx;
+
+       __set_current_state(TASK_RUNNING);
+       if (!__io_sq_thread_acquire_mm(ctx)) {
+               mutex_lock(&ctx->uring_lock);
+               __io_queue_sqe(req, NULL, NULL);
+               mutex_unlock(&ctx->uring_lock);
        } else {
-               io_req_link_next(req, nxt);
+               __io_req_task_cancel(req, -EFAULT);
        }
 }
 
-static void io_free_req(struct io_kiocb *req)
+static void io_req_task_submit(struct callback_head *cb)
 {
-       struct io_kiocb *nxt = NULL;
+       struct io_kiocb *req = container_of(cb, struct io_kiocb, task_work);
 
-       io_req_find_next(req, &nxt);
-       __io_free_req(req);
+       __io_req_task_submit(req);
+}
+
+static void io_req_task_queue(struct io_kiocb *req)
+{
+       struct task_struct *tsk = req->task;
+       int ret;
+
+       init_task_work(&req->task_work, io_req_task_submit);
+
+       ret = task_work_add(tsk, &req->task_work, true);
+       if (unlikely(ret)) {
+               init_task_work(&req->task_work, io_req_task_cancel);
+               tsk = io_wq_get_task(req->ctx->io_wq);
+               task_work_add(tsk, &req->task_work, true);
+       }
+       wake_up_process(tsk);
+}
+
+static void io_queue_next(struct io_kiocb *req)
+{
+       struct io_kiocb *nxt = io_req_find_next(req);
 
        if (nxt)
-               io_queue_async_work(nxt);
+               io_req_task_queue(nxt);
 }
 
-static void io_wq_assign_next(struct io_wq_work **workptr, struct io_kiocb *nxt)
+static void io_free_req(struct io_kiocb *req)
 {
-       struct io_kiocb *link;
-       const struct io_op_def *def = &io_op_defs[nxt->opcode];
+       io_queue_next(req);
+       __io_free_req(req);
+}
 
-       if ((nxt->flags & REQ_F_ISREG) && def->hash_reg_file)
-               io_wq_hash_work(&nxt->work, file_inode(nxt->file));
+struct req_batch {
+       void *reqs[IO_IOPOLL_BATCH];
+       int to_free;
+};
 
-       *workptr = &nxt->work;
-       link = io_prep_linked_timeout(nxt);
-       if (link)
-               nxt->flags |= REQ_F_QUEUE_TIMEOUT;
+static void __io_req_free_batch_flush(struct io_ring_ctx *ctx,
+                                     struct req_batch *rb)
+{
+       kmem_cache_free_bulk(req_cachep, rb->to_free, rb->reqs);
+       percpu_ref_put_many(&ctx->refs, rb->to_free);
+       rb->to_free = 0;
+}
+
+static void io_req_free_batch_finish(struct io_ring_ctx *ctx,
+                                    struct req_batch *rb)
+{
+       if (rb->to_free)
+               __io_req_free_batch_flush(ctx, rb);
+}
+
+static void io_req_free_batch(struct req_batch *rb, struct io_kiocb *req)
+{
+       if (unlikely(io_is_fallback_req(req))) {
+               io_free_req(req);
+               return;
+       }
+       if (req->flags & REQ_F_LINK_HEAD)
+               io_queue_next(req);
+
+       io_dismantle_req(req);
+       rb->reqs[rb->to_free++] = req;
+       if (unlikely(rb->to_free == ARRAY_SIZE(rb->reqs)))
+               __io_req_free_batch_flush(req->ctx, rb);
 }
 
 /*
  * Drop reference to request, return next in chain (if there is one) if this
  * was the last reference to this request.
  */
-__attribute__((nonnull))
-static void io_put_req_find_next(struct io_kiocb *req, struct io_kiocb **nxtptr)
+static struct io_kiocb *io_put_req_find_next(struct io_kiocb *req)
 {
+       struct io_kiocb *nxt = NULL;
+
        if (refcount_dec_and_test(&req->refs)) {
-               io_req_find_next(req, nxtptr);
+               nxt = io_req_find_next(req);
                __io_free_req(req);
        }
+       return nxt;
 }
 
 static void io_put_req(struct io_kiocb *req)
@@ -1649,24 +1817,26 @@ static void io_put_req(struct io_kiocb *req)
                io_free_req(req);
 }
 
-static void io_steal_work(struct io_kiocb *req,
-                         struct io_wq_work **workptr)
+static struct io_wq_work *io_steal_work(struct io_kiocb *req)
 {
+       struct io_kiocb *timeout, *nxt = NULL;
+
        /*
-        * It's in an io-wq worker, so there always should be at least
-        * one reference, which will be dropped in io_put_work() just
-        * after the current handler returns.
-        *
-        * It also means, that if the counter dropped to 1, then there is
-        * no asynchronous users left, so it's safe to steal the next work.
+        * A ref is owned by io-wq in which context we're. So, if that's the
+        * last one, it's safe to steal next work. False negatives are Ok,
+        * it just will be re-punted async in io_put_work()
         */
-       if (refcount_read(&req->refs) == 1) {
-               struct io_kiocb *nxt = NULL;
+       if (refcount_read(&req->refs) != 1)
+               return NULL;
 
-               io_req_find_next(req, &nxt);
-               if (nxt)
-                       io_wq_assign_next(workptr, nxt);
-       }
+       nxt = io_req_find_next(req);
+       if (!nxt)
+               return NULL;
+
+       timeout = io_prep_linked_timeout(nxt);
+       if (timeout)
+               nxt->flags |= REQ_F_QUEUE_TIMEOUT;
+       return &nxt->work;
 }
 
 /*
@@ -1716,20 +1886,6 @@ static inline unsigned int io_sqring_entries(struct io_ring_ctx *ctx)
        return smp_load_acquire(&rings->sq.tail) - ctx->cached_sq_head;
 }
 
-static inline bool io_req_multi_free(struct req_batch *rb, struct io_kiocb *req)
-{
-       if ((req->flags & REQ_F_LINK_HEAD) || io_is_fallback_req(req))
-               return false;
-
-       if (req->file || req->io)
-               rb->need_iter++;
-
-       rb->reqs[rb->to_free++] = req;
-       if (unlikely(rb->to_free == ARRAY_SIZE(rb->reqs)))
-               io_free_req_many(req->ctx, rb);
-       return true;
-}
-
 static int io_put_kbuf(struct io_kiocb *req)
 {
        struct io_buffer *kbuf;
@@ -1745,21 +1901,13 @@ static int io_put_kbuf(struct io_kiocb *req)
 
 static void io_iopoll_queue(struct list_head *again)
 {
-       struct io_kiocb *req;
-
-       do {
-               req = list_first_entry(again, struct io_kiocb, list);
-               list_del(&req->list);
-
-               /* shouldn't happen unless io_uring is dying, cancel reqs */
-               if (unlikely(!current->mm)) {
-                       io_complete_rw_common(&req->rw.kiocb, -EAGAIN);
-                       io_put_req(req);
-                       continue;
-               }
+       struct io_kiocb *req;
 
-               refcount_inc(&req->refs);
-               io_queue_async_work(req);
+       do {
+               req = list_first_entry(again, struct io_kiocb, list);
+               list_del(&req->list);
+               if (!io_rw_reissue(req, -EAGAIN))
+                       io_complete_rw_common(&req->rw.kiocb, -EAGAIN, NULL);
        } while (!list_empty(again));
 }
 
@@ -1776,7 +1924,7 @@ static void io_iopoll_complete(struct io_ring_ctx *ctx, unsigned int *nr_events,
        /* order with ->result store in io_complete_rw_iopoll() */
        smp_rmb();
 
-       rb.to_free = rb.need_iter = 0;
+       rb.to_free = 0;
        while (!list_empty(done)) {
                int cflags = 0;
 
@@ -1794,15 +1942,14 @@ static void io_iopoll_complete(struct io_ring_ctx *ctx, unsigned int *nr_events,
                __io_cqring_fill_event(req, req->result, cflags);
                (*nr_events)++;
 
-               if (refcount_dec_and_test(&req->refs) &&
-                   !io_req_multi_free(&rb, req))
-                       io_free_req(req);
+               if (refcount_dec_and_test(&req->refs))
+                       io_req_free_batch(&rb, req);
        }
 
        io_commit_cqring(ctx);
        if (ctx->flags & IORING_SETUP_SQPOLL)
                io_cqring_ev_posted(ctx);
-       io_free_req_many(ctx, &rb);
+       io_req_free_batch_finish(ctx, &rb);
 
        if (!list_empty(&again))
                io_iopoll_queue(&again);
@@ -1932,6 +2079,8 @@ static int io_iopoll_check(struct io_ring_ctx *ctx, unsigned *nr_events,
                 */
                if (!(++iters & 7)) {
                        mutex_unlock(&ctx->uring_lock);
+                       if (current->task_works)
+                               task_work_run();
                        mutex_lock(&ctx->uring_lock);
                }
 
@@ -1962,13 +2111,8 @@ static void kiocb_end_write(struct io_kiocb *req)
        file_end_write(req->file);
 }
 
-static inline void req_set_fail_links(struct io_kiocb *req)
-{
-       if ((req->flags & (REQ_F_LINK | REQ_F_HARDLINK)) == REQ_F_LINK)
-               req->flags |= REQ_F_FAIL_LINK;
-}
-
-static void io_complete_rw_common(struct kiocb *kiocb, long res)
+static void io_complete_rw_common(struct kiocb *kiocb, long res,
+                                 struct io_comp_state *cs)
 {
        struct io_kiocb *req = container_of(kiocb, struct io_kiocb, rw.kiocb);
        int cflags = 0;
@@ -1980,15 +2124,101 @@ static void io_complete_rw_common(struct kiocb *kiocb, long res)
                req_set_fail_links(req);
        if (req->flags & REQ_F_BUFFER_SELECTED)
                cflags = io_put_kbuf(req);
-       __io_cqring_add_event(req, res, cflags);
+       __io_req_complete(req, res, cflags, cs);
+}
+
+#ifdef CONFIG_BLOCK
+static bool io_resubmit_prep(struct io_kiocb *req, int error)
+{
+       struct iovec inline_vecs[UIO_FASTIOV], *iovec = inline_vecs;
+       ssize_t ret = -ECANCELED;
+       struct iov_iter iter;
+       int rw;
+
+       if (error) {
+               ret = error;
+               goto end_req;
+       }
+
+       switch (req->opcode) {
+       case IORING_OP_READV:
+       case IORING_OP_READ_FIXED:
+       case IORING_OP_READ:
+               rw = READ;
+               break;
+       case IORING_OP_WRITEV:
+       case IORING_OP_WRITE_FIXED:
+       case IORING_OP_WRITE:
+               rw = WRITE;
+               break;
+       default:
+               printk_once(KERN_WARNING "io_uring: bad opcode in resubmit %d\n",
+                               req->opcode);
+               goto end_req;
+       }
+
+       ret = io_import_iovec(rw, req, &iovec, &iter, false);
+       if (ret < 0)
+               goto end_req;
+       ret = io_setup_async_rw(req, ret, iovec, inline_vecs, &iter);
+       if (!ret)
+               return true;
+       kfree(iovec);
+end_req:
+       req_set_fail_links(req);
+       io_req_complete(req, ret);
+       return false;
+}
+
+static void io_rw_resubmit(struct callback_head *cb)
+{
+       struct io_kiocb *req = container_of(cb, struct io_kiocb, task_work);
+       struct io_ring_ctx *ctx = req->ctx;
+       int err;
+
+       __set_current_state(TASK_RUNNING);
+
+       err = io_sq_thread_acquire_mm(ctx, req);
+
+       if (io_resubmit_prep(req, err)) {
+               refcount_inc(&req->refs);
+               io_queue_async_work(req);
+       }
+}
+#endif
+
+static bool io_rw_reissue(struct io_kiocb *req, long res)
+{
+#ifdef CONFIG_BLOCK
+       struct task_struct *tsk;
+       int ret;
+
+       if ((res != -EAGAIN && res != -EOPNOTSUPP) || io_wq_current_is_worker())
+               return false;
+
+       tsk = req->task;
+       init_task_work(&req->task_work, io_rw_resubmit);
+       ret = task_work_add(tsk, &req->task_work, true);
+       if (!ret) {
+               wake_up_process(tsk);
+               return true;
+       }
+#endif
+       return false;
+}
+
+static void __io_complete_rw(struct io_kiocb *req, long res, long res2,
+                            struct io_comp_state *cs)
+{
+       if (!io_rw_reissue(req, res))
+               io_complete_rw_common(&req->rw.kiocb, res, cs);
 }
 
 static void io_complete_rw(struct kiocb *kiocb, long res, long res2)
 {
        struct io_kiocb *req = container_of(kiocb, struct io_kiocb, rw.kiocb);
 
-       io_complete_rw_common(kiocb, res);
-       io_put_req(req);
+       __io_complete_rw(req, res, res2, NULL);
 }
 
 static void io_complete_rw_iopoll(struct kiocb *kiocb, long res, long res2)
@@ -2091,6 +2321,15 @@ static struct file *__io_file_get(struct io_submit_state *state, int fd)
        return state->file;
 }
 
+static bool io_bdev_nowait(struct block_device *bdev)
+{
+#ifdef CONFIG_BLOCK
+       return !bdev || queue_is_mq(bdev_get_queue(bdev));
+#else
+       return true;
+#endif
+}
+
 /*
  * If we tracked the file through the SCM inflight mechanism, we could support
  * any file. For now, just ensure that anything potentially problematic is done
@@ -2100,10 +2339,19 @@ static bool io_file_supports_async(struct file *file, int rw)
 {
        umode_t mode = file_inode(file)->i_mode;
 
-       if (S_ISBLK(mode) || S_ISCHR(mode) || S_ISSOCK(mode))
-               return true;
-       if (S_ISREG(mode) && file->f_op != &io_uring_fops)
+       if (S_ISBLK(mode)) {
+               if (io_bdev_nowait(file->f_inode->i_bdev))
+                       return true;
+               return false;
+       }
+       if (S_ISCHR(mode) || S_ISSOCK(mode))
                return true;
+       if (S_ISREG(mode)) {
+               if (io_bdev_nowait(file->f_inode->i_sb->s_bdev) &&
+                   file->f_op != &io_uring_fops)
+                       return true;
+               return false;
+       }
 
        /* any ->read/write should understand O_NONBLOCK */
        if (file->f_flags & O_NONBLOCK)
@@ -2154,6 +2402,9 @@ static int io_prep_rw(struct io_kiocb *req, const struct io_uring_sqe *sqe,
        if (kiocb->ki_flags & IOCB_NOWAIT)
                req->flags |= REQ_F_NOWAIT;
 
+       if (kiocb->ki_flags & IOCB_DIRECT)
+               io_get_req_task(req);
+
        if (force_nonblock)
                kiocb->ki_flags |= IOCB_NOWAIT;
 
@@ -2164,8 +2415,8 @@ static int io_prep_rw(struct io_kiocb *req, const struct io_uring_sqe *sqe,
 
                kiocb->ki_flags |= IOCB_HIPRI;
                kiocb->ki_complete = io_complete_rw_iopoll;
-               req->result = 0;
                req->iopoll_completed = 0;
+               io_get_req_task(req);
        } else {
                if (kiocb->ki_flags & IOCB_HIPRI)
                        return -EINVAL;
@@ -2199,14 +2450,15 @@ static inline void io_rw_done(struct kiocb *kiocb, ssize_t ret)
        }
 }
 
-static void kiocb_done(struct kiocb *kiocb, ssize_t ret)
+static void kiocb_done(struct kiocb *kiocb, ssize_t ret,
+                      struct io_comp_state *cs)
 {
        struct io_kiocb *req = container_of(kiocb, struct io_kiocb, rw.kiocb);
 
        if (req->flags & REQ_F_CUR_POS)
                req->file->f_pos = kiocb->ki_pos;
        if (ret >= 0 && kiocb->ki_complete == io_complete_rw)
-               io_complete_rw(kiocb, ret, 0);
+               __io_complete_rw(req, ret, 0, cs);
        else
                io_rw_done(kiocb, ret);
 }
@@ -2622,7 +2874,105 @@ static int io_read_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe,
        return 0;
 }
 
-static int io_read(struct io_kiocb *req, bool force_nonblock)
+static void io_async_buf_cancel(struct callback_head *cb)
+{
+       struct io_async_rw *rw;
+       struct io_kiocb *req;
+
+       rw = container_of(cb, struct io_async_rw, task_work);
+       req = rw->wpq.wait.private;
+       __io_req_task_cancel(req, -ECANCELED);
+}
+
+static void io_async_buf_retry(struct callback_head *cb)
+{
+       struct io_async_rw *rw;
+       struct io_kiocb *req;
+
+       rw = container_of(cb, struct io_async_rw, task_work);
+       req = rw->wpq.wait.private;
+
+       __io_req_task_submit(req);
+}
+
+static int io_async_buf_func(struct wait_queue_entry *wait, unsigned mode,
+                            int sync, void *arg)
+{
+       struct wait_page_queue *wpq;
+       struct io_kiocb *req = wait->private;
+       struct io_async_rw *rw = &req->io->rw;
+       struct wait_page_key *key = arg;
+       struct task_struct *tsk;
+       int ret;
+
+       wpq = container_of(wait, struct wait_page_queue, wait);
+
+       ret = wake_page_match(wpq, key);
+       if (ret != 1)
+               return ret;
+
+       list_del_init(&wait->entry);
+
+       init_task_work(&rw->task_work, io_async_buf_retry);
+       /* submit ref gets dropped, acquire a new one */
+       refcount_inc(&req->refs);
+       tsk = req->task;
+       ret = task_work_add(tsk, &rw->task_work, true);
+       if (unlikely(ret)) {
+               /* queue just for cancelation */
+               init_task_work(&rw->task_work, io_async_buf_cancel);
+               tsk = io_wq_get_task(req->ctx->io_wq);
+               task_work_add(tsk, &rw->task_work, true);
+       }
+       wake_up_process(tsk);
+       return 1;
+}
+
+static bool io_rw_should_retry(struct io_kiocb *req)
+{
+       struct kiocb *kiocb = &req->rw.kiocb;
+       int ret;
+
+       /* never retry for NOWAIT, we just complete with -EAGAIN */
+       if (req->flags & REQ_F_NOWAIT)
+               return false;
+
+       /* already tried, or we're doing O_DIRECT */
+       if (kiocb->ki_flags & (IOCB_DIRECT | IOCB_WAITQ))
+               return false;
+       /*
+        * just use poll if we can, and don't attempt if the fs doesn't
+        * support callback based unlocks
+        */
+       if (file_can_poll(req->file) || !(req->file->f_mode & FMODE_BUF_RASYNC))
+               return false;
+
+       /*
+        * If request type doesn't require req->io to defer in general,
+        * we need to allocate it here
+        */
+       if (!req->io && __io_alloc_async_ctx(req))
+               return false;
+
+       ret = kiocb_wait_page_queue_init(kiocb, &req->io->rw.wpq,
+                                               io_async_buf_func, req);
+       if (!ret) {
+               io_get_req_task(req);
+               return true;
+       }
+
+       return false;
+}
+
+static int io_iter_do_read(struct io_kiocb *req, struct iov_iter *iter)
+{
+       if (req->file->f_op->read_iter)
+               return call_read_iter(req->file, &req->rw.kiocb, iter);
+       return loop_rw_iter(READ, req->file, &req->rw.kiocb, iter);
+}
+
+static int io_read(struct io_kiocb *req, bool force_nonblock,
+                  struct io_comp_state *cs)
 {
        struct iovec inline_vecs[UIO_FASTIOV], *iovec = inline_vecs;
        struct kiocb *kiocb = &req->rw.kiocb;
@@ -2638,41 +2988,43 @@ static int io_read(struct io_kiocb *req, bool force_nonblock)
        if (!force_nonblock)
                kiocb->ki_flags &= ~IOCB_NOWAIT;
 
-       req->result = 0;
        io_size = ret;
-       if (req->flags & REQ_F_LINK_HEAD)
-               req->result = io_size;
+       req->result = io_size;
 
-       /*
-        * If the file doesn't support async, mark it as REQ_F_MUST_PUNT so
-        * we know to async punt it even if it was opened O_NONBLOCK
-        */
+       /* If the file doesn't support async, just async punt */
        if (force_nonblock && !io_file_supports_async(req->file, READ))
                goto copy_iov;
 
        iov_count = iov_iter_count(&iter);
        ret = rw_verify_area(READ, req->file, &kiocb->ki_pos, iov_count);
        if (!ret) {
-               ssize_t ret2;
+               unsigned long nr_segs = iter.nr_segs;
+               ssize_t ret2 = 0;
 
-               if (req->file->f_op->read_iter)
-                       ret2 = call_read_iter(req->file, kiocb, &iter);
-               else
-                       ret2 = loop_rw_iter(READ, req->file, kiocb, &iter);
+               ret2 = io_iter_do_read(req, &iter);
 
                /* Catch -EAGAIN return for forced non-blocking submission */
-               if (!force_nonblock || ret2 != -EAGAIN) {
-                       kiocb_done(kiocb, ret2);
+               if (!force_nonblock || (ret2 != -EAGAIN && ret2 != -EIO)) {
+                       kiocb_done(kiocb, ret2, cs);
                } else {
+                       iter.count = iov_count;
+                       iter.nr_segs = nr_segs;
 copy_iov:
                        ret = io_setup_async_rw(req, io_size, iovec,
                                                inline_vecs, &iter);
                        if (ret)
                                goto out_free;
-                       /* any defer here is final, must blocking retry */
-                       if (!(req->flags & REQ_F_NOWAIT) &&
-                           !file_can_poll(req->file))
-                               req->flags |= REQ_F_MUST_PUNT;
+                       /* if we can retry, do so with the callbacks armed */
+                       if (io_rw_should_retry(req)) {
+                               ret2 = io_iter_do_read(req, &iter);
+                               if (ret2 == -EIOCBQUEUED) {
+                                       goto out_free;
+                               } else if (ret2 != -EAGAIN) {
+                                       kiocb_done(kiocb, ret2, cs);
+                                       goto out_free;
+                               }
+                       }
+                       kiocb->ki_flags &= ~IOCB_WAITQ;
                        return -EAGAIN;
                }
        }
@@ -2714,7 +3066,8 @@ static int io_write_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe,
        return 0;
 }
 
-static int io_write(struct io_kiocb *req, bool force_nonblock)
+static int io_write(struct io_kiocb *req, bool force_nonblock,
+                   struct io_comp_state *cs)
 {
        struct iovec inline_vecs[UIO_FASTIOV], *iovec = inline_vecs;
        struct kiocb *kiocb = &req->rw.kiocb;
@@ -2730,15 +3083,10 @@ static int io_write(struct io_kiocb *req, bool force_nonblock)
        if (!force_nonblock)
                req->rw.kiocb.ki_flags &= ~IOCB_NOWAIT;
 
-       req->result = 0;
        io_size = ret;
-       if (req->flags & REQ_F_LINK_HEAD)
-               req->result = io_size;
+       req->result = io_size;
 
-       /*
-        * If the file doesn't support async, mark it as REQ_F_MUST_PUNT so
-        * we know to async punt it even if it was opened O_NONBLOCK
-        */
+       /* If the file doesn't support async, just async punt */
        if (force_nonblock && !io_file_supports_async(req->file, WRITE))
                goto copy_iov;
 
@@ -2750,6 +3098,7 @@ static int io_write(struct io_kiocb *req, bool force_nonblock)
        iov_count = iov_iter_count(&iter);
        ret = rw_verify_area(WRITE, req->file, &kiocb->ki_pos, iov_count);
        if (!ret) {
+               unsigned long nr_segs = iter.nr_segs;
                ssize_t ret2;
 
                /*
@@ -2785,17 +3134,15 @@ static int io_write(struct io_kiocb *req, bool force_nonblock)
                if (ret2 == -EOPNOTSUPP && (kiocb->ki_flags & IOCB_NOWAIT))
                        ret2 = -EAGAIN;
                if (!force_nonblock || ret2 != -EAGAIN) {
-                       kiocb_done(kiocb, ret2);
+                       kiocb_done(kiocb, ret2, cs);
                } else {
+                       iter.count = iov_count;
+                       iter.nr_segs = nr_segs;
 copy_iov:
                        ret = io_setup_async_rw(req, io_size, iovec,
                                                inline_vecs, &iter);
                        if (ret)
                                goto out_free;
-                       /* any defer here is final, must blocking retry */
-                       if (!(req->flags & REQ_F_NOWAIT) &&
-                           !file_can_poll(req->file))
-                               req->flags |= REQ_F_MUST_PUNT;
                        return -EAGAIN;
                }
        }
@@ -2866,10 +3213,9 @@ static int io_tee(struct io_kiocb *req, bool force_nonblock)
        io_put_file(req, in, (sp->flags & SPLICE_F_FD_IN_FIXED));
        req->flags &= ~REQ_F_NEED_CLEANUP;
 
-       io_cqring_add_event(req, ret);
        if (ret != sp->len)
                req_set_fail_links(req);
-       io_put_req(req);
+       io_req_complete(req, ret);
        return 0;
 }
 
@@ -2903,25 +3249,23 @@ static int io_splice(struct io_kiocb *req, bool force_nonblock)
        io_put_file(req, in, (sp->flags & SPLICE_F_FD_IN_FIXED));
        req->flags &= ~REQ_F_NEED_CLEANUP;
 
-       io_cqring_add_event(req, ret);
        if (ret != sp->len)
                req_set_fail_links(req);
-       io_put_req(req);
+       io_req_complete(req, ret);
        return 0;
 }
 
 /*
  * IORING_OP_NOP just posts a completion event, nothing else.
  */
-static int io_nop(struct io_kiocb *req)
+static int io_nop(struct io_kiocb *req, struct io_comp_state *cs)
 {
        struct io_ring_ctx *ctx = req->ctx;
 
        if (unlikely(ctx->flags & IORING_SETUP_IOPOLL))
                return -EINVAL;
 
-       io_cqring_add_event(req, 0);
-       io_put_req(req);
+       __io_req_complete(req, 0, 0, cs);
        return 0;
 }
 
@@ -2960,8 +3304,7 @@ static int io_fsync(struct io_kiocb *req, bool force_nonblock)
                                req->sync.flags & IORING_FSYNC_DATASYNC);
        if (ret < 0)
                req_set_fail_links(req);
-       io_cqring_add_event(req, ret);
-       io_put_req(req);
+       io_req_complete(req, ret);
        return 0;
 }
 
@@ -2994,8 +3337,7 @@ static int io_fallocate(struct io_kiocb *req, bool force_nonblock)
        current->signal->rlim[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
        if (ret < 0)
                req_set_fail_links(req);
-       io_cqring_add_event(req, ret);
-       io_put_req(req);
+       io_req_complete(req, ret);
        return 0;
 }
 
@@ -3091,8 +3433,7 @@ err:
        req->flags &= ~REQ_F_NEED_CLEANUP;
        if (ret < 0)
                req_set_fail_links(req);
-       io_cqring_add_event(req, ret);
-       io_put_req(req);
+       io_req_complete(req, ret);
        return 0;
 }
 
@@ -3146,7 +3487,8 @@ static int __io_remove_buffers(struct io_ring_ctx *ctx, struct io_buffer *buf,
        return i;
 }
 
-static int io_remove_buffers(struct io_kiocb *req, bool force_nonblock)
+static int io_remove_buffers(struct io_kiocb *req, bool force_nonblock,
+                            struct io_comp_state *cs)
 {
        struct io_provide_buf *p = &req->pbuf;
        struct io_ring_ctx *ctx = req->ctx;
@@ -3165,8 +3507,7 @@ static int io_remove_buffers(struct io_kiocb *req, bool force_nonblock)
        io_ring_submit_lock(ctx, !force_nonblock);
        if (ret < 0)
                req_set_fail_links(req);
-       io_cqring_add_event(req, ret);
-       io_put_req(req);
+       __io_req_complete(req, ret, 0, cs);
        return 0;
 }
 
@@ -3224,7 +3565,8 @@ static int io_add_buffers(struct io_provide_buf *pbuf, struct io_buffer **head)
        return i ? i : -ENOMEM;
 }
 
-static int io_provide_buffers(struct io_kiocb *req, bool force_nonblock)
+static int io_provide_buffers(struct io_kiocb *req, bool force_nonblock,
+                             struct io_comp_state *cs)
 {
        struct io_provide_buf *p = &req->pbuf;
        struct io_ring_ctx *ctx = req->ctx;
@@ -3253,8 +3595,7 @@ out:
        io_ring_submit_unlock(ctx, !force_nonblock);
        if (ret < 0)
                req_set_fail_links(req);
-       io_cqring_add_event(req, ret);
-       io_put_req(req);
+       __io_req_complete(req, ret, 0, cs);
        return 0;
 }
 
@@ -3285,7 +3626,8 @@ static int io_epoll_ctl_prep(struct io_kiocb *req,
 #endif
 }
 
-static int io_epoll_ctl(struct io_kiocb *req, bool force_nonblock)
+static int io_epoll_ctl(struct io_kiocb *req, bool force_nonblock,
+                       struct io_comp_state *cs)
 {
 #if defined(CONFIG_EPOLL)
        struct io_epoll *ie = &req->epoll;
@@ -3297,8 +3639,7 @@ static int io_epoll_ctl(struct io_kiocb *req, bool force_nonblock)
 
        if (ret < 0)
                req_set_fail_links(req);
-       io_cqring_add_event(req, ret);
-       io_put_req(req);
+       __io_req_complete(req, ret, 0, cs);
        return 0;
 #else
        return -EOPNOTSUPP;
@@ -3334,8 +3675,7 @@ static int io_madvise(struct io_kiocb *req, bool force_nonblock)
        ret = do_madvise(ma->addr, ma->len, ma->advice);
        if (ret < 0)
                req_set_fail_links(req);
-       io_cqring_add_event(req, ret);
-       io_put_req(req);
+       io_req_complete(req, ret);
        return 0;
 #else
        return -EOPNOTSUPP;
@@ -3374,8 +3714,7 @@ static int io_fadvise(struct io_kiocb *req, bool force_nonblock)
        ret = vfs_fadvise(req->file, fa->offset, fa->len, fa->advice);
        if (ret < 0)
                req_set_fail_links(req);
-       io_cqring_add_event(req, ret);
-       io_put_req(req);
+       io_req_complete(req, ret);
        return 0;
 }
 
@@ -3414,8 +3753,7 @@ static int io_statx(struct io_kiocb *req, bool force_nonblock)
 
        if (ret < 0)
                req_set_fail_links(req);
-       io_cqring_add_event(req, ret);
-       io_put_req(req);
+       io_req_complete(req, ret);
        return 0;
 }
 
@@ -3446,7 +3784,8 @@ static int io_close_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
        return 0;
 }
 
-static int io_close(struct io_kiocb *req, bool force_nonblock)
+static int io_close(struct io_kiocb *req, bool force_nonblock,
+                   struct io_comp_state *cs)
 {
        struct io_close *close = &req->close;
        int ret;
@@ -3460,8 +3799,10 @@ static int io_close(struct io_kiocb *req, bool force_nonblock)
 
        /* if the file has a flush method, be safe and punt to async */
        if (close->put_file->f_op->flush && force_nonblock) {
+               /* was never set, but play safe */
+               req->flags &= ~REQ_F_NOWAIT;
                /* avoid grabbing files - we don't need the files */
-               req->flags |= REQ_F_NO_FILE_TABLE | REQ_F_MUST_PUNT;
+               req->flags |= REQ_F_NO_FILE_TABLE;
                return -EAGAIN;
        }
 
@@ -3469,10 +3810,9 @@ static int io_close(struct io_kiocb *req, bool force_nonblock)
        ret = filp_close(close->put_file, req->work.files);
        if (ret < 0)
                req_set_fail_links(req);
-       io_cqring_add_event(req, ret);
        fput(close->put_file);
        close->put_file = NULL;
-       io_put_req(req);
+       __io_req_complete(req, ret, 0, cs);
        return 0;
 }
 
@@ -3506,8 +3846,7 @@ static int io_sync_file_range(struct io_kiocb *req, bool force_nonblock)
                                req->sync.flags);
        if (ret < 0)
                req_set_fail_links(req);
-       io_cqring_add_event(req, ret);
-       io_put_req(req);
+       io_req_complete(req, ret);
        return 0;
 }
 
@@ -3559,7 +3898,8 @@ static int io_sendmsg_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
        return ret;
 }
 
-static int io_sendmsg(struct io_kiocb *req, bool force_nonblock)
+static int io_sendmsg(struct io_kiocb *req, bool force_nonblock,
+                     struct io_comp_state *cs)
 {
        struct io_async_msghdr *kmsg = NULL;
        struct socket *sock;
@@ -3606,14 +3946,14 @@ static int io_sendmsg(struct io_kiocb *req, bool force_nonblock)
        if (kmsg && kmsg->iov != kmsg->fast_iov)
                kfree(kmsg->iov);
        req->flags &= ~REQ_F_NEED_CLEANUP;
-       io_cqring_add_event(req, ret);
        if (ret < 0)
                req_set_fail_links(req);
-       io_put_req(req);
+       __io_req_complete(req, ret, 0, cs);
        return 0;
 }
 
-static int io_send(struct io_kiocb *req, bool force_nonblock)
+static int io_send(struct io_kiocb *req, bool force_nonblock,
+                  struct io_comp_state *cs)
 {
        struct socket *sock;
        int ret;
@@ -3649,10 +3989,9 @@ static int io_send(struct io_kiocb *req, bool force_nonblock)
                        ret = -EINTR;
        }
 
-       io_cqring_add_event(req, ret);
        if (ret < 0)
                req_set_fail_links(req);
-       io_put_req(req);
+       __io_req_complete(req, ret, 0, cs);
        return 0;
 }
 
@@ -3795,7 +4134,8 @@ static int io_recvmsg_prep(struct io_kiocb *req,
        return ret;
 }
 
-static int io_recvmsg(struct io_kiocb *req, bool force_nonblock)
+static int io_recvmsg(struct io_kiocb *req, bool force_nonblock,
+                     struct io_comp_state *cs)
 {
        struct io_async_msghdr *kmsg = NULL;
        struct socket *sock;
@@ -3849,14 +4189,14 @@ static int io_recvmsg(struct io_kiocb *req, bool force_nonblock)
        if (kmsg && kmsg->iov != kmsg->fast_iov)
                kfree(kmsg->iov);
        req->flags &= ~REQ_F_NEED_CLEANUP;
-       __io_cqring_add_event(req, ret, cflags);
        if (ret < 0)
                req_set_fail_links(req);
-       io_put_req(req);
+       __io_req_complete(req, ret, cflags, cs);
        return 0;
 }
 
-static int io_recv(struct io_kiocb *req, bool force_nonblock)
+static int io_recv(struct io_kiocb *req, bool force_nonblock,
+                  struct io_comp_state *cs)
 {
        struct io_buffer *kbuf = NULL;
        struct socket *sock;
@@ -3906,10 +4246,9 @@ static int io_recv(struct io_kiocb *req, bool force_nonblock)
 
        kfree(kbuf);
        req->flags &= ~REQ_F_NEED_CLEANUP;
-       __io_cqring_add_event(req, ret, cflags);
        if (ret < 0)
                req_set_fail_links(req);
-       io_put_req(req);
+       __io_req_complete(req, ret, cflags, cs);
        return 0;
 }
 
@@ -3929,7 +4268,8 @@ static int io_accept_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
        return 0;
 }
 
-static int io_accept(struct io_kiocb *req, bool force_nonblock)
+static int io_accept(struct io_kiocb *req, bool force_nonblock,
+                    struct io_comp_state *cs)
 {
        struct io_accept *accept = &req->accept;
        unsigned int file_flags = force_nonblock ? O_NONBLOCK : 0;
@@ -3948,8 +4288,7 @@ static int io_accept(struct io_kiocb *req, bool force_nonblock)
                        ret = -EINTR;
                req_set_fail_links(req);
        }
-       io_cqring_add_event(req, ret);
-       io_put_req(req);
+       __io_req_complete(req, ret, 0, cs);
        return 0;
 }
 
@@ -3973,7 +4312,8 @@ static int io_connect_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
                                        &io->connect.address);
 }
 
-static int io_connect(struct io_kiocb *req, bool force_nonblock)
+static int io_connect(struct io_kiocb *req, bool force_nonblock,
+                     struct io_comp_state *cs)
 {
        struct io_async_ctx __io, *io;
        unsigned file_flags;
@@ -4009,8 +4349,7 @@ static int io_connect(struct io_kiocb *req, bool force_nonblock)
 out:
        if (ret < 0)
                req_set_fail_links(req);
-       io_cqring_add_event(req, ret);
-       io_put_req(req);
+       __io_req_complete(req, ret, 0, cs);
        return 0;
 }
 #else /* !CONFIG_NET */
@@ -4019,12 +4358,14 @@ static int io_sendmsg_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
        return -EOPNOTSUPP;
 }
 
-static int io_sendmsg(struct io_kiocb *req, bool force_nonblock)
+static int io_sendmsg(struct io_kiocb *req, bool force_nonblock,
+                     struct io_comp_state *cs)
 {
        return -EOPNOTSUPP;
 }
 
-static int io_send(struct io_kiocb *req, bool force_nonblock)
+static int io_send(struct io_kiocb *req, bool force_nonblock,
+                  struct io_comp_state *cs)
 {
        return -EOPNOTSUPP;
 }
@@ -4035,12 +4376,14 @@ static int io_recvmsg_prep(struct io_kiocb *req,
        return -EOPNOTSUPP;
 }
 
-static int io_recvmsg(struct io_kiocb *req, bool force_nonblock)
+static int io_recvmsg(struct io_kiocb *req, bool force_nonblock,
+                     struct io_comp_state *cs)
 {
        return -EOPNOTSUPP;
 }
 
-static int io_recv(struct io_kiocb *req, bool force_nonblock)
+static int io_recv(struct io_kiocb *req, bool force_nonblock,
+                  struct io_comp_state *cs)
 {
        return -EOPNOTSUPP;
 }
@@ -4050,7 +4393,8 @@ static int io_accept_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
        return -EOPNOTSUPP;
 }
 
-static int io_accept(struct io_kiocb *req, bool force_nonblock)
+static int io_accept(struct io_kiocb *req, bool force_nonblock,
+                    struct io_comp_state *cs)
 {
        return -EOPNOTSUPP;
 }
@@ -4060,7 +4404,8 @@ static int io_connect_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
        return -EOPNOTSUPP;
 }
 
-static int io_connect(struct io_kiocb *req, bool force_nonblock)
+static int io_connect(struct io_kiocb *req, bool force_nonblock,
+                     struct io_comp_state *cs)
 {
        return -EOPNOTSUPP;
 }
@@ -4188,7 +4533,7 @@ static void io_poll_task_handler(struct io_kiocb *req, struct io_kiocb **nxt)
        hash_del(&req->hash_node);
        io_poll_complete(req, req->result, 0);
        req->flags |= REQ_F_COMP_LOCKED;
-       io_put_req_find_next(req, nxt);
+       *nxt = io_put_req_find_next(req);
        spin_unlock_irq(&ctx->completion_lock);
 
        io_cqring_ev_posted(ctx);
@@ -4200,13 +4545,8 @@ static void io_poll_task_func(struct callback_head *cb)
        struct io_kiocb *nxt = NULL;
 
        io_poll_task_handler(req, &nxt);
-       if (nxt) {
-               struct io_ring_ctx *ctx = nxt->ctx;
-
-               mutex_lock(&ctx->uring_lock);
-               __io_queue_sqe(nxt, NULL);
-               mutex_unlock(&ctx->uring_lock);
-       }
+       if (nxt)
+               __io_req_task_submit(nxt);
 }
 
 static int io_poll_double_wake(struct wait_queue_entry *wait, unsigned mode,
@@ -4275,7 +4615,11 @@ static void __io_queue_proc(struct io_poll_iocb *poll, struct io_poll_table *pt,
 
        pt->error = 0;
        poll->head = head;
-       add_wait_queue(head, &poll->wait);
+
+       if (poll->events & EPOLLEXCLUSIVE)
+               add_wait_queue_exclusive(head, &poll->wait);
+       else
+               add_wait_queue(head, &poll->wait);
 }
 
 static void io_async_queue_proc(struct file *file, struct wait_queue_head *head,
@@ -4286,34 +4630,11 @@ static void io_async_queue_proc(struct file *file, struct wait_queue_head *head,
        __io_queue_proc(&pt->req->apoll->poll, pt, head);
 }
 
-static void io_sq_thread_drop_mm(struct io_ring_ctx *ctx)
-{
-       struct mm_struct *mm = current->mm;
-
-       if (mm) {
-               kthread_unuse_mm(mm);
-               mmput(mm);
-       }
-}
-
-static int io_sq_thread_acquire_mm(struct io_ring_ctx *ctx,
-                                  struct io_kiocb *req)
-{
-       if (io_op_defs[req->opcode].needs_mm && !current->mm) {
-               if (unlikely(!mmget_not_zero(ctx->sqo_mm)))
-                       return -EFAULT;
-               kthread_use_mm(ctx->sqo_mm);
-       }
-
-       return 0;
-}
-
 static void io_async_task_func(struct callback_head *cb)
 {
        struct io_kiocb *req = container_of(cb, struct io_kiocb, task_work);
        struct async_poll *apoll = req->apoll;
        struct io_ring_ctx *ctx = req->ctx;
-       bool canceled = false;
 
        trace_io_uring_task_run(req->ctx, req->opcode, req->user_data);
 
@@ -4323,15 +4644,8 @@ static void io_async_task_func(struct callback_head *cb)
        }
 
        /* If req is still hashed, it cannot have been canceled. Don't check. */
-       if (hash_hashed(&req->hash_node)) {
+       if (hash_hashed(&req->hash_node))
                hash_del(&req->hash_node);
-       } else {
-               canceled = READ_ONCE(apoll->poll.canceled);
-               if (canceled) {
-                       io_cqring_fill_event(req, -ECANCELED);
-                       io_commit_cqring(ctx);
-               }
-       }
 
        spin_unlock_irq(&ctx->completion_lock);
 
@@ -4340,21 +4654,10 @@ static void io_async_task_func(struct callback_head *cb)
                memcpy(&req->work, &apoll->work, sizeof(req->work));
        kfree(apoll);
 
-       if (!canceled) {
-               __set_current_state(TASK_RUNNING);
-               if (io_sq_thread_acquire_mm(ctx, req)) {
-                       io_cqring_add_event(req, -EFAULT);
-                       goto end_req;
-               }
-               mutex_lock(&ctx->uring_lock);
-               __io_queue_sqe(req, NULL);
-               mutex_unlock(&ctx->uring_lock);
-       } else {
-               io_cqring_ev_posted(ctx);
-end_req:
-               req_set_fail_links(req);
-               io_double_put_req(req);
-       }
+       if (!READ_ONCE(apoll->poll.canceled))
+               __io_req_task_submit(req);
+       else
+               __io_req_task_cancel(req, -ECANCELED);
 }
 
 static int io_async_wake(struct wait_queue_entry *wait, unsigned mode, int sync,
@@ -4387,8 +4690,8 @@ static __poll_t __io_arm_poll_handler(struct io_kiocb *req,
        struct io_ring_ctx *ctx = req->ctx;
        bool cancel = false;
 
-       poll->file = req->file;
        io_init_poll_iocb(poll, mask, wake_func);
+       poll->file = req->file;
        poll->wait.private = req;
 
        ipt->pt._key = mask;
@@ -4429,7 +4732,7 @@ static bool io_arm_poll_handler(struct io_kiocb *req)
 
        if (!req->file || !file_can_poll(req->file))
                return false;
-       if (req->flags & (REQ_F_MUST_PUNT | REQ_F_POLLED))
+       if (req->flags & REQ_F_POLLED)
                return false;
        if (!def->pollin && !def->pollout)
                return false;
@@ -4592,10 +4895,9 @@ static int io_poll_remove(struct io_kiocb *req)
        ret = io_poll_cancel(ctx, addr);
        spin_unlock_irq(&ctx->completion_lock);
 
-       io_cqring_add_event(req, ret);
        if (ret < 0)
                req_set_fail_links(req);
-       io_put_req(req);
+       io_req_complete(req, ret);
        return 0;
 }
 
@@ -4619,7 +4921,7 @@ static void io_poll_queue_proc(struct file *file, struct wait_queue_head *head,
 static int io_poll_add_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
 {
        struct io_poll_iocb *poll = &req->poll;
-       u16 events;
+       u32 events;
 
        if (unlikely(req->ctx->flags & IORING_SETUP_IOPOLL))
                return -EINVAL;
@@ -4628,8 +4930,12 @@ static int io_poll_add_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe
        if (!poll->file)
                return -EBADF;
 
-       events = READ_ONCE(sqe->poll_events);
-       poll->events = demangle_poll(events) | EPOLLERR | EPOLLHUP;
+       events = READ_ONCE(sqe->poll32_events);
+#ifdef __BIG_ENDIAN
+       events = swahw32(events);
+#endif
+       poll->events = demangle_poll(events) | EPOLLERR | EPOLLHUP |
+                      (events & EPOLLEXCLUSIVE);
 
        io_get_req_task(req);
        return 0;
@@ -4777,7 +5083,6 @@ static int io_timeout_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe,
 
        data = &req->io->timeout;
        data->req = req;
-       req->flags |= REQ_F_TIMEOUT;
 
        if (get_timespec64(&data->ts, u64_to_user_ptr(sqe->addr)))
                return -EFAULT;
@@ -4805,8 +5110,7 @@ static int io_timeout(struct io_kiocb *req)
         * timeout event to be satisfied. If it isn't set, then this is
         * a pure timeout request, sequence isn't used.
         */
-       if (!off) {
-               req->flags |= REQ_F_TIMEOUT_NOSEQ;
+       if (io_is_timeout_noseq(req)) {
                entry = ctx->timeout_list.prev;
                goto add;
        }
@@ -4821,7 +5125,7 @@ static int io_timeout(struct io_kiocb *req)
        list_for_each_prev(entry, &ctx->timeout_list) {
                struct io_kiocb *nxt = list_entry(entry, struct io_kiocb, list);
 
-               if (nxt->flags & REQ_F_TIMEOUT_NOSEQ)
+               if (io_is_timeout_noseq(nxt))
                        continue;
                /* nxt.seq is behind @tail, otherwise would've been completed */
                if (off >= nxt->timeout.target_seq - tail)
@@ -4929,7 +5233,8 @@ static int io_files_update_prep(struct io_kiocb *req,
        return 0;
 }
 
-static int io_files_update(struct io_kiocb *req, bool force_nonblock)
+static int io_files_update(struct io_kiocb *req, bool force_nonblock,
+                          struct io_comp_state *cs)
 {
        struct io_ring_ctx *ctx = req->ctx;
        struct io_uring_files_update up;
@@ -4947,8 +5252,7 @@ static int io_files_update(struct io_kiocb *req, bool force_nonblock)
 
        if (ret < 0)
                req_set_fail_links(req);
-       io_cqring_add_event(req, ret);
-       io_put_req(req);
+       __io_req_complete(req, ret, 0, cs);
        return 0;
 }
 
@@ -4960,16 +5264,13 @@ static int io_req_defer_prep(struct io_kiocb *req,
        if (!sqe)
                return 0;
 
-       io_req_init_async(req);
-
        if (io_op_defs[req->opcode].file_table) {
+               io_req_init_async(req);
                ret = io_grab_files(req);
                if (unlikely(ret))
                        return ret;
        }
 
-       io_req_work_grab_env(req, &io_op_defs[req->opcode]);
-
        switch (req->opcode) {
        case IORING_OP_NOP:
                break;
@@ -5086,6 +5387,7 @@ static int io_req_defer(struct io_kiocb *req, const struct io_uring_sqe *sqe)
                if (ret < 0)
                        return ret;
        }
+       io_prep_async_link(req);
 
        spin_lock_irq(&ctx->completion_lock);
        if (!req_need_defer(req) && list_empty(&ctx->defer_list)) {
@@ -5142,14 +5444,14 @@ static void io_cleanup_req(struct io_kiocb *req)
 }
 
 static int io_issue_sqe(struct io_kiocb *req, const struct io_uring_sqe *sqe,
-                       bool force_nonblock)
+                       bool force_nonblock, struct io_comp_state *cs)
 {
        struct io_ring_ctx *ctx = req->ctx;
        int ret;
 
        switch (req->opcode) {
        case IORING_OP_NOP:
-               ret = io_nop(req);
+               ret = io_nop(req, cs);
                break;
        case IORING_OP_READV:
        case IORING_OP_READ_FIXED:
@@ -5159,7 +5461,7 @@ static int io_issue_sqe(struct io_kiocb *req, const struct io_uring_sqe *sqe,
                        if (ret < 0)
                                break;
                }
-               ret = io_read(req, force_nonblock);
+               ret = io_read(req, force_nonblock, cs);
                break;
        case IORING_OP_WRITEV:
        case IORING_OP_WRITE_FIXED:
@@ -5169,7 +5471,7 @@ static int io_issue_sqe(struct io_kiocb *req, const struct io_uring_sqe *sqe,
                        if (ret < 0)
                                break;
                }
-               ret = io_write(req, force_nonblock);
+               ret = io_write(req, force_nonblock, cs);
                break;
        case IORING_OP_FSYNC:
                if (sqe) {
@@ -5211,9 +5513,9 @@ static int io_issue_sqe(struct io_kiocb *req, const struct io_uring_sqe *sqe,
                                break;
                }
                if (req->opcode == IORING_OP_SENDMSG)
-                       ret = io_sendmsg(req, force_nonblock);
+                       ret = io_sendmsg(req, force_nonblock, cs);
                else
-                       ret = io_send(req, force_nonblock);
+                       ret = io_send(req, force_nonblock, cs);
                break;
        case IORING_OP_RECVMSG:
        case IORING_OP_RECV:
@@ -5223,9 +5525,9 @@ static int io_issue_sqe(struct io_kiocb *req, const struct io_uring_sqe *sqe,
                                break;
                }
                if (req->opcode == IORING_OP_RECVMSG)
-                       ret = io_recvmsg(req, force_nonblock);
+                       ret = io_recvmsg(req, force_nonblock, cs);
                else
-                       ret = io_recv(req, force_nonblock);
+                       ret = io_recv(req, force_nonblock, cs);
                break;
        case IORING_OP_TIMEOUT:
                if (sqe) {
@@ -5249,7 +5551,7 @@ static int io_issue_sqe(struct io_kiocb *req, const struct io_uring_sqe *sqe,
                        if (ret)
                                break;
                }
-               ret = io_accept(req, force_nonblock);
+               ret = io_accept(req, force_nonblock, cs);
                break;
        case IORING_OP_CONNECT:
                if (sqe) {
@@ -5257,7 +5559,7 @@ static int io_issue_sqe(struct io_kiocb *req, const struct io_uring_sqe *sqe,
                        if (ret)
                                break;
                }
-               ret = io_connect(req, force_nonblock);
+               ret = io_connect(req, force_nonblock, cs);
                break;
        case IORING_OP_ASYNC_CANCEL:
                if (sqe) {
@@ -5289,7 +5591,7 @@ static int io_issue_sqe(struct io_kiocb *req, const struct io_uring_sqe *sqe,
                        if (ret)
                                break;
                }
-               ret = io_close(req, force_nonblock);
+               ret = io_close(req, force_nonblock, cs);
                break;
        case IORING_OP_FILES_UPDATE:
                if (sqe) {
@@ -5297,7 +5599,7 @@ static int io_issue_sqe(struct io_kiocb *req, const struct io_uring_sqe *sqe,
                        if (ret)
                                break;
                }
-               ret = io_files_update(req, force_nonblock);
+               ret = io_files_update(req, force_nonblock, cs);
                break;
        case IORING_OP_STATX:
                if (sqe) {
@@ -5337,7 +5639,7 @@ static int io_issue_sqe(struct io_kiocb *req, const struct io_uring_sqe *sqe,
                        if (ret)
                                break;
                }
-               ret = io_epoll_ctl(req, force_nonblock);
+               ret = io_epoll_ctl(req, force_nonblock, cs);
                break;
        case IORING_OP_SPLICE:
                if (sqe) {
@@ -5353,7 +5655,7 @@ static int io_issue_sqe(struct io_kiocb *req, const struct io_uring_sqe *sqe,
                        if (ret)
                                break;
                }
-               ret = io_provide_buffers(req, force_nonblock);
+               ret = io_provide_buffers(req, force_nonblock, cs);
                break;
        case IORING_OP_REMOVE_BUFFERS:
                if (sqe) {
@@ -5361,7 +5663,7 @@ static int io_issue_sqe(struct io_kiocb *req, const struct io_uring_sqe *sqe,
                        if (ret)
                                break;
                }
-               ret = io_remove_buffers(req, force_nonblock);
+               ret = io_remove_buffers(req, force_nonblock, cs);
                break;
        case IORING_OP_TEE:
                if (sqe) {
@@ -5408,9 +5710,8 @@ static void io_arm_async_linked_timeout(struct io_kiocb *req)
        io_queue_linked_timeout(link);
 }
 
-static void io_wq_submit_work(struct io_wq_work **workptr)
+static struct io_wq_work *io_wq_submit_work(struct io_wq_work *work)
 {
-       struct io_wq_work *work = *workptr;
        struct io_kiocb *req = container_of(work, struct io_kiocb, work);
        int ret = 0;
 
@@ -5424,7 +5725,7 @@ static void io_wq_submit_work(struct io_wq_work **workptr)
 
        if (!ret) {
                do {
-                       ret = io_issue_sqe(req, NULL, false);
+                       ret = io_issue_sqe(req, NULL, false, NULL);
                        /*
                         * We can get EAGAIN for polled IO even though we're
                         * forcing a sync submission from here, since we can't
@@ -5438,11 +5739,10 @@ static void io_wq_submit_work(struct io_wq_work **workptr)
 
        if (ret) {
                req_set_fail_links(req);
-               io_cqring_add_event(req, ret);
-               io_put_req(req);
+               io_req_complete(req, ret);
        }
 
-       io_steal_work(req, workptr);
+       return io_steal_work(req);
 }
 
 static inline struct file *io_file_from_index(struct io_ring_ctx *ctx,
@@ -5556,8 +5856,7 @@ static enum hrtimer_restart io_link_timeout_fn(struct hrtimer *timer)
                io_async_find_and_cancel(ctx, req, prev->user_data, -ETIME);
                io_put_req(prev);
        } else {
-               io_cqring_add_event(req, -ETIME);
-               io_put_req(req);
+               io_req_complete(req, -ETIME);
        }
        return HRTIMER_NORESTART;
 }
@@ -5603,7 +5902,8 @@ static struct io_kiocb *io_prep_linked_timeout(struct io_kiocb *req)
        return nxt;
 }
 
-static void __io_queue_sqe(struct io_kiocb *req, const struct io_uring_sqe *sqe)
+static void __io_queue_sqe(struct io_kiocb *req, const struct io_uring_sqe *sqe,
+                          struct io_comp_state *cs)
 {
        struct io_kiocb *linked_timeout;
        struct io_kiocb *nxt;
@@ -5623,14 +5923,13 @@ again:
                        old_creds = override_creds(req->work.creds);
        }
 
-       ret = io_issue_sqe(req, sqe, true);
+       ret = io_issue_sqe(req, sqe, true, cs);
 
        /*
         * We async punt it if the file wasn't marked NOWAIT, or if the file
         * doesn't support non-blocking read/write attempts
         */
-       if (ret == -EAGAIN && (!(req->flags & REQ_F_NOWAIT) ||
-           (req->flags & REQ_F_MUST_PUNT))) {
+       if (ret == -EAGAIN && !(req->flags & REQ_F_NOWAIT)) {
                if (io_arm_poll_handler(req)) {
                        if (linked_timeout)
                                io_queue_linked_timeout(linked_timeout);
@@ -5654,9 +5953,8 @@ punt:
        }
 
 err:
-       nxt = NULL;
        /* drop submission reference */
-       io_put_req_find_next(req, &nxt);
+       nxt = io_put_req_find_next(req);
 
        if (linked_timeout) {
                if (!ret)
@@ -5667,9 +5965,8 @@ err:
 
        /* and drop final reference, if we failed */
        if (ret) {
-               io_cqring_add_event(req, ret);
                req_set_fail_links(req);
-               io_put_req(req);
+               io_req_complete(req, ret);
        }
        if (nxt) {
                req = nxt;
@@ -5683,7 +5980,8 @@ exit:
                revert_creds(old_creds);
 }
 
-static void io_queue_sqe(struct io_kiocb *req, const struct io_uring_sqe *sqe)
+static void io_queue_sqe(struct io_kiocb *req, const struct io_uring_sqe *sqe,
+                        struct io_comp_state *cs)
 {
        int ret;
 
@@ -5691,9 +5989,9 @@ static void io_queue_sqe(struct io_kiocb *req, const struct io_uring_sqe *sqe)
        if (ret) {
                if (ret != -EIOCBQUEUED) {
 fail_req:
-                       io_cqring_add_event(req, ret);
                        req_set_fail_links(req);
-                       io_double_put_req(req);
+                       io_put_req(req);
+                       io_req_complete(req, ret);
                }
        } else if (req->flags & REQ_F_FORCE_ASYNC) {
                if (!req->io) {
@@ -5712,21 +6010,22 @@ fail_req:
                req->work.flags |= IO_WQ_WORK_CONCURRENT;
                io_queue_async_work(req);
        } else {
-               __io_queue_sqe(req, sqe);
+               __io_queue_sqe(req, sqe, cs);
        }
 }
 
-static inline void io_queue_link_head(struct io_kiocb *req)
+static inline void io_queue_link_head(struct io_kiocb *req,
+                                     struct io_comp_state *cs)
 {
        if (unlikely(req->flags & REQ_F_FAIL_LINK)) {
-               io_cqring_add_event(req, -ECANCELED);
-               io_double_put_req(req);
+               io_put_req(req);
+               io_req_complete(req, -ECANCELED);
        } else
-               io_queue_sqe(req, NULL);
+               io_queue_sqe(req, NULL, cs);
 }
 
 static int io_submit_sqe(struct io_kiocb *req, const struct io_uring_sqe *sqe,
-                        struct io_kiocb **link)
+                        struct io_kiocb **link, struct io_comp_state *cs)
 {
        struct io_ring_ctx *ctx = req->ctx;
        int ret;
@@ -5762,11 +6061,12 @@ static int io_submit_sqe(struct io_kiocb *req, const struct io_uring_sqe *sqe,
                        return ret;
                }
                trace_io_uring_link(ctx, req, head);
+               io_get_req_task(req);
                list_add_tail(&req->link_list, &head->link_list);
 
                /* last request of a link, enqueue the link */
                if (!(req->flags & (REQ_F_LINK | REQ_F_HARDLINK))) {
-                       io_queue_link_head(head);
+                       io_queue_link_head(head, cs);
                        *link = NULL;
                }
        } else {
@@ -5786,7 +6086,7 @@ static int io_submit_sqe(struct io_kiocb *req, const struct io_uring_sqe *sqe,
                                req->flags |= REQ_F_FAIL_LINK;
                        *link = req;
                } else {
-                       io_queue_sqe(req, sqe);
+                       io_queue_sqe(req, sqe, cs);
                }
        }
 
@@ -5798,6 +6098,8 @@ static int io_submit_sqe(struct io_kiocb *req, const struct io_uring_sqe *sqe,
  */
 static void io_submit_state_end(struct io_submit_state *state)
 {
+       if (!list_empty(&state->comp.list))
+               io_submit_flush_completions(&state->comp);
        blk_finish_plug(&state->plug);
        io_state_file_put(state);
        if (state->free_reqs)
@@ -5808,9 +6110,15 @@ static void io_submit_state_end(struct io_submit_state *state)
  * Start submission side cache.
  */
 static void io_submit_state_start(struct io_submit_state *state,
-                                 unsigned int max_ios)
+                                 struct io_ring_ctx *ctx, unsigned int max_ios)
 {
        blk_start_plug(&state->plug);
+#ifdef CONFIG_BLOCK
+       state->plug.nowait = true;
+#endif
+       state->comp.nr = 0;
+       INIT_LIST_HEAD(&state->comp.list);
+       state->comp.ctx = ctx;
        state->free_reqs = 0;
        state->file = NULL;
        state->ios_left = max_ios;
@@ -5928,7 +6236,7 @@ static int io_init_req(struct io_ring_ctx *ctx, struct io_kiocb *req,
 static int io_submit_sqes(struct io_ring_ctx *ctx, unsigned int nr,
                          struct file *ring_file, int ring_fd)
 {
-       struct io_submit_state state, *statep = NULL;
+       struct io_submit_state state;
        struct io_kiocb *link = NULL;
        int i, submitted = 0;
 
@@ -5945,10 +6253,7 @@ static int io_submit_sqes(struct io_ring_ctx *ctx, unsigned int nr,
        if (!percpu_ref_tryget_many(&ctx->refs, nr))
                return -EAGAIN;
 
-       if (nr > IO_PLUG_THRESHOLD) {
-               io_submit_state_start(&state, nr);
-               statep = &state;
-       }
+       io_submit_state_start(&state, ctx, nr);
 
        ctx->ring_fd = ring_fd;
        ctx->ring_file = ring_file;
@@ -5963,28 +6268,28 @@ static int io_submit_sqes(struct io_ring_ctx *ctx, unsigned int nr,
                        io_consume_sqe(ctx);
                        break;
                }
-               req = io_alloc_req(ctx, statep);
+               req = io_alloc_req(ctx, &state);
                if (unlikely(!req)) {
                        if (!submitted)
                                submitted = -EAGAIN;
                        break;
                }
 
-               err = io_init_req(ctx, req, sqe, statep);
+               err = io_init_req(ctx, req, sqe, &state);
                io_consume_sqe(ctx);
                /* will complete beyond this point, count as submitted */
                submitted++;
 
                if (unlikely(err)) {
 fail_req:
-                       io_cqring_add_event(req, err);
-                       io_double_put_req(req);
+                       io_put_req(req);
+                       io_req_complete(req, err);
                        break;
                }
 
                trace_io_uring_submit_sqe(ctx, req->opcode, req->user_data,
                                                true, io_async_submit(ctx));
-               err = io_submit_sqe(req, sqe, &link);
+               err = io_submit_sqe(req, sqe, &link, &state.comp);
                if (err)
                        goto fail_req;
        }
@@ -5995,9 +6300,8 @@ fail_req:
                percpu_ref_put_many(&ctx->refs, nr - ref_used);
        }
        if (link)
-               io_queue_link_head(link);
-       if (statep)
-               io_submit_state_end(&state);
+               io_queue_link_head(link, &state.comp);
+       io_submit_state_end(&state);
 
         /* Commit SQ ring head once we've consumed and submitted all SQEs */
        io_commit_sqring(ctx);
@@ -6943,10 +7247,10 @@ static int io_sq_offload_start(struct io_ring_ctx *ctx,
 {
        int ret;
 
-       mmgrab(current->mm);
-       ctx->sqo_mm = current->mm;
-
        if (ctx->flags & IORING_SETUP_SQPOLL) {
+               mmgrab(current->mm);
+               ctx->sqo_mm = current->mm;
+
                ret = -EPERM;
                if (!capable(CAP_SYS_ADMIN))
                        goto err;
@@ -6990,17 +7294,21 @@ static int io_sq_offload_start(struct io_ring_ctx *ctx,
        return 0;
 err:
        io_finish_async(ctx);
-       mmdrop(ctx->sqo_mm);
-       ctx->sqo_mm = NULL;
+       if (ctx->sqo_mm) {
+               mmdrop(ctx->sqo_mm);
+               ctx->sqo_mm = NULL;
+       }
        return ret;
 }
 
-static void io_unaccount_mem(struct user_struct *user, unsigned long nr_pages)
+static inline void __io_unaccount_mem(struct user_struct *user,
+                                     unsigned long nr_pages)
 {
        atomic_long_sub(nr_pages, &user->locked_vm);
 }
 
-static int io_account_mem(struct user_struct *user, unsigned long nr_pages)
+static inline int __io_account_mem(struct user_struct *user,
+                                  unsigned long nr_pages)
 {
        unsigned long page_limit, cur_pages, new_pages;
 
@@ -7018,6 +7326,41 @@ static int io_account_mem(struct user_struct *user, unsigned long nr_pages)
        return 0;
 }
 
+static void io_unaccount_mem(struct io_ring_ctx *ctx, unsigned long nr_pages,
+                            enum io_mem_account acct)
+{
+       if (ctx->limit_mem)
+               __io_unaccount_mem(ctx->user, nr_pages);
+
+       if (ctx->sqo_mm) {
+               if (acct == ACCT_LOCKED)
+                       ctx->sqo_mm->locked_vm -= nr_pages;
+               else if (acct == ACCT_PINNED)
+                       atomic64_sub(nr_pages, &ctx->sqo_mm->pinned_vm);
+       }
+}
+
+static int io_account_mem(struct io_ring_ctx *ctx, unsigned long nr_pages,
+                         enum io_mem_account acct)
+{
+       int ret;
+
+       if (ctx->limit_mem) {
+               ret = __io_account_mem(ctx->user, nr_pages);
+               if (ret)
+                       return ret;
+       }
+
+       if (ctx->sqo_mm) {
+               if (acct == ACCT_LOCKED)
+                       ctx->sqo_mm->locked_vm += nr_pages;
+               else if (acct == ACCT_PINNED)
+                       atomic64_add(nr_pages, &ctx->sqo_mm->pinned_vm);
+       }
+
+       return 0;
+}
+
 static void io_mem_free(void *ptr)
 {
        struct page *page;
@@ -7092,8 +7435,7 @@ static int io_sqe_buffer_unregister(struct io_ring_ctx *ctx)
                for (j = 0; j < imu->nr_bvecs; j++)
                        unpin_user_page(imu->bvec[j].bv_page);
 
-               if (ctx->account_mem)
-                       io_unaccount_mem(ctx->user, imu->nr_bvecs);
+               io_unaccount_mem(ctx, imu->nr_bvecs, ACCT_PINNED);
                kvfree(imu->bvec);
                imu->nr_bvecs = 0;
        }
@@ -7176,11 +7518,9 @@ static int io_sqe_buffer_register(struct io_ring_ctx *ctx, void __user *arg,
                start = ubuf >> PAGE_SHIFT;
                nr_pages = end - start;
 
-               if (ctx->account_mem) {
-                       ret = io_account_mem(ctx->user, nr_pages);
-                       if (ret)
-                               goto err;
-               }
+               ret = io_account_mem(ctx, nr_pages, ACCT_PINNED);
+               if (ret)
+                       goto err;
 
                ret = 0;
                if (!pages || nr_pages > got_pages) {
@@ -7193,8 +7533,7 @@ static int io_sqe_buffer_register(struct io_ring_ctx *ctx, void __user *arg,
                                        GFP_KERNEL);
                        if (!pages || !vmas) {
                                ret = -ENOMEM;
-                               if (ctx->account_mem)
-                                       io_unaccount_mem(ctx->user, nr_pages);
+                               io_unaccount_mem(ctx, nr_pages, ACCT_PINNED);
                                goto err;
                        }
                        got_pages = nr_pages;
@@ -7204,8 +7543,7 @@ static int io_sqe_buffer_register(struct io_ring_ctx *ctx, void __user *arg,
                                                GFP_KERNEL);
                ret = -ENOMEM;
                if (!imu->bvec) {
-                       if (ctx->account_mem)
-                               io_unaccount_mem(ctx->user, nr_pages);
+                       io_unaccount_mem(ctx, nr_pages, ACCT_PINNED);
                        goto err;
                }
 
@@ -7236,8 +7574,7 @@ static int io_sqe_buffer_register(struct io_ring_ctx *ctx, void __user *arg,
                         */
                        if (pret > 0)
                                unpin_user_pages(pages, pret);
-                       if (ctx->account_mem)
-                               io_unaccount_mem(ctx->user, nr_pages);
+                       io_unaccount_mem(ctx, nr_pages, ACCT_PINNED);
                        kvfree(imu->bvec);
                        goto err;
                }
@@ -7321,8 +7658,10 @@ static void io_destroy_buffers(struct io_ring_ctx *ctx)
 static void io_ring_ctx_free(struct io_ring_ctx *ctx)
 {
        io_finish_async(ctx);
-       if (ctx->sqo_mm)
+       if (ctx->sqo_mm) {
                mmdrop(ctx->sqo_mm);
+               ctx->sqo_mm = NULL;
+       }
 
        io_iopoll_reap_events(ctx);
        io_sqe_buffer_unregister(ctx);
@@ -7342,9 +7681,8 @@ static void io_ring_ctx_free(struct io_ring_ctx *ctx)
        io_mem_free(ctx->sq_sqes);
 
        percpu_ref_exit(&ctx->refs);
-       if (ctx->account_mem)
-               io_unaccount_mem(ctx->user,
-                               ring_pages(ctx->sq_entries, ctx->cq_entries));
+       io_unaccount_mem(ctx, ring_pages(ctx->sq_entries, ctx->cq_entries),
+                        ACCT_LOCKED);
        free_uid(ctx->user);
        put_cred(ctx->creds);
        kfree(ctx->cancel_hash);
@@ -7872,7 +8210,7 @@ static int io_uring_create(unsigned entries, struct io_uring_params *p,
 {
        struct user_struct *user = NULL;
        struct io_ring_ctx *ctx;
-       bool account_mem;
+       bool limit_mem;
        int ret;
 
        if (!entries)
@@ -7911,10 +8249,10 @@ static int io_uring_create(unsigned entries, struct io_uring_params *p,
        }
 
        user = get_uid(current_user());
-       account_mem = !capable(CAP_IPC_LOCK);
+       limit_mem = !capable(CAP_IPC_LOCK);
 
-       if (account_mem) {
-               ret = io_account_mem(user,
+       if (limit_mem) {
+               ret = __io_account_mem(user,
                                ring_pages(p->sq_entries, p->cq_entries));
                if (ret) {
                        free_uid(user);
@@ -7924,14 +8262,13 @@ static int io_uring_create(unsigned entries, struct io_uring_params *p,
 
        ctx = io_ring_ctx_alloc(p);
        if (!ctx) {
-               if (account_mem)
-                       io_unaccount_mem(user, ring_pages(p->sq_entries,
+               if (limit_mem)
+                       __io_unaccount_mem(user, ring_pages(p->sq_entries,
                                                                p->cq_entries));
                free_uid(user);
                return -ENOMEM;
        }
        ctx->compat = in_compat_syscall();
-       ctx->account_mem = account_mem;
        ctx->user = user;
        ctx->creds = get_current_cred();
 
@@ -7963,7 +8300,8 @@ static int io_uring_create(unsigned entries, struct io_uring_params *p,
 
        p->features = IORING_FEAT_SINGLE_MMAP | IORING_FEAT_NODROP |
                        IORING_FEAT_SUBMIT_STABLE | IORING_FEAT_RW_CUR_POS |
-                       IORING_FEAT_CUR_PERSONALITY | IORING_FEAT_FAST_POLL;
+                       IORING_FEAT_CUR_PERSONALITY | IORING_FEAT_FAST_POLL |
+                       IORING_FEAT_POLL_32BITS;
 
        if (copy_to_user(params, p, sizeof(*p))) {
                ret = -EFAULT;
@@ -7978,6 +8316,9 @@ static int io_uring_create(unsigned entries, struct io_uring_params *p,
                goto err;
 
        trace_io_uring_create(ret, ctx, p->sq_entries, p->cq_entries, p->flags);
+       io_account_mem(ctx, ring_pages(p->sq_entries, p->cq_entries),
+                      ACCT_LOCKED);
+       ctx->limit_mem = limit_mem;
        return ret;
 err:
        io_ring_ctx_wait_and_kill(ctx);
@@ -8252,7 +8593,8 @@ static int __init io_uring_init(void)
        BUILD_BUG_SQE_ELEM(28, /* compat */   int, rw_flags);
        BUILD_BUG_SQE_ELEM(28, /* compat */ __u32, rw_flags);
        BUILD_BUG_SQE_ELEM(28, __u32,  fsync_flags);
-       BUILD_BUG_SQE_ELEM(28, __u16,  poll_events);
+       BUILD_BUG_SQE_ELEM(28, /* compat */ __u16,  poll_events);
+       BUILD_BUG_SQE_ELEM(28, __u32,  poll32_events);
        BUILD_BUG_SQE_ELEM(28, __u32,  sync_range_flags);
        BUILD_BUG_SQE_ELEM(28, __u32,  msg_flags);
        BUILD_BUG_SQE_ELEM(28, __u32,  timeout_flags);