Commit cb3b200e authored by Jens Axboe's avatar Jens Axboe

io_uring: don't attempt re-add of multishot poll request if racing

We currently allow racy updates to multishot requests, but we can end up
double adding the poll request if both completion and update does it.
Ensure that we skip re-add on the update side if someone else is
completing it.

Fixes: b69de288 ("io_uring: allow events and user_data update of running poll requests")
Reported-by: default avatarJoakim Hassila <joj@mac.com>
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent 417b5052
......@@ -5432,6 +5432,7 @@ static int io_poll_update(struct io_kiocb *req)
{
struct io_ring_ctx *ctx = req->ctx;
struct io_kiocb *preq;
bool completing;
int ret;
spin_lock_irq(&ctx->completion_lock);
......@@ -5444,17 +5445,22 @@ static int io_poll_update(struct io_kiocb *req)
ret = -EACCES;
goto err;
}
if (!__io_poll_remove_one(preq, &preq->poll, false)) {
if (preq->poll.events & EPOLLONESHOT) {
ret = -EALREADY;
goto err;
}
/*
* Don't allow racy completion with singleshot, as we cannot safely
* update those. For multishot, if we're racing with completion, just
* let completion re-add it.
*/
completing = !__io_poll_remove_one(preq, &preq->poll, false);
if (completing && (preq->poll.events & EPOLLONESHOT)) {
ret = -EALREADY;
goto err;
}
/* we now have a detached poll request. reissue. */
ret = 0;
err:
spin_unlock_irq(&ctx->completion_lock);
if (ret < 0) {
spin_unlock_irq(&ctx->completion_lock);
req_set_fail_links(req);
io_req_complete(req, ret);
return 0;
......@@ -5468,13 +5474,17 @@ static int io_poll_update(struct io_kiocb *req)
if (req->poll.update_user_data)
preq->user_data = req->poll.new_user_data;
spin_unlock_irq(&ctx->completion_lock);
/* complete update request, we're done with it */
io_req_complete(req, ret);
ret = __io_poll_add(preq);
if (ret < 0) {
req_set_fail_links(preq);
io_req_complete(preq, ret);
if (!completing) {
ret = __io_poll_add(preq);
if (ret < 0) {
req_set_fail_links(preq);
io_req_complete(preq, ret);
}
}
return 0;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment