Skip to content

Commit 19a63c4

Browse files
isilenceaxboe
authored andcommitted
io_uring/rsrc: keep one global dummy_ubuf
We set empty registered buffers to dummy_ubuf as an optimisation. Currently, we allocate the dummy entry for each ring, whenever we can simply have one global instance. We're casting out const on assignment, it's fine as we're not going to change the content of the dummy, the constness gives us an extra layer of protection if sth ever goes wrong. Signed-off-by: Pavel Begunkov <asml.silence@gmail.com> Link: https://lore.kernel.org/r/e4a96dda35ab755914bc43f6781bba0df97ac489.1691757663.git.asml.silence@gmail.com Signed-off-by: Jens Axboe <axboe@kernel.dk>
1 parent b6b2bb5 commit 19a63c4

File tree

2 files changed

+10
-13
lines changed

2 files changed

+10
-13
lines changed

io_uring/io_uring.c

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -290,13 +290,6 @@ static __cold struct io_ring_ctx *io_ring_ctx_alloc(struct io_uring_params *p)
290290
goto err;
291291
if (io_alloc_hash_table(&ctx->cancel_table_locked, hash_bits))
292292
goto err;
293-
294-
ctx->dummy_ubuf = kzalloc(sizeof(*ctx->dummy_ubuf), GFP_KERNEL);
295-
if (!ctx->dummy_ubuf)
296-
goto err;
297-
/* set invalid range, so io_import_fixed() fails meeting it */
298-
ctx->dummy_ubuf->ubuf = -1UL;
299-
300293
if (percpu_ref_init(&ctx->refs, io_ring_ctx_ref_free,
301294
0, GFP_KERNEL))
302295
goto err;
@@ -335,7 +328,6 @@ static __cold struct io_ring_ctx *io_ring_ctx_alloc(struct io_uring_params *p)
335328
INIT_WQ_LIST(&ctx->submit_state.compl_reqs);
336329
return ctx;
337330
err:
338-
kfree(ctx->dummy_ubuf);
339331
kfree(ctx->cancel_table.hbs);
340332
kfree(ctx->cancel_table_locked.hbs);
341333
kfree(ctx->io_bl);
@@ -2897,7 +2889,6 @@ static __cold void io_ring_ctx_free(struct io_ring_ctx *ctx)
28972889
io_wq_put_hash(ctx->hash_map);
28982890
kfree(ctx->cancel_table.hbs);
28992891
kfree(ctx->cancel_table_locked.hbs);
2900-
kfree(ctx->dummy_ubuf);
29012892
kfree(ctx->io_bl);
29022893
xa_destroy(&ctx->io_bl_xa);
29032894
kfree(ctx);

io_uring/rsrc.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,12 @@ static int io_sqe_buffer_register(struct io_ring_ctx *ctx, struct iovec *iov,
3333
#define IORING_MAX_FIXED_FILES (1U << 20)
3434
#define IORING_MAX_REG_BUFFERS (1U << 14)
3535

36+
static const struct io_mapped_ubuf dummy_ubuf = {
37+
/* set invalid range, so io_import_fixed() fails meeting it */
38+
.ubuf = -1UL,
39+
.ubuf_end = 0,
40+
};
41+
3642
int __io_account_mem(struct user_struct *user, unsigned long nr_pages)
3743
{
3844
unsigned long page_limit, cur_pages, new_pages;
@@ -132,7 +138,7 @@ static void io_buffer_unmap(struct io_ring_ctx *ctx, struct io_mapped_ubuf **slo
132138
struct io_mapped_ubuf *imu = *slot;
133139
unsigned int i;
134140

135-
if (imu != ctx->dummy_ubuf) {
141+
if (imu != &dummy_ubuf) {
136142
for (i = 0; i < imu->nr_bvecs; i++)
137143
unpin_user_page(imu->bvec[i].bv_page);
138144
if (imu->acct_pages)
@@ -459,14 +465,14 @@ static int __io_sqe_buffers_update(struct io_ring_ctx *ctx,
459465
break;
460466

461467
i = array_index_nospec(up->offset + done, ctx->nr_user_bufs);
462-
if (ctx->user_bufs[i] != ctx->dummy_ubuf) {
468+
if (ctx->user_bufs[i] != &dummy_ubuf) {
463469
err = io_queue_rsrc_removal(ctx->buf_data, i,
464470
ctx->user_bufs[i]);
465471
if (unlikely(err)) {
466472
io_buffer_unmap(ctx, &imu);
467473
break;
468474
}
469-
ctx->user_bufs[i] = ctx->dummy_ubuf;
475+
ctx->user_bufs[i] = (struct io_mapped_ubuf *)&dummy_ubuf;
470476
}
471477

472478
ctx->user_bufs[i] = imu;
@@ -1077,7 +1083,7 @@ static int io_sqe_buffer_register(struct io_ring_ctx *ctx, struct iovec *iov,
10771083
int ret, nr_pages, i;
10781084
struct folio *folio = NULL;
10791085

1080-
*pimu = ctx->dummy_ubuf;
1086+
*pimu = (struct io_mapped_ubuf *)&dummy_ubuf;
10811087
if (!iov->iov_base)
10821088
return 0;
10831089

0 commit comments

Comments
 (0)