]> git.itanic.dy.fi Git - linux-stable/commitdiff
io_uring/waitid: always remove waitid entry for cancel all
authorJens Axboe <axboe@kernel.dk>
Fri, 15 Mar 2024 21:42:49 +0000 (15:42 -0600)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 3 Apr 2024 13:32:24 +0000 (15:32 +0200)
[ Upstream commit 2b35b8b43e07b1a6f06fdd84cf4b9eb24785896d ]

We know the request is either being removed, or already in the process of
being removed through task_work, so we can delete it from our waitid list
upfront. This is important for remove all conditions, as we otherwise
will find it multiple times and prevent cancelation progress.

Remove the dead check in cancelation as well for the hash_node being
empty or not. We already have a waitid reference check for ownership,
so we don't need to check the list too.

Cc: stable@vger.kernel.org
Fixes: f31ecf671ddc ("io_uring: add IORING_OP_WAITID support")
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Sasha Levin <sashal@kernel.org>
io_uring/waitid.c

index 6f851978606d988cfe2486d725d905b558b4a066..77d340666cb95b61a98ccd4717e033f35ec2f9f8 100644 (file)
@@ -125,12 +125,6 @@ static void io_waitid_complete(struct io_kiocb *req, int ret)
 
        lockdep_assert_held(&req->ctx->uring_lock);
 
-       /*
-        * Did cancel find it meanwhile?
-        */
-       if (hlist_unhashed(&req->hash_node))
-               return;
-
        hlist_del_init(&req->hash_node);
 
        ret = io_waitid_finish(req, ret);
@@ -202,6 +196,7 @@ bool io_waitid_remove_all(struct io_ring_ctx *ctx, struct task_struct *task,
        hlist_for_each_entry_safe(req, tmp, &ctx->waitid_list, hash_node) {
                if (!io_match_task_safe(req, task, cancel_all))
                        continue;
+               hlist_del_init(&req->hash_node);
                __io_waitid_cancel(ctx, req);
                found = true;
        }