Skip to content

Commit 3a4689a

Browse files
isilenceaxboe
authored andcommitted
io_uring/cmd: add iovec cache for commands
Add iou_vec to commands and wire caching for it, but don't expose it to users just yet. We need the vec cleared on initial alloc, but since we can't place it at the beginning at the moment, zero the entire async_data. It's cached, and the performance effects only the initial allocation, and it might be not a bad idea since we're exposing those bits to outside drivers. Signed-off-by: Pavel Begunkov <[email protected]> Link: https://lore.kernel.org/r/c0f2145b75791bc6106eb4e72add2cf6a2c72a7a.1742579999.git.asml.silence@gmail.com Signed-off-by: Jens Axboe <[email protected]>
1 parent 5f14404 commit 3a4689a

File tree

4 files changed

+28
-3
lines changed

4 files changed

+28
-3
lines changed

io_uring/io_uring.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ static void io_free_alloc_caches(struct io_ring_ctx *ctx)
289289
io_alloc_cache_free(&ctx->apoll_cache, kfree);
290290
io_alloc_cache_free(&ctx->netmsg_cache, io_netmsg_cache_free);
291291
io_alloc_cache_free(&ctx->rw_cache, io_rw_cache_free);
292-
io_alloc_cache_free(&ctx->cmd_cache, kfree);
292+
io_alloc_cache_free(&ctx->cmd_cache, io_cmd_cache_free);
293293
io_alloc_cache_free(&ctx->msg_cache, kfree);
294294
io_futex_cache_free(ctx);
295295
io_rsrc_cache_free(ctx);
@@ -335,7 +335,8 @@ static __cold struct io_ring_ctx *io_ring_ctx_alloc(struct io_uring_params *p)
335335
sizeof(struct io_async_rw),
336336
offsetof(struct io_async_rw, clear));
337337
ret |= io_alloc_cache_init(&ctx->cmd_cache, IO_ALLOC_CACHE_MAX,
338-
sizeof(struct io_async_cmd), 0);
338+
sizeof(struct io_async_cmd),
339+
sizeof(struct io_async_cmd));
339340
spin_lock_init(&ctx->msg_lock);
340341
ret |= io_alloc_cache_init(&ctx->msg_cache, IO_ALLOC_CACHE_MAX,
341342
sizeof(struct io_kiocb), 0);

io_uring/opdef.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -755,6 +755,7 @@ const struct io_cold_def io_cold_defs[] = {
755755
},
756756
[IORING_OP_URING_CMD] = {
757757
.name = "URING_CMD",
758+
.cleanup = io_uring_cmd_cleanup,
758759
},
759760
[IORING_OP_SEND_ZC] = {
760761
.name = "SEND_ZC",

io_uring/uring_cmd.c

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,14 @@
1616
#include "rsrc.h"
1717
#include "uring_cmd.h"
1818

19+
void io_cmd_cache_free(const void *entry)
20+
{
21+
struct io_async_cmd *ac = (struct io_async_cmd *)entry;
22+
23+
io_vec_free(&ac->vec);
24+
kfree(ac);
25+
}
26+
1927
static void io_req_uring_cleanup(struct io_kiocb *req, unsigned int issue_flags)
2028
{
2129
struct io_uring_cmd *ioucmd = io_kiocb_to_cmd(req, struct io_uring_cmd);
@@ -29,13 +37,23 @@ static void io_req_uring_cleanup(struct io_kiocb *req, unsigned int issue_flags)
2937

3038
if (issue_flags & IO_URING_F_UNLOCKED)
3139
return;
40+
41+
io_alloc_cache_vec_kasan(&ac->vec);
42+
if (ac->vec.nr > IO_VEC_CACHE_SOFT_CAP)
43+
io_vec_free(&ac->vec);
44+
3245
if (io_alloc_cache_put(&req->ctx->cmd_cache, cache)) {
3346
ioucmd->sqe = NULL;
3447
req->async_data = NULL;
35-
req->flags &= ~REQ_F_ASYNC_DATA;
48+
req->flags &= ~(REQ_F_ASYNC_DATA|REQ_F_NEED_CLEANUP);
3649
}
3750
}
3851

52+
void io_uring_cmd_cleanup(struct io_kiocb *req)
53+
{
54+
io_req_uring_cleanup(req, 0);
55+
}
56+
3957
bool io_uring_try_cancel_uring_cmd(struct io_ring_ctx *ctx,
4058
struct io_uring_task *tctx, bool cancel_all)
4159
{

io_uring/uring_cmd.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,18 @@
11
// SPDX-License-Identifier: GPL-2.0
22

33
#include <linux/io_uring/cmd.h>
4+
#include <linux/io_uring_types.h>
45

56
struct io_async_cmd {
67
struct io_uring_cmd_data data;
8+
struct iou_vec vec;
79
};
810

911
int io_uring_cmd(struct io_kiocb *req, unsigned int issue_flags);
1012
int io_uring_cmd_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe);
13+
void io_uring_cmd_cleanup(struct io_kiocb *req);
1114

1215
bool io_uring_try_cancel_uring_cmd(struct io_ring_ctx *ctx,
1316
struct io_uring_task *tctx, bool cancel_all);
17+
18+
void io_cmd_cache_free(const void *entry);

0 commit comments

Comments
 (0)