Skip to content

Commit 5082620

Browse files
committed
io_uring: terminate multishot poll for CQ ring overflow
If we hit overflow and fail to allocate an overflow entry for the completion, terminate the multishot poll mode. Signed-off-by: Jens Axboe <[email protected]>
1 parent b2c3f7e commit 5082620

File tree

1 file changed

+12
-8
lines changed

1 file changed

+12
-8
lines changed

fs/io_uring.c

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1044,6 +1044,7 @@ static void io_rsrc_put_work(struct work_struct *work);
10441044
static void io_req_task_queue(struct io_kiocb *req);
10451045
static void io_submit_flush_completions(struct io_comp_state *cs,
10461046
struct io_ring_ctx *ctx);
1047+
static bool io_poll_remove_waitqs(struct io_kiocb *req);
10471048
static int io_req_prep_async(struct io_kiocb *req);
10481049

10491050
static struct kmem_cache *req_cachep;
@@ -1501,7 +1502,7 @@ static inline void req_ref_get(struct io_kiocb *req)
15011502
atomic_inc(&req->refs);
15021503
}
15031504

1504-
static void __io_cqring_fill_event(struct io_kiocb *req, long res,
1505+
static bool __io_cqring_fill_event(struct io_kiocb *req, long res,
15051506
unsigned int cflags)
15061507
{
15071508
struct io_ring_ctx *ctx = req->ctx;
@@ -1519,7 +1520,7 @@ static void __io_cqring_fill_event(struct io_kiocb *req, long res,
15191520
WRITE_ONCE(cqe->user_data, req->user_data);
15201521
WRITE_ONCE(cqe->res, res);
15211522
WRITE_ONCE(cqe->flags, cflags);
1522-
return;
1523+
return true;
15231524
}
15241525
if (!ctx->cq_overflow_flushed &&
15251526
!atomic_read(&req->task->io_uring->in_idle)) {
@@ -1537,7 +1538,7 @@ static void __io_cqring_fill_event(struct io_kiocb *req, long res,
15371538
ocqe->cqe.res = res;
15381539
ocqe->cqe.flags = cflags;
15391540
list_add_tail(&ocqe->list, &ctx->cq_overflow_list);
1540-
return;
1541+
return true;
15411542
}
15421543
overflow:
15431544
/*
@@ -1546,6 +1547,7 @@ static void __io_cqring_fill_event(struct io_kiocb *req, long res,
15461547
* on the floor.
15471548
*/
15481549
WRITE_ONCE(ctx->rings->cq_overflow, ++ctx->cached_cq_overflow);
1550+
return false;
15491551
}
15501552

15511553
static void io_cqring_fill_event(struct io_kiocb *req, long res)
@@ -4907,14 +4909,14 @@ static bool io_poll_complete(struct io_kiocb *req, __poll_t mask, int error)
49074909
error = -ECANCELED;
49084910
req->poll.events |= EPOLLONESHOT;
49094911
}
4910-
if (error || (req->poll.events & EPOLLONESHOT)) {
4911-
io_poll_remove_double(req);
4912+
if (!error)
4913+
error = mangle_poll(mask);
4914+
if (!__io_cqring_fill_event(req, error, flags) ||
4915+
(req->poll.events & EPOLLONESHOT)) {
4916+
io_poll_remove_waitqs(req);
49124917
req->poll.done = true;
49134918
flags = 0;
49144919
}
4915-
if (!error)
4916-
error = mangle_poll(mask);
4917-
__io_cqring_fill_event(req, error, flags);
49184920
io_commit_cqring(ctx);
49194921
return !(flags & IORING_CQE_F_MORE);
49204922
}
@@ -5205,6 +5207,8 @@ static bool __io_poll_remove_one(struct io_kiocb *req,
52055207
{
52065208
bool do_complete = false;
52075209

5210+
if (!poll->head)
5211+
return false;
52085212
spin_lock(&poll->head->lock);
52095213
WRITE_ONCE(poll->canceled, true);
52105214
if (!list_empty(&poll->wait.entry)) {

0 commit comments

Comments
 (0)