Skip to content

Commit d92d008

Browse files
isilencegregkh
authored andcommitted
io_uring: fix sleeping under spin in __io_clean_op
[ Upstream commit 9d5c819 ] [ 27.629441] BUG: sleeping function called from invalid context at fs/file.c:402 [ 27.631317] in_atomic(): 1, irqs_disabled(): 1, non_block: 0, pid: 1012, name: io_wqe_worker-0 [ 27.633220] 1 lock held by io_wqe_worker-0/1012: [ 27.634286] #0: ffff888105e26c98 (&ctx->completion_lock) {....}-{2:2}, at: __io_req_complete.part.102+0x30/0x70 [ 27.649249] Call Trace: [ 27.649874] dump_stack+0xac/0xe3 [ 27.650666] ___might_sleep+0x284/0x2c0 [ 27.651566] put_files_struct+0xb8/0x120 [ 27.652481] __io_clean_op+0x10c/0x2a0 [ 27.653362] __io_cqring_fill_event+0x2c1/0x350 [ 27.654399] __io_req_complete.part.102+0x41/0x70 [ 27.655464] io_openat2+0x151/0x300 [ 27.656297] io_issue_sqe+0x6c/0x14e0 [ 27.660991] io_wq_submit_work+0x7f/0x240 [ 27.662890] io_worker_handle_work+0x501/0x8a0 [ 27.664836] io_wqe_worker+0x158/0x520 [ 27.667726] kthread+0x134/0x180 [ 27.669641] ret_from_fork+0x1f/0x30 Instead of cleaning files on overflow, return back overflow cancellation into io_uring_cancel_files(). Previously it was racy to clean REQ_F_OVERFLOW flag, but we got rid of it, and can do it through repetitive attempts targeting all matching requests. Cc: stable@vger.kernel.org # 5.9+ Reported-by: Abaci <abaci@linux.alibaba.com> Reported-by: Joseph Qi <joseph.qi@linux.alibaba.com> Cc: Xiaoguang Wang <xiaoguang.wang@linux.alibaba.com> Signed-off-by: Pavel Begunkov <asml.silence@gmail.com> Signed-off-by: Jens Axboe <axboe@kernel.dk> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 7bccd1c commit d92d008

File tree

1 file changed

+6
-5
lines changed

1 file changed

+6
-5
lines changed

fs/io_uring.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -971,6 +971,7 @@ static ssize_t io_import_iovec(int rw, struct io_kiocb *req,
971971
static int io_setup_async_rw(struct io_kiocb *req, const struct iovec *iovec,
972972
const struct iovec *fast_iov,
973973
struct iov_iter *iter, bool force);
974+
static void io_req_drop_files(struct io_kiocb *req);
974975

975976
static struct kmem_cache *req_cachep;
976977

@@ -991,8 +992,7 @@ EXPORT_SYMBOL(io_uring_get_socket);
991992

992993
static inline void io_clean_op(struct io_kiocb *req)
993994
{
994-
if (req->flags & (REQ_F_NEED_CLEANUP | REQ_F_BUFFER_SELECTED |
995-
REQ_F_INFLIGHT))
995+
if (req->flags & (REQ_F_NEED_CLEANUP | REQ_F_BUFFER_SELECTED))
996996
__io_clean_op(req);
997997
}
998998

@@ -1256,6 +1256,8 @@ static void io_req_clean_work(struct io_kiocb *req)
12561256
free_fs_struct(fs);
12571257
req->work.flags &= ~IO_WQ_WORK_FS;
12581258
}
1259+
if (req->flags & REQ_F_INFLIGHT)
1260+
io_req_drop_files(req);
12591261

12601262
io_put_identity(req->task->io_uring, req);
12611263
}
@@ -5960,9 +5962,6 @@ static void __io_clean_op(struct io_kiocb *req)
59605962
}
59615963
req->flags &= ~REQ_F_NEED_CLEANUP;
59625964
}
5963-
5964-
if (req->flags & REQ_F_INFLIGHT)
5965-
io_req_drop_files(req);
59665965
}
59675966

59685967
static int io_issue_sqe(struct io_kiocb *req, bool force_nonblock,
@@ -8700,6 +8699,8 @@ static bool io_uring_cancel_files(struct io_ring_ctx *ctx,
87008699
break;
87018700
/* cancel this request, or head link requests */
87028701
io_attempt_cancel(ctx, cancel_req);
8702+
io_cqring_overflow_flush(ctx, true, task, files);
8703+
87038704
io_put_req(cancel_req);
87048705
/* cancellations _may_ trigger task work */
87058706
io_run_task_work();

0 commit comments

Comments
 (0)