diff options
Diffstat (limited to 'io_uring/io_uring.c')
| -rw-r--r-- | io_uring/io_uring.c | 40 | 
1 files changed, 40 insertions, 0 deletions
diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c index 3a23c8713f1b..895740c955d0 100644 --- a/io_uring/io_uring.c +++ b/io_uring/io_uring.c @@ -793,6 +793,21 @@ bool io_cqe_cache_refill(struct io_ring_ctx *ctx, bool overflow)  	return true;  } +static bool io_fill_cqe_aux32(struct io_ring_ctx *ctx, +			      struct io_uring_cqe src_cqe[2]) +{ +	struct io_uring_cqe *cqe; + +	if (WARN_ON_ONCE(!(ctx->flags & IORING_SETUP_CQE32))) +		return false; +	if (unlikely(!io_get_cqe(ctx, &cqe))) +		return false; + +	memcpy(cqe, src_cqe, 2 * sizeof(*cqe)); +	trace_io_uring_complete(ctx, NULL, cqe); +	return true; +} +  static bool io_fill_cqe_aux(struct io_ring_ctx *ctx, u64 user_data, s32 res,  			      u32 cflags)  { @@ -904,6 +919,31 @@ bool io_req_post_cqe(struct io_kiocb *req, s32 res, u32 cflags)  	return posted;  } +/* + * A helper for multishot requests posting additional CQEs. + * Should only be used from a task_work including IO_URING_F_MULTISHOT. + */ +bool io_req_post_cqe32(struct io_kiocb *req, struct io_uring_cqe cqe[2]) +{ +	struct io_ring_ctx *ctx = req->ctx; +	bool posted; + +	lockdep_assert(!io_wq_current_is_worker()); +	lockdep_assert_held(&ctx->uring_lock); + +	cqe[0].user_data = req->cqe.user_data; +	if (!ctx->lockless_cq) { +		spin_lock(&ctx->completion_lock); +		posted = io_fill_cqe_aux32(ctx, cqe); +		spin_unlock(&ctx->completion_lock); +	} else { +		posted = io_fill_cqe_aux32(ctx, cqe); +	} + +	ctx->submit_state.cq_flush = true; +	return posted; +} +  static void io_req_complete_post(struct io_kiocb *req, unsigned issue_flags)  {  	struct io_ring_ctx *ctx = req->ctx;  | 
