diff --git a/io_uring/waitid.c b/io_uring/waitid.c index 2ba2369681d0..172cf770b29b 100644 --- a/io_uring/waitid.c +++ b/io_uring/waitid.c @@ -154,9 +154,12 @@ static bool __io_waitid_cancel(struct io_kiocb *req, bool copy_si) /* * Mark us canceled regardless of ownership. This will prevent a - * potential retry from a spurious wakeup. + * potential retry from a spurious wakeup. Only the first cancel + * attempt should take a reference for the ownership handoff. */ - atomic_or(IO_WAITID_CANCEL_FLAG, &iw->refs); + if (atomic_fetch_or(IO_WAITID_CANCEL_FLAG, &iw->refs) & + IO_WAITID_CANCEL_FLAG) + return false; /* claim ownership */ if (atomic_fetch_inc(&iw->refs) & IO_WAITID_REF_MASK)