Skip to content

Commit 99ebe4e

Browse files
isilenceaxboe
authored andcommitted
io_uring: pre-initialise some of req fields
Most of requests are allocated from an internal cache, so it's waste of time fully initialising them every time. Instead, let's pre-init some of the fields we can during initial allocation (e.g. kmalloc(), see io_alloc_req()) and keep them valid on request recycling. There are four of them in this patch: ->ctx is always stays the same ->link is NULL on free, it's an invariant ->result is not even needed to init, just a precaution ->async_data we now clean in io_dismantle_req() as it's likely to never be allocated. Signed-off-by: Pavel Begunkov <[email protected]> Link: https://lore.kernel.org/r/892ba0e71309bba9fe9e0142472330bbf9d8f05d.1624739600.git.asml.silence@gmail.com Signed-off-by: Jens Axboe <[email protected]>
1 parent 5182ed2 commit 99ebe4e

File tree

1 file changed

+18
-6
lines changed

1 file changed

+18
-6
lines changed

fs/io_uring.c

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1711,7 +1711,7 @@ static struct io_kiocb *io_alloc_req(struct io_ring_ctx *ctx)
17111711

17121712
if (!state->free_reqs) {
17131713
gfp_t gfp = GFP_KERNEL | __GFP_NOWARN;
1714-
int ret;
1714+
int ret, i;
17151715

17161716
if (io_flush_cached_reqs(ctx))
17171717
goto got_req;
@@ -1729,6 +1729,20 @@ static struct io_kiocb *io_alloc_req(struct io_ring_ctx *ctx)
17291729
return NULL;
17301730
ret = 1;
17311731
}
1732+
1733+
/*
1734+
* Don't initialise the fields below on every allocation, but
1735+
* do that in advance and keep valid on free.
1736+
*/
1737+
for (i = 0; i < ret; i++) {
1738+
struct io_kiocb *req = state->reqs[i];
1739+
1740+
req->ctx = ctx;
1741+
req->link = NULL;
1742+
req->async_data = NULL;
1743+
/* not necessary, but safer to zero */
1744+
req->result = 0;
1745+
}
17321746
state->free_reqs = ret;
17331747
}
17341748
got_req:
@@ -1752,8 +1766,10 @@ static void io_dismantle_req(struct io_kiocb *req)
17521766
io_put_file(req->file);
17531767
if (req->fixed_rsrc_refs)
17541768
percpu_ref_put(req->fixed_rsrc_refs);
1755-
if (req->async_data)
1769+
if (req->async_data) {
17561770
kfree(req->async_data);
1771+
req->async_data = NULL;
1772+
}
17571773
}
17581774

17591775
/* must to be called somewhat shortly after putting a request */
@@ -6534,15 +6550,11 @@ static int io_init_req(struct io_ring_ctx *ctx, struct io_kiocb *req,
65346550
/* same numerical values with corresponding REQ_F_*, safe to copy */
65356551
req->flags = sqe_flags = READ_ONCE(sqe->flags);
65366552
req->user_data = READ_ONCE(sqe->user_data);
6537-
req->async_data = NULL;
65386553
req->file = NULL;
6539-
req->ctx = ctx;
6540-
req->link = NULL;
65416554
req->fixed_rsrc_refs = NULL;
65426555
/* one is dropped after submission, the other at completion */
65436556
atomic_set(&req->refs, 2);
65446557
req->task = current;
6545-
req->result = 0;
65466558

65476559
/* enforce forwards compatibility on users */
65486560
if (unlikely(sqe_flags & ~SQE_VALID_FLAGS))

0 commit comments

Comments
 (0)