Skip to content

Commit 674ee8e

Browse files
isilenceaxboe
authored andcommitted
io_uring: correct link-list traversal locking
As io_remove_next_linked() is now under ->timeout_lock (see io_link_timeout_fn), we should update locking around io_for_each_link() and io_match_task() to use the new lock. Cc: [email protected] # 5.15+ Fixes: 89850fc ("io_uring: run timeouts from task_work") Signed-off-by: Pavel Begunkov <[email protected]> Link: https://lore.kernel.org/r/b54541cedf7de59cb5ae36109e58529ca16e66aa.1637631883.git.asml.silence@gmail.com Signed-off-by: Jens Axboe <[email protected]>
1 parent f6f9b27 commit 674ee8e

File tree

1 file changed

+8
-4
lines changed

1 file changed

+8
-4
lines changed

fs/io_uring.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1502,10 +1502,10 @@ static void io_prep_async_link(struct io_kiocb *req)
15021502
if (req->flags & REQ_F_LINK_TIMEOUT) {
15031503
struct io_ring_ctx *ctx = req->ctx;
15041504

1505-
spin_lock(&ctx->completion_lock);
1505+
spin_lock_irq(&ctx->timeout_lock);
15061506
io_for_each_link(cur, req)
15071507
io_prep_async_work(cur);
1508-
spin_unlock(&ctx->completion_lock);
1508+
spin_unlock_irq(&ctx->timeout_lock);
15091509
} else {
15101510
io_for_each_link(cur, req)
15111511
io_prep_async_work(cur);
@@ -5699,6 +5699,7 @@ static __cold bool io_poll_remove_all(struct io_ring_ctx *ctx,
56995699
int posted = 0, i;
57005700

57015701
spin_lock(&ctx->completion_lock);
5702+
spin_lock_irq(&ctx->timeout_lock);
57025703
for (i = 0; i < (1U << ctx->cancel_hash_bits); i++) {
57035704
struct hlist_head *list;
57045705

@@ -5708,6 +5709,7 @@ static __cold bool io_poll_remove_all(struct io_ring_ctx *ctx,
57085709
posted += io_poll_remove_one(req);
57095710
}
57105711
}
5712+
spin_unlock_irq(&ctx->timeout_lock);
57115713
spin_unlock(&ctx->completion_lock);
57125714

57135715
if (posted)
@@ -9568,9 +9570,9 @@ static bool io_cancel_task_cb(struct io_wq_work *work, void *data)
95689570
struct io_ring_ctx *ctx = req->ctx;
95699571

95709572
/* protect against races with linked timeouts */
9571-
spin_lock(&ctx->completion_lock);
9573+
spin_lock_irq(&ctx->timeout_lock);
95729574
ret = io_match_task(req, cancel->task, cancel->all);
9573-
spin_unlock(&ctx->completion_lock);
9575+
spin_unlock_irq(&ctx->timeout_lock);
95749576
} else {
95759577
ret = io_match_task(req, cancel->task, cancel->all);
95769578
}
@@ -9585,12 +9587,14 @@ static __cold bool io_cancel_defer_files(struct io_ring_ctx *ctx,
95859587
LIST_HEAD(list);
95869588

95879589
spin_lock(&ctx->completion_lock);
9590+
spin_lock_irq(&ctx->timeout_lock);
95889591
list_for_each_entry_reverse(de, &ctx->defer_list, list) {
95899592
if (io_match_task(de->req, task, cancel_all)) {
95909593
list_cut_position(&list, &ctx->defer_list, &de->list);
95919594
break;
95929595
}
95939596
}
9597+
spin_unlock_irq(&ctx->timeout_lock);
95949598
spin_unlock(&ctx->completion_lock);
95959599
if (list_empty(&list))
95969600
return false;

0 commit comments

Comments
 (0)