
static void io_uring_cancel_sqpoll(struct io_ring_ctx *ctx)
{
	struct io_sq_data *sqd = ctx->sq_data;
	struct io_uring_task *tctx;
	s64 inflight;
	DEFINE_WAIT(wait);

	if (!sqd)
		return;
	io_disable_sqo_submit(ctx);
	if (!io_sq_thread_park(sqd))
		return;
	tctx = ctx->sq_data->thread->io_uring;
	/* can happen on fork/alloc failure, just ignore that state */
	if (!tctx) {
		io_sq_thread_unpark(sqd);
		return;
	}

	atomic_inc(&tctx->in_idle);
	do {
		/* read completions before cancelations */
		inflight = tctx_inflight(tctx);
		if (!inflight)
			break;
		io_uring_cancel_task_requests(ctx, NULL);

		prepare_to_wait(&tctx->wait, &wait, TASK_UNINTERRUPTIBLE);
		/*
		 * If we've seen completions, retry without waiting. This
		 * avoids a race where a completion comes in before we did
		 * prepare_to_wait().
		 */
		if (inflight == tctx_inflight(tctx))
			schedule();
		finish_wait(&tctx->wait, &wait);
	} while (1);
	atomic_dec(&tctx->in_idle);
	io_sq_thread_unpark(sqd);

static void io_uring_cancel_sqpoll(struct io_ring_ctx *ctx)
{
	struct io_sq_data *sqd = ctx->sq_data;
	struct io_uring_task *tctx;
	s64 inflight;
	DEFINE_WAIT(wait);

	if (!sqd)
		return;
	io_disable_sqo_submit(ctx);
	if (!io_sq_thread_park(sqd))
		return;
	tctx = ctx->sq_data->thread->io_uring;
	 
	if (!tctx) {
		io_sq_thread_unpark(sqd);
		return;
	}

	atomic_inc(&tctx->in_idle);
	do {
		 
		inflight = tctx_inflight(tctx);
		if (!inflight)
			break;
		io_uring_cancel_task_requests(ctx, NULL);

		prepare_to_wait(&tctx->wait, &wait, TASK_UNINTERRUPTIBLE);
		 
		if (inflight == tctx_inflight(tctx))
			schedule();
		finish_wait(&tctx->wait, &wait);
	} while (1);
	atomic_dec(&tctx->in_idle);
	io_sq_thread_unpark(sqd);