Skip to content

Commit 0701db7

Browse files
committed
io_uring/rsrc: add an empty io_rsrc_node for sparse buffer entries
Rather than allocate an io_rsrc_node for an empty/sparse buffer entry, add a const entry that can be used for that. This just needs checking for writing the tag, and the put check needs to check for that sparse node rather than NULL for validity. This avoids allocating rsrc nodes for sparse buffer entries. Signed-off-by: Jens Axboe <[email protected]>
1 parent fbbb8e9 commit 0701db7

File tree

5 files changed

+41
-29
lines changed

5 files changed

+41
-29
lines changed

io_uring/io_uring.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2032,8 +2032,8 @@ static int io_init_req(struct io_ring_ctx *ctx, struct io_kiocb *req,
20322032
req->flags = (__force io_req_flags_t) sqe_flags;
20332033
req->cqe.user_data = READ_ONCE(sqe->user_data);
20342034
req->file = NULL;
2035-
req->rsrc_nodes[IORING_RSRC_FILE] = NULL;
2036-
req->rsrc_nodes[IORING_RSRC_BUFFER] = NULL;
2035+
req->rsrc_nodes[IORING_RSRC_FILE] = rsrc_empty_node;
2036+
req->rsrc_nodes[IORING_RSRC_BUFFER] = rsrc_empty_node;
20372037
req->task = current;
20382038
req->cancel_seq_set = false;
20392039

io_uring/notif.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,8 @@ struct io_kiocb *io_alloc_notif(struct io_ring_ctx *ctx)
117117
notif->file = NULL;
118118
notif->task = current;
119119
io_get_task_refs(1);
120-
notif->rsrc_nodes[IORING_RSRC_FILE] = NULL;
121-
notif->rsrc_nodes[IORING_RSRC_BUFFER] = NULL;
120+
notif->rsrc_nodes[IORING_RSRC_FILE] = rsrc_empty_node;
121+
notif->rsrc_nodes[IORING_RSRC_BUFFER] = rsrc_empty_node;
122122

123123
nd = io_notif_to_data(notif);
124124
nd->zc_report = false;

io_uring/rsrc.c

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,11 @@ static const struct io_mapped_ubuf dummy_ubuf = {
3838
.len = UINT_MAX,
3939
};
4040

41+
const struct io_rsrc_node empty_node = {
42+
.type = IORING_RSRC_BUFFER,
43+
.buf = (struct io_mapped_ubuf *) &dummy_ubuf,
44+
};
45+
4146
int __io_account_mem(struct user_struct *user, unsigned long nr_pages)
4247
{
4348
unsigned long page_limit, cur_pages, new_pages;
@@ -144,7 +149,8 @@ static void io_rsrc_data_free(struct io_rsrc_data *data)
144149
for (i = 0; i < data->nr; i++) {
145150
struct io_rsrc_node *node = data->nodes[i];
146151

147-
io_put_rsrc_node(node);
152+
if (node)
153+
io_put_rsrc_node(node);
148154
}
149155
kvfree(data->nodes);
150156
kfree(data);
@@ -229,7 +235,8 @@ static int __io_sqe_files_update(struct io_ring_ctx *ctx,
229235
break;
230236
}
231237
ctx->file_table.nodes[i] = node;
232-
node->tag = tag;
238+
if (tag)
239+
node->tag = tag;
233240
io_fixed_file_set(node, file);
234241
io_file_bitmap_set(&ctx->file_table, i);
235242
}
@@ -281,10 +288,12 @@ static int __io_sqe_buffers_update(struct io_ring_ctx *ctx,
281288
err = PTR_ERR(node);
282289
break;
283290
}
284-
io_put_rsrc_node(ctx->user_bufs[i]);
291+
if (ctx->user_bufs[i])
292+
io_put_rsrc_node(ctx->user_bufs[i]);
285293

286294
ctx->user_bufs[i] = node;
287-
node->tag = tag;
295+
if (tag)
296+
node->tag = tag;
288297
if (ctx->compat)
289298
user_data += sizeof(struct compat_iovec);
290299
else
@@ -600,8 +609,10 @@ static void __io_sqe_buffers_unregister(struct io_ring_ctx *ctx)
600609
lockdep_assert_held(&ctx->uring_lock);
601610

602611
for (i = 0; i < ctx->nr_user_bufs; i++) {
603-
io_put_rsrc_node(ctx->user_bufs[i]);
604-
ctx->user_bufs[i] = NULL;
612+
if (ctx->user_bufs[i]) {
613+
io_put_rsrc_node(ctx->user_bufs[i]);
614+
ctx->user_bufs[i] = NULL;
615+
}
605616
}
606617
kvfree(ctx->user_bufs);
607618
ctx->user_bufs = NULL;
@@ -799,11 +810,6 @@ static struct io_rsrc_node *io_sqe_buffer_register(struct io_ring_ctx *ctx,
799810
return ERR_PTR(-ENOMEM);
800811
node->buf = NULL;
801812

802-
if (!iov->iov_base) {
803-
node->buf = (struct io_mapped_ubuf *) &dummy_ubuf;
804-
return node;
805-
}
806-
807813
ret = -ENOMEM;
808814
pages = io_pin_pages((unsigned long) iov->iov_base, iov->iov_len,
809815
&nr_pages);
@@ -927,7 +933,8 @@ int io_sqe_buffers_register(struct io_ring_ctx *ctx, void __user *arg,
927933
ret = PTR_ERR(node);
928934
break;
929935
}
930-
node->tag = tag;
936+
if (tag)
937+
node->tag = tag;
931938
ctx->user_bufs[i] = node;
932939
}
933940

@@ -1028,18 +1035,18 @@ static int io_clone_buffers(struct io_ring_ctx *ctx, struct io_ring_ctx *src_ctx
10281035
goto out_free_data;
10291036

10301037
for (i = 0; i < nbufs; i++) {
1031-
struct io_mapped_ubuf *imu = src_ctx->user_bufs[i]->buf;
1038+
struct io_rsrc_node *src_node = src_ctx->user_bufs[i];
10321039
struct io_rsrc_node *dst_node;
10331040

1034-
dst_node = io_rsrc_node_alloc(ctx, IORING_RSRC_BUFFER);
1035-
if (!dst_node)
1036-
goto out_put_free;
1037-
1038-
if (imu == &dummy_ubuf) {
1039-
dst_node->buf = (struct io_mapped_ubuf *) &dummy_ubuf;
1041+
if (src_node == rsrc_empty_node) {
1042+
dst_node = rsrc_empty_node;
10401043
} else {
1041-
refcount_inc(&imu->refs);
1042-
dst_node->buf = imu;
1044+
dst_node = io_rsrc_node_alloc(ctx, IORING_RSRC_BUFFER);
1045+
if (!dst_node)
1046+
goto out_put_free;
1047+
1048+
refcount_inc(&src_node->buf->refs);
1049+
dst_node->buf = src_node->buf;
10431050
}
10441051
user_bufs[i] = dst_node;
10451052
}

io_uring/rsrc.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,12 @@ int io_register_rsrc_update(struct io_ring_ctx *ctx, void __user *arg,
7070
int io_register_rsrc(struct io_ring_ctx *ctx, void __user *arg,
7171
unsigned int size, unsigned int type);
7272

73+
extern const struct io_rsrc_node empty_node;
74+
#define rsrc_empty_node (struct io_rsrc_node *) &empty_node
75+
7376
static inline void io_put_rsrc_node(struct io_rsrc_node *node)
7477
{
75-
if (node && !--node->refs)
78+
if (node != rsrc_empty_node && !--node->refs)
7679
io_free_rsrc_node(node);
7780
}
7881

@@ -85,8 +88,10 @@ static inline void io_req_put_rsrc_nodes(struct io_kiocb *req)
8588
static inline void io_req_assign_rsrc_node(struct io_kiocb *req,
8689
struct io_rsrc_node *node)
8790
{
88-
node->refs++;
89-
req->rsrc_nodes[node->type] = node;
91+
if (node != rsrc_empty_node) {
92+
node->refs++;
93+
req->rsrc_nodes[node->type] = node;
94+
}
9095
}
9196

9297
int io_files_update(struct io_kiocb *req, unsigned int issue_flags);

io_uring/splice.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ static int __io_splice_prep(struct io_kiocb *req,
3535
if (unlikely(sp->flags & ~valid_flags))
3636
return -EINVAL;
3737
sp->splice_fd_in = READ_ONCE(sqe->splice_fd_in);
38-
sp->rsrc_node = NULL;
38+
sp->rsrc_node = rsrc_empty_node;
3939
req->flags |= REQ_F_FORCE_ASYNC;
4040
return 0;
4141
}

0 commit comments

Comments
 (0)