Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

io_uring/kbuf: use struct io_br_sel for multiple buffers picking

The networking side uses bundles, which is picking multiple buffers at
the same time. Pass in struct io_br_sel to those helpers.

Link: https://lore.kernel.org/r/20250821020750.598432-9-axboe@kernel.dk
Signed-off-by: Jens Axboe <axboe@kernel.dk>

+25 -23
+3 -2
io_uring/kbuf.c
··· 299 299 } 300 300 301 301 int io_buffers_select(struct io_kiocb *req, struct buf_sel_arg *arg, 302 - unsigned int issue_flags) 302 + struct io_br_sel *sel, unsigned int issue_flags) 303 303 { 304 304 struct io_ring_ctx *ctx = req->ctx; 305 305 struct io_buffer_list *bl; ··· 331 331 return ret; 332 332 } 333 333 334 - int io_buffers_peek(struct io_kiocb *req, struct buf_sel_arg *arg) 334 + int io_buffers_peek(struct io_kiocb *req, struct buf_sel_arg *arg, 335 + struct io_br_sel *sel) 335 336 { 336 337 struct io_ring_ctx *ctx = req->ctx; 337 338 struct io_buffer_list *bl;
+3 -2
io_uring/kbuf.h
··· 80 80 struct io_br_sel io_buffer_select(struct io_kiocb *req, size_t *len, 81 81 unsigned buf_group, unsigned int issue_flags); 82 82 int io_buffers_select(struct io_kiocb *req, struct buf_sel_arg *arg, 83 - unsigned int issue_flags); 84 - int io_buffers_peek(struct io_kiocb *req, struct buf_sel_arg *arg); 83 + struct io_br_sel *sel, unsigned int issue_flags); 84 + int io_buffers_peek(struct io_kiocb *req, struct buf_sel_arg *arg, 85 + struct io_br_sel *sel); 85 86 void io_destroy_buffers(struct io_ring_ctx *ctx); 86 87 87 88 int io_remove_buffers_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe);
+19 -19
io_uring/net.c
··· 586 586 } 587 587 588 588 static int io_send_select_buffer(struct io_kiocb *req, unsigned int issue_flags, 589 - struct io_async_msghdr *kmsg) 589 + struct io_br_sel *sel, struct io_async_msghdr *kmsg) 590 590 { 591 591 struct io_sr_msg *sr = io_kiocb_to_cmd(req, struct io_sr_msg); 592 - 593 - int ret; 594 592 struct buf_sel_arg arg = { 595 593 .iovs = &kmsg->fast_iov, 596 594 .max_len = min_not_zero(sr->len, INT_MAX), 597 595 .nr_iovs = 1, 598 596 .buf_group = sr->buf_group, 599 597 }; 598 + int ret; 600 599 601 600 if (kmsg->vec.iovec) { 602 601 arg.nr_iovs = kmsg->vec.nr; ··· 608 609 else 609 610 arg.mode |= KBUF_MODE_EXPAND; 610 611 611 - ret = io_buffers_select(req, &arg, issue_flags); 612 + ret = io_buffers_select(req, &arg, sel, issue_flags); 612 613 if (unlikely(ret < 0)) 613 614 return ret; 614 615 ··· 637 638 { 638 639 struct io_sr_msg *sr = io_kiocb_to_cmd(req, struct io_sr_msg); 639 640 struct io_async_msghdr *kmsg = req->async_data; 641 + struct io_br_sel sel = { }; 640 642 struct socket *sock; 641 643 unsigned flags; 642 644 int min_ret = 0; ··· 657 657 658 658 retry_bundle: 659 659 if (io_do_buffer_select(req)) { 660 - ret = io_send_select_buffer(req, issue_flags, kmsg); 660 + ret = io_send_select_buffer(req, issue_flags, &sel, kmsg); 661 661 if (ret) 662 662 return ret; 663 663 } ··· 1015 1015 { 1016 1016 struct io_sr_msg *sr = io_kiocb_to_cmd(req, struct io_sr_msg); 1017 1017 struct io_async_msghdr *kmsg = req->async_data; 1018 + struct io_br_sel sel = { }; 1018 1019 struct socket *sock; 1019 1020 unsigned flags; 1020 1021 int ret, min_ret = 0; ··· 1036 1035 1037 1036 retry_multishot: 1038 1037 if (io_do_buffer_select(req)) { 1039 - struct io_br_sel sel; 1040 1038 size_t len = sr->len; 1041 1039 1042 1040 sel = io_buffer_select(req, &len, sr->buf_group, issue_flags); ··· 1099 1099 } 1100 1100 1101 1101 static int io_recv_buf_select(struct io_kiocb *req, struct io_async_msghdr *kmsg, 1102 - size_t *len, unsigned int issue_flags) 1102 + struct io_br_sel *sel, unsigned int issue_flags) 1103 1103 { 1104 1104 struct io_sr_msg *sr = io_kiocb_to_cmd(req, struct io_sr_msg); 1105 1105 int ret; ··· 1124 1124 arg.mode |= KBUF_MODE_FREE; 1125 1125 } 1126 1126 1127 - if (*len) 1128 - arg.max_len = *len; 1127 + if (sel->val) 1128 + arg.max_len = sel->val; 1129 1129 else if (kmsg->msg.msg_inq > 1) 1130 - arg.max_len = min_not_zero(*len, (size_t) kmsg->msg.msg_inq); 1130 + arg.max_len = min_not_zero(sel->val, (size_t) kmsg->msg.msg_inq); 1131 1131 1132 1132 /* if mshot limited, ensure we don't go over */ 1133 1133 if (sr->flags & IORING_RECV_MSHOT_LIM) 1134 1134 arg.max_len = min_not_zero(arg.max_len, sr->mshot_total_len); 1135 - ret = io_buffers_peek(req, &arg); 1135 + ret = io_buffers_peek(req, &arg, sel); 1136 1136 if (unlikely(ret < 0)) 1137 1137 return ret; 1138 1138 ··· 1153 1153 iov_iter_init(&kmsg->msg.msg_iter, ITER_DEST, arg.iovs, ret, 1154 1154 arg.out_len); 1155 1155 } else { 1156 - struct io_br_sel sel; 1156 + size_t len = sel->val; 1157 1157 1158 - *len = sr->len; 1159 - sel = io_buffer_select(req, len, sr->buf_group, issue_flags); 1160 - if (!sel.addr) 1158 + *sel = io_buffer_select(req, &len, sr->buf_group, issue_flags); 1159 + if (!sel->addr) 1161 1160 return -ENOBUFS; 1162 - sr->buf = sel.addr; 1163 - sr->len = *len; 1161 + sr->buf = sel->addr; 1162 + sr->len = len; 1164 1163 map_ubuf: 1165 1164 ret = import_ubuf(ITER_DEST, sr->buf, sr->len, 1166 1165 &kmsg->msg.msg_iter); ··· 1174 1175 { 1175 1176 struct io_sr_msg *sr = io_kiocb_to_cmd(req, struct io_sr_msg); 1176 1177 struct io_async_msghdr *kmsg = req->async_data; 1178 + struct io_br_sel sel = { }; 1177 1179 struct socket *sock; 1178 1180 unsigned flags; 1179 1181 int ret, min_ret = 0; 1180 1182 bool force_nonblock = issue_flags & IO_URING_F_NONBLOCK; 1181 - size_t len = sr->len; 1182 1183 bool mshot_finished; 1183 1184 1184 1185 if (!(req->flags & REQ_F_POLLED) && ··· 1195 1196 1196 1197 retry_multishot: 1197 1198 if (io_do_buffer_select(req)) { 1198 - ret = io_recv_buf_select(req, kmsg, &len, issue_flags); 1199 + sel.val = sr->len; 1200 + ret = io_recv_buf_select(req, kmsg, &sel, issue_flags); 1199 1201 if (unlikely(ret < 0)) { 1200 1202 kmsg->msg.msg_inq = -1; 1201 1203 goto out_free;