io_uring: fix NULL-mm for linked reqs
authorPavel Begunkov <asml.silence@gmail.com>
Thu, 25 Jun 2020 09:38:13 +0000 (12:38 +0300)
committerJens Axboe <axboe@kernel.dk>
Thu, 25 Jun 2020 13:22:38 +0000 (07:22 -0600)
__io_queue_sqe() tries to handle all request of a link,
so it's not enough to grab mm in io_sq_thread_acquire_mm()
based just on the head.

Don't check req->needs_mm and do it always.

Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
fs/io_uring.c

index c686061..7273918 100644 (file)
@@ -1991,10 +1991,9 @@ static void io_sq_thread_drop_mm(struct io_ring_ctx *ctx)
        }
 }
 
-static int io_sq_thread_acquire_mm(struct io_ring_ctx *ctx,
-                                  struct io_kiocb *req)
+static int __io_sq_thread_acquire_mm(struct io_ring_ctx *ctx)
 {
-       if (io_op_defs[req->opcode].needs_mm && !current->mm) {
+       if (!current->mm) {
                if (unlikely(!mmget_not_zero(ctx->sqo_mm)))
                        return -EFAULT;
                kthread_use_mm(ctx->sqo_mm);
@@ -2003,6 +2002,14 @@ static int io_sq_thread_acquire_mm(struct io_ring_ctx *ctx,
        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);
+}
+
 #ifdef CONFIG_BLOCK
 static bool io_resubmit_prep(struct io_kiocb *req, int error)
 {
@@ -2781,7 +2788,7 @@ static void io_async_buf_retry(struct callback_head *cb)
        ctx = req->ctx;
 
        __set_current_state(TASK_RUNNING);
-       if (!io_sq_thread_acquire_mm(ctx, req)) {
+       if (!__io_sq_thread_acquire_mm(ctx)) {
                mutex_lock(&ctx->uring_lock);
                __io_queue_sqe(req, NULL);
                mutex_unlock(&ctx->uring_lock);