Commit ab0f2473 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'io_uring-5.8-2020-06-26' of git://git.kernel.dk/linux-block

Pull io_uring fixes from Jens Axboe:
 "Three small fixes:

   - Close a corner case for polled IO resubmission (Pavel)

   - Toss commands when exiting (Pavel)

   - Fix SQPOLL conditional reschedule on perpetually busy submit
     (Xuan)"

* tag 'io_uring-5.8-2020-06-26' of git://git.kernel.dk/linux-block:
  io_uring: fix current->mm NULL dereference on exit
  io_uring: fix hanging iopoll in case of -EAGAIN
  io_uring: fix io_sq_thread no schedule when busy
parents 9b8d0207 d60b5fbc
...@@ -890,6 +890,7 @@ static int __io_sqe_files_update(struct io_ring_ctx *ctx, ...@@ -890,6 +890,7 @@ static int __io_sqe_files_update(struct io_ring_ctx *ctx,
struct io_uring_files_update *ip, struct io_uring_files_update *ip,
unsigned nr_args); unsigned nr_args);
static int io_grab_files(struct io_kiocb *req); static int io_grab_files(struct io_kiocb *req);
static void io_complete_rw_common(struct kiocb *kiocb, long res);
static void io_cleanup_req(struct io_kiocb *req); static void io_cleanup_req(struct io_kiocb *req);
static int io_file_get(struct io_submit_state *state, 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); int fd, struct file **out_file, bool fixed);
...@@ -1749,6 +1750,14 @@ static void io_iopoll_queue(struct list_head *again) ...@@ -1749,6 +1750,14 @@ static void io_iopoll_queue(struct list_head *again)
do { do {
req = list_first_entry(again, struct io_kiocb, list); req = list_first_entry(again, struct io_kiocb, list);
list_del(&req->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;
}
refcount_inc(&req->refs); refcount_inc(&req->refs);
io_queue_async_work(req); io_queue_async_work(req);
} while (!list_empty(again)); } while (!list_empty(again));
...@@ -1994,10 +2003,8 @@ static void io_complete_rw_iopoll(struct kiocb *kiocb, long res, long res2) ...@@ -1994,10 +2003,8 @@ static void io_complete_rw_iopoll(struct kiocb *kiocb, long res, long res2)
WRITE_ONCE(req->result, res); WRITE_ONCE(req->result, res);
/* order with io_poll_complete() checking ->result */ /* order with io_poll_complete() checking ->result */
if (res != -EAGAIN) { smp_wmb();
smp_wmb(); WRITE_ONCE(req->iopoll_completed, 1);
WRITE_ONCE(req->iopoll_completed, 1);
}
} }
/* /*
...@@ -5353,9 +5360,6 @@ static int io_issue_sqe(struct io_kiocb *req, const struct io_uring_sqe *sqe, ...@@ -5353,9 +5360,6 @@ static int io_issue_sqe(struct io_kiocb *req, const struct io_uring_sqe *sqe,
if ((ctx->flags & IORING_SETUP_IOPOLL) && req->file) { if ((ctx->flags & IORING_SETUP_IOPOLL) && req->file) {
const bool in_async = io_wq_current_is_worker(); const bool in_async = io_wq_current_is_worker();
if (req->result == -EAGAIN)
return -EAGAIN;
/* workqueue context doesn't hold uring_lock, grab it now */ /* workqueue context doesn't hold uring_lock, grab it now */
if (in_async) if (in_async)
mutex_lock(&ctx->uring_lock); mutex_lock(&ctx->uring_lock);
...@@ -6011,7 +6015,7 @@ static int io_sq_thread(void *data) ...@@ -6011,7 +6015,7 @@ static int io_sq_thread(void *data)
* If submit got -EBUSY, flag us as needing the application * If submit got -EBUSY, flag us as needing the application
* to enter the kernel to reap and flush events. * to enter the kernel to reap and flush events.
*/ */
if (!to_submit || ret == -EBUSY) { if (!to_submit || ret == -EBUSY || need_resched()) {
/* /*
* Drop cur_mm before scheduling, we can't hold it for * Drop cur_mm before scheduling, we can't hold it for
* long periods (or over schedule()). Do this before * long periods (or over schedule()). Do this before
...@@ -6027,7 +6031,7 @@ static int io_sq_thread(void *data) ...@@ -6027,7 +6031,7 @@ static int io_sq_thread(void *data)
* more IO, we should wait for the application to * more IO, we should wait for the application to
* reap events and wake us up. * reap events and wake us up.
*/ */
if (!list_empty(&ctx->poll_list) || if (!list_empty(&ctx->poll_list) || need_resched() ||
(!time_after(jiffies, timeout) && ret != -EBUSY && (!time_after(jiffies, timeout) && ret != -EBUSY &&
!percpu_ref_is_dying(&ctx->refs))) { !percpu_ref_is_dying(&ctx->refs))) {
if (current->task_works) if (current->task_works)
......
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