Skip to content

Commit 2579f91

Browse files
committed
io_uring: batch io_kiocb allocation
Similarly to how we use the state->ios_left to know how many references to get to a file, we can use it to allocate the io_kiocb's we need in bulk. Reviewed-by: Hannes Reinecke <hare@suse.com> Signed-off-by: Jens Axboe <axboe@kernel.dk>
1 parent 9a56a23 commit 2579f91

File tree

1 file changed

+38
-7
lines changed

1 file changed

+38
-7
lines changed

fs/io_uring.c

Lines changed: 38 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,13 @@ struct io_kiocb {
168168
struct io_submit_state {
169169
struct blk_plug plug;
170170

171+
/*
172+
* io_kiocb alloc cache
173+
*/
174+
void *reqs[IO_IOPOLL_BATCH];
175+
unsigned int free_reqs;
176+
unsigned int cur_req;
177+
171178
/*
172179
* File reference cache
173180
*/
@@ -305,20 +312,40 @@ static void io_ring_drop_ctx_refs(struct io_ring_ctx *ctx, unsigned refs)
305312
wake_up(&ctx->wait);
306313
}
307314

308-
static struct io_kiocb *io_get_req(struct io_ring_ctx *ctx)
315+
static struct io_kiocb *io_get_req(struct io_ring_ctx *ctx,
316+
struct io_submit_state *state)
309317
{
310318
struct io_kiocb *req;
311319

312320
if (!percpu_ref_tryget(&ctx->refs))
313321
return NULL;
314322

315-
req = kmem_cache_alloc(req_cachep, __GFP_NOWARN);
316-
if (req) {
317-
req->ctx = ctx;
318-
req->flags = 0;
319-
return req;
323+
if (!state) {
324+
req = kmem_cache_alloc(req_cachep, __GFP_NOWARN);
325+
if (unlikely(!req))
326+
goto out;
327+
} else if (!state->free_reqs) {
328+
size_t sz;
329+
int ret;
330+
331+
sz = min_t(size_t, state->ios_left, ARRAY_SIZE(state->reqs));
332+
ret = kmem_cache_alloc_bulk(req_cachep, __GFP_NOWARN, sz,
333+
state->reqs);
334+
if (unlikely(ret <= 0))
335+
goto out;
336+
state->free_reqs = ret - 1;
337+
state->cur_req = 1;
338+
req = state->reqs[0];
339+
} else {
340+
req = state->reqs[state->cur_req];
341+
state->free_reqs--;
342+
state->cur_req++;
320343
}
321344

345+
req->ctx = ctx;
346+
req->flags = 0;
347+
return req;
348+
out:
322349
io_ring_drop_ctx_refs(ctx, 1);
323350
return NULL;
324351
}
@@ -1007,7 +1034,7 @@ static int io_submit_sqe(struct io_ring_ctx *ctx, struct sqe_submit *s,
10071034
if (unlikely(s->sqe->flags))
10081035
return -EINVAL;
10091036

1010-
req = io_get_req(ctx);
1037+
req = io_get_req(ctx, state);
10111038
if (unlikely(!req))
10121039
return -EAGAIN;
10131040

@@ -1041,6 +1068,9 @@ static void io_submit_state_end(struct io_submit_state *state)
10411068
{
10421069
blk_finish_plug(&state->plug);
10431070
io_file_put(state, NULL);
1071+
if (state->free_reqs)
1072+
kmem_cache_free_bulk(req_cachep, state->free_reqs,
1073+
&state->reqs[state->cur_req]);
10441074
}
10451075

10461076
/*
@@ -1050,6 +1080,7 @@ static void io_submit_state_start(struct io_submit_state *state,
10501080
struct io_ring_ctx *ctx, unsigned max_ios)
10511081
{
10521082
blk_start_plug(&state->plug);
1083+
state->free_reqs = 0;
10531084
state->file = NULL;
10541085
state->ios_left = max_ios;
10551086
}

0 commit comments

Comments
 (0)