diff options
author | Jens Axboe <axboe@kernel.dk> | 2020-06-26 13:44:16 -0600 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2020-06-26 13:44:16 -0600 |
commit | 2237d76530ebf8e4fc3a0c6048d74cff808dee8f (patch) | |
tree | e971e9aaa4aaa26cc5efc1936bf93731bfd088a4 /fs/io_uring.c | |
parent | f4db7182e0de981a3f1b356e0cf43c6815423055 (diff) | |
parent | d60b5fbc1ce8210759b568da49d149b868e7c6d3 (diff) | |
download | lwn-2237d76530ebf8e4fc3a0c6048d74cff808dee8f.tar.gz lwn-2237d76530ebf8e4fc3a0c6048d74cff808dee8f.zip |
Merge branch 'io_uring-5.8' into for-5.9/io_uring
Merge in changes that went into 5.8-rc3. GIT will silently do the
merge, but we still need a tweak on top of that since
io_complete_rw_common() was modified to take a io_comp_state pointer.
The auto-merge fails on that, and we end up with something that
doesn't compile.
* io_uring-5.8:
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
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'fs/io_uring.c')
-rw-r--r-- | fs/io_uring.c | 23 |
1 files changed, 14 insertions, 9 deletions
diff --git a/fs/io_uring.c b/fs/io_uring.c index 2e44b3788265..af4d7a5c49f4 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -905,6 +905,8 @@ 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, + 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); @@ -1897,6 +1899,14 @@ static void io_iopoll_queue(struct list_head *again) 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, NULL); + io_put_req(req); + continue; + } + refcount_inc(&req->refs); io_queue_async_work(req); } while (!list_empty(again)); @@ -2221,10 +2231,8 @@ static void io_complete_rw_iopoll(struct kiocb *kiocb, long res, long res2) WRITE_ONCE(req->result, res); /* order with io_poll_complete() checking ->result */ - if (res != -EAGAIN) { - smp_wmb(); - WRITE_ONCE(req->iopoll_completed, 1); - } + smp_wmb(); + WRITE_ONCE(req->iopoll_completed, 1); } /* @@ -5680,9 +5688,6 @@ static int io_issue_sqe(struct io_kiocb *req, const struct io_uring_sqe *sqe, if ((ctx->flags & IORING_SETUP_IOPOLL) && req->file) { 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 */ if (in_async) mutex_lock(&ctx->uring_lock); @@ -6341,7 +6346,7 @@ static int io_sq_thread(void *data) * If submit got -EBUSY, flag us as needing the application * 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 * long periods (or over schedule()). Do this before @@ -6357,7 +6362,7 @@ static int io_sq_thread(void *data) * more IO, we should wait for the application to * 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 && !percpu_ref_is_dying(&ctx->refs))) { if (current->task_works) |