Commit 0baca070 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'io_uring-5.9-2020-09-22' of git://git.kernel.dk/linux-block

Pull io_uring fixes from Jens Axboe:
 "A few fixes - most of them regression fixes from this cycle, but also
  a few stable heading fixes, and a build fix for the included demo tool
  since some systems now actually have gettid() available"

* tag 'io_uring-5.9-2020-09-22' of git://git.kernel.dk/linux-block:
  io_uring: fix openat/openat2 unified prep handling
  io_uring: mark statx/files_update/epoll_ctl as non-SQPOLL
  tools/io_uring: fix compile breakage
  io_uring: don't use retry based buffered reads for non-async bdev
  io_uring: don't re-setup vecs/iter in io_resumit_prep() is already there
  io_uring: don't run task work on an exiting task
  io_uring: drop 'ctx' ref on task work cancelation
  io_uring: grab any needed state during defer prep
parents c37b7189 4eb8dded
...@@ -1753,6 +1753,9 @@ static int io_req_task_work_add(struct io_kiocb *req, struct callback_head *cb, ...@@ -1753,6 +1753,9 @@ static int io_req_task_work_add(struct io_kiocb *req, struct callback_head *cb,
struct io_ring_ctx *ctx = req->ctx; struct io_ring_ctx *ctx = req->ctx;
int ret, notify; int ret, notify;
if (tsk->flags & PF_EXITING)
return -ESRCH;
/* /*
* SQPOLL kernel thread doesn't need notification, just a wakeup. For * SQPOLL kernel thread doesn't need notification, just a wakeup. For
* all other cases, use TWA_SIGNAL unconditionally to ensure we're * all other cases, use TWA_SIGNAL unconditionally to ensure we're
...@@ -1787,8 +1790,10 @@ static void __io_req_task_cancel(struct io_kiocb *req, int error) ...@@ -1787,8 +1790,10 @@ static void __io_req_task_cancel(struct io_kiocb *req, int error)
static void io_req_task_cancel(struct callback_head *cb) static void io_req_task_cancel(struct callback_head *cb)
{ {
struct io_kiocb *req = container_of(cb, struct io_kiocb, task_work); struct io_kiocb *req = container_of(cb, struct io_kiocb, task_work);
struct io_ring_ctx *ctx = req->ctx;
__io_req_task_cancel(req, -ECANCELED); __io_req_task_cancel(req, -ECANCELED);
percpu_ref_put(&ctx->refs);
} }
static void __io_req_task_submit(struct io_kiocb *req) static void __io_req_task_submit(struct io_kiocb *req)
...@@ -2010,6 +2015,12 @@ static inline unsigned int io_put_rw_kbuf(struct io_kiocb *req) ...@@ -2010,6 +2015,12 @@ static inline unsigned int io_put_rw_kbuf(struct io_kiocb *req)
static inline bool io_run_task_work(void) static inline bool io_run_task_work(void)
{ {
/*
* Not safe to run on exiting task, and the task_work handling will
* not add work to such a task.
*/
if (unlikely(current->flags & PF_EXITING))
return false;
if (current->task_works) { if (current->task_works) {
__set_current_state(TASK_RUNNING); __set_current_state(TASK_RUNNING);
task_work_run(); task_work_run();
...@@ -2283,6 +2294,7 @@ static bool io_resubmit_prep(struct io_kiocb *req, int error) ...@@ -2283,6 +2294,7 @@ static bool io_resubmit_prep(struct io_kiocb *req, int error)
goto end_req; goto end_req;
} }
if (!req->io) {
ret = io_import_iovec(rw, req, &iovec, &iter, false); ret = io_import_iovec(rw, req, &iovec, &iter, false);
if (ret < 0) if (ret < 0)
goto end_req; goto end_req;
...@@ -2290,6 +2302,9 @@ static bool io_resubmit_prep(struct io_kiocb *req, int error) ...@@ -2290,6 +2302,9 @@ static bool io_resubmit_prep(struct io_kiocb *req, int error)
if (!ret) if (!ret)
return true; return true;
kfree(iovec); kfree(iovec);
} else {
return true;
}
end_req: end_req:
req_set_fail_links(req); req_set_fail_links(req);
io_req_complete(req, ret); io_req_complete(req, ret);
...@@ -3115,6 +3130,7 @@ static int io_read(struct io_kiocb *req, bool force_nonblock, ...@@ -3115,6 +3130,7 @@ static int io_read(struct io_kiocb *req, bool force_nonblock,
struct iov_iter __iter, *iter = &__iter; struct iov_iter __iter, *iter = &__iter;
ssize_t io_size, ret, ret2; ssize_t io_size, ret, ret2;
size_t iov_count; size_t iov_count;
bool no_async;
if (req->io) if (req->io)
iter = &req->io->rw.iter; iter = &req->io->rw.iter;
...@@ -3132,7 +3148,8 @@ static int io_read(struct io_kiocb *req, bool force_nonblock, ...@@ -3132,7 +3148,8 @@ static int io_read(struct io_kiocb *req, bool force_nonblock,
kiocb->ki_flags &= ~IOCB_NOWAIT; kiocb->ki_flags &= ~IOCB_NOWAIT;
/* If the file doesn't support async, just async punt */ /* If the file doesn't support async, just async punt */
if (force_nonblock && !io_file_supports_async(req->file, READ)) no_async = force_nonblock && !io_file_supports_async(req->file, READ);
if (no_async)
goto copy_iov; goto copy_iov;
ret = rw_verify_area(READ, req->file, io_kiocb_ppos(kiocb), iov_count); ret = rw_verify_area(READ, req->file, io_kiocb_ppos(kiocb), iov_count);
...@@ -3176,6 +3193,8 @@ static int io_read(struct io_kiocb *req, bool force_nonblock, ...@@ -3176,6 +3193,8 @@ static int io_read(struct io_kiocb *req, bool force_nonblock,
ret = ret2; ret = ret2;
goto out_free; goto out_free;
} }
if (no_async)
return -EAGAIN;
/* it's copied and will be cleaned with ->io */ /* it's copied and will be cleaned with ->io */
iovec = NULL; iovec = NULL;
/* now use our persistent iterator, if we aren't already */ /* now use our persistent iterator, if we aren't already */
...@@ -3508,8 +3527,6 @@ static int __io_openat_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe ...@@ -3508,8 +3527,6 @@ static int __io_openat_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe
const char __user *fname; const char __user *fname;
int ret; int ret;
if (unlikely(req->ctx->flags & (IORING_SETUP_IOPOLL|IORING_SETUP_SQPOLL)))
return -EINVAL;
if (unlikely(sqe->ioprio || sqe->buf_index)) if (unlikely(sqe->ioprio || sqe->buf_index))
return -EINVAL; return -EINVAL;
if (unlikely(req->flags & REQ_F_FIXED_FILE)) if (unlikely(req->flags & REQ_F_FIXED_FILE))
...@@ -3536,6 +3553,8 @@ static int io_openat_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) ...@@ -3536,6 +3553,8 @@ static int io_openat_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
{ {
u64 flags, mode; u64 flags, mode;
if (unlikely(req->ctx->flags & (IORING_SETUP_IOPOLL|IORING_SETUP_SQPOLL)))
return -EINVAL;
if (req->flags & REQ_F_NEED_CLEANUP) if (req->flags & REQ_F_NEED_CLEANUP)
return 0; return 0;
mode = READ_ONCE(sqe->len); mode = READ_ONCE(sqe->len);
...@@ -3550,6 +3569,8 @@ static int io_openat2_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) ...@@ -3550,6 +3569,8 @@ static int io_openat2_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
size_t len; size_t len;
int ret; int ret;
if (unlikely(req->ctx->flags & (IORING_SETUP_IOPOLL|IORING_SETUP_SQPOLL)))
return -EINVAL;
if (req->flags & REQ_F_NEED_CLEANUP) if (req->flags & REQ_F_NEED_CLEANUP)
return 0; return 0;
how = u64_to_user_ptr(READ_ONCE(sqe->addr2)); how = u64_to_user_ptr(READ_ONCE(sqe->addr2));
...@@ -3767,7 +3788,7 @@ static int io_epoll_ctl_prep(struct io_kiocb *req, ...@@ -3767,7 +3788,7 @@ static int io_epoll_ctl_prep(struct io_kiocb *req,
#if defined(CONFIG_EPOLL) #if defined(CONFIG_EPOLL)
if (sqe->ioprio || sqe->buf_index) if (sqe->ioprio || sqe->buf_index)
return -EINVAL; return -EINVAL;
if (unlikely(req->ctx->flags & IORING_SETUP_IOPOLL)) if (unlikely(req->ctx->flags & (IORING_SETUP_IOPOLL | IORING_SETUP_SQPOLL)))
return -EINVAL; return -EINVAL;
req->epoll.epfd = READ_ONCE(sqe->fd); req->epoll.epfd = READ_ONCE(sqe->fd);
...@@ -3882,7 +3903,7 @@ static int io_fadvise(struct io_kiocb *req, bool force_nonblock) ...@@ -3882,7 +3903,7 @@ static int io_fadvise(struct io_kiocb *req, bool force_nonblock)
static int io_statx_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) static int io_statx_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
{ {
if (unlikely(req->ctx->flags & IORING_SETUP_IOPOLL)) if (unlikely(req->ctx->flags & (IORING_SETUP_IOPOLL | IORING_SETUP_SQPOLL)))
return -EINVAL; return -EINVAL;
if (sqe->ioprio || sqe->buf_index) if (sqe->ioprio || sqe->buf_index)
return -EINVAL; return -EINVAL;
...@@ -5399,6 +5420,8 @@ static int io_async_cancel(struct io_kiocb *req) ...@@ -5399,6 +5420,8 @@ static int io_async_cancel(struct io_kiocb *req)
static int io_files_update_prep(struct io_kiocb *req, static int io_files_update_prep(struct io_kiocb *req,
const struct io_uring_sqe *sqe) const struct io_uring_sqe *sqe)
{ {
if (unlikely(req->ctx->flags & IORING_SETUP_SQPOLL))
return -EINVAL;
if (unlikely(req->flags & (REQ_F_FIXED_FILE | REQ_F_BUFFER_SELECT))) if (unlikely(req->flags & (REQ_F_FIXED_FILE | REQ_F_BUFFER_SELECT)))
return -EINVAL; return -EINVAL;
if (sqe->ioprio || sqe->rw_flags) if (sqe->ioprio || sqe->rw_flags)
...@@ -5449,6 +5472,8 @@ static int io_req_defer_prep(struct io_kiocb *req, ...@@ -5449,6 +5472,8 @@ static int io_req_defer_prep(struct io_kiocb *req,
if (unlikely(ret)) if (unlikely(ret))
return ret; return ret;
io_prep_async_work(req);
switch (req->opcode) { switch (req->opcode) {
case IORING_OP_NOP: case IORING_OP_NOP:
break; break;
...@@ -8180,6 +8205,8 @@ static void io_uring_cancel_files(struct io_ring_ctx *ctx, ...@@ -8180,6 +8205,8 @@ static void io_uring_cancel_files(struct io_ring_ctx *ctx,
/* cancel this request, or head link requests */ /* cancel this request, or head link requests */
io_attempt_cancel(ctx, cancel_req); io_attempt_cancel(ctx, cancel_req);
io_put_req(cancel_req); io_put_req(cancel_req);
/* cancellations _may_ trigger task work */
io_run_task_work();
schedule(); schedule();
finish_wait(&ctx->inflight_wait, &wait); finish_wait(&ctx->inflight_wait, &wait);
} }
......
...@@ -130,7 +130,7 @@ static int io_uring_register_files(struct submitter *s) ...@@ -130,7 +130,7 @@ static int io_uring_register_files(struct submitter *s)
s->nr_files); s->nr_files);
} }
static int gettid(void) static int lk_gettid(void)
{ {
return syscall(__NR_gettid); return syscall(__NR_gettid);
} }
...@@ -281,7 +281,7 @@ static void *submitter_fn(void *data) ...@@ -281,7 +281,7 @@ static void *submitter_fn(void *data)
struct io_sq_ring *ring = &s->sq_ring; struct io_sq_ring *ring = &s->sq_ring;
int ret, prepped; int ret, prepped;
printf("submitter=%d\n", gettid()); printf("submitter=%d\n", lk_gettid());
srand48_r(pthread_self(), &s->rand); srand48_r(pthread_self(), &s->rand);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment