Commit f8b632e
io_uring: tighten task exit cancellations
io_uring_cancel_generic() should retry if any state changes like a
request is completed, however in case of a task exit it only goes for
another loop and avoids schedule() if any tracked (i.e. REQ_F_INFLIGHT)
request got completed.
Let's assume we have a non-tracked request executing in iowq and a
tracked request linked to it. Let's also assume
io_uring_cancel_generic() fails to find and cancel the request, i.e.
via io_run_local_work(), which may happen as io-wq has gaps.
Next, the request logically completes, io-wq still hold a ref but queues
it for completion via tw, which happens in
io_uring_try_cancel_requests(). After, right before prepare_to_wait()
io-wq puts the request, grabs the linked one and tries executes it, e.g.
arms polling. Finally the cancellation loop calls prepare_to_wait(),
there are no tw to run, no tracked request was completed, so the
tctx_inflight() check passes and the task is put to indefinite sleep.
Cc: [email protected]
Fixes: 3f48cf1 ("io_uring: unify files and task cancel")
Signed-off-by: Pavel Begunkov <[email protected]>
Link: https://lore.kernel.org/r/acac7311f4e02ce3c43293f8f1fda9c705d158f1.1721819383.git.asml.silence@gmail.com
Signed-off-by: Jens Axboe <[email protected]>1 parent bcc87d9 commit f8b632e
1 file changed
+4
-1
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
3031 | 3031 | | |
3032 | 3032 | | |
3033 | 3033 | | |
| 3034 | + | |
| 3035 | + | |
| 3036 | + | |
3034 | 3037 | | |
3035 | | - | |
| 3038 | + | |
3036 | 3039 | | |
3037 | 3040 | | |
3038 | 3041 | | |
| |||
0 commit comments