Skip to content

Commit

Permalink
io_uring/poll: add hash if ready poll request can't complete inline
Browse files Browse the repository at this point in the history
If we don't, then we may lose access to it completely, leading to a
request leak. This will eventually stall the ring exit process as
well.

Cc: [email protected]
Fixes: 49f1c68 ("io_uring: optimise submission side poll_refs")
Reported-and-tested-by: [email protected]
Link: https://lore.kernel.org/io-uring/[email protected]/
Suggested-by: Pavel Begunkov <[email protected]>
Signed-off-by: Jens Axboe <[email protected]>
  • Loading branch information
axboe committed Jan 9, 2023
1 parent e6db6f9 commit febb985
Showing 1 changed file with 12 additions and 5 deletions.
17 changes: 12 additions & 5 deletions io_uring/poll.c
Original file line number Diff line number Diff line change
Expand Up @@ -533,6 +533,14 @@ static bool io_poll_can_finish_inline(struct io_kiocb *req,
return pt->owning || io_poll_get_ownership(req);
}

static void io_poll_add_hash(struct io_kiocb *req)
{
if (req->flags & REQ_F_HASH_LOCKED)
io_poll_req_insert_locked(req);
else
io_poll_req_insert(req);
}

/*
* Returns 0 when it's handed over for polling. The caller owns the requests if
* it returns non-zero, but otherwise should not touch it. Negative values
Expand Down Expand Up @@ -591,18 +599,17 @@ static int __io_arm_poll_handler(struct io_kiocb *req,

if (mask &&
((poll->events & (EPOLLET|EPOLLONESHOT)) == (EPOLLET|EPOLLONESHOT))) {
if (!io_poll_can_finish_inline(req, ipt))
if (!io_poll_can_finish_inline(req, ipt)) {
io_poll_add_hash(req);
return 0;
}
io_poll_remove_entries(req);
ipt->result_mask = mask;
/* no one else has access to the req, forget about the ref */
return 1;
}

if (req->flags & REQ_F_HASH_LOCKED)
io_poll_req_insert_locked(req);
else
io_poll_req_insert(req);
io_poll_add_hash(req);

if (mask && (poll->events & EPOLLET) &&
io_poll_can_finish_inline(req, ipt)) {
Expand Down

0 comments on commit febb985

Please sign in to comment.