@@ -213,6 +213,7 @@ struct io_submit_state {
bool need_plug;
bool cq_flush;
unsigned short submit_nr;
+ unsigned short inline_completions;
struct blk_plug plug;
};
@@ -899,6 +899,10 @@ struct io_uring_recvmsg_out {
__u32 flags;
};
+enum {
+ IOSQE_SET_F_HINT_IGNORE_INLINE = 1,
+};
+
struct io_uring_ioset_reg {
__u64 flags;
__u64 __resv[3];
@@ -1575,6 +1575,9 @@ void __io_submit_flush_completions(struct io_ring_ctx *ctx)
struct io_kiocb *req = container_of(node, struct io_kiocb,
comp_list);
+ if (req->ioset->flags & IOSQE_SET_F_HINT_IGNORE_INLINE)
+ state->inline_completions++;
+
if (unlikely(req->flags & (REQ_F_CQE_SKIP | REQ_F_GROUP))) {
if (req->flags & REQ_F_GROUP) {
io_complete_group_req(req);
@@ -2511,6 +2514,7 @@ static void io_submit_state_start(struct io_submit_state *state,
state->plug_started = false;
state->need_plug = max_ios > 2;
state->submit_nr = max_ios;
+ state->inline_completions = 0;
/* set only head, no need to init link_last in advance */
state->link.head = NULL;
state->group.head = NULL;
@@ -3611,6 +3615,7 @@ SYSCALL_DEFINE6(io_uring_enter, unsigned int, fd, u32, to_submit,
size_t, argsz)
{
struct io_ring_ctx *ctx;
+ int inline_complete = 0;
struct file *file;
long ret;
@@ -3676,6 +3681,7 @@ SYSCALL_DEFINE6(io_uring_enter, unsigned int, fd, u32, to_submit,
mutex_unlock(&ctx->uring_lock);
goto out;
}
+ inline_complete = ctx->submit_state.inline_completions;
if (flags & IORING_ENTER_GETEVENTS) {
if (ctx->syscall_iopoll)
goto iopoll_locked;
@@ -3713,8 +3719,10 @@ SYSCALL_DEFINE6(io_uring_enter, unsigned int, fd, u32, to_submit,
ret2 = io_get_ext_arg(ctx, flags, argp, &ext_arg);
if (likely(!ret2)) {
- min_complete = min(min_complete,
- ctx->cq_entries);
+ if (min_complete > ctx->cq_entries)
+ min_complete = ctx->cq_entries;
+ else
+ min_complete += inline_complete;
ret2 = io_cqring_wait(ctx, min_complete, flags,
&ext_arg);
}
@@ -92,7 +92,7 @@ static int io_update_ioset(struct io_ring_ctx *ctx,
{
if (!(ctx->flags & IORING_SETUP_IOSET))
return -EINVAL;
- if (reg->flags)
+ if (reg->flags & ~IOSQE_SET_F_HINT_IGNORE_INLINE)
return -EINVAL;
if (reg->__resv[0] || reg->__resv[1] || reg->__resv[2])
return -EINVAL;