History

io_uring: support buffer selection for OP_READ and OP_RECV

If a server process has tons of pending socket connections, generally it uses epoll to wait for activity. When the socket is ready for reading (or writing), the task can select a buffer and issue a recv/send on the given fd. Now that we have fast (non-async thread) support, a task can have tons of pending reads or writes pending. But that means they need buffers to back that data, and if the number of connections is high enough, having them preallocated for all possible connections is unfeasible. With IORING_OP_PROVIDE_BUFFERS, an application can register buffers to use for any request. The request then sets IOSQE_BUFFER_SELECT in the sqe, and a given group ID in sqe->buf_group. When the fd becomes ready, a free buffer from the specified group is selected. If none are available, the request is terminated with -ENOBUFS. If successful, the CQE on completion will contain the buffer ID chosen in the cqe->flags member, encoded as: (buffer_id << IORING_CQE_BUFFER_SHIFT) | IORING_CQE_F_BUFFER; Once a buffer has been consumed by a request, it is no longer available and must be registered again with IORING_OP_PROVIDE_BUFFERS. Requests need to support this feature. For now, IORING_OP_READ and IORING_OP_RECV support it. This is checked on SQE submission, a CQE with res == -EOPNOTSUPP will be posted if attempted on unsupported requests.

Jens Axboe committed 6 years ago

Commit bcda7ba1 parent ddf03222 files · +199 −39Browse files

Unified · Split

2 files
  1. fs/io_uring.c +185 −39
  2. include/uapi/linux/io_uring.h +14 −0
fs/io_uring.c+185−39
@@ -395,7 +395,9 @@ struct io_sr_msg { · 394 unmodified lines
395 void __user *buf;395 void __user *buf;
396 };396 };
397 int msg_flags;397 int msg_flags;
398 int bgid;
398 size_t len;399 size_t len;
400 struct io_buffer *kbuf;
399};401};
400 402
401struct io_open {403struct io_open {
@@ -490,6 +492,7 @@ enum { · 88 unmodified lines
490 REQ_F_LINK_BIT = IOSQE_IO_LINK_BIT,492 REQ_F_LINK_BIT = IOSQE_IO_LINK_BIT,
491 REQ_F_HARDLINK_BIT = IOSQE_IO_HARDLINK_BIT,493 REQ_F_HARDLINK_BIT = IOSQE_IO_HARDLINK_BIT,
492 REQ_F_FORCE_ASYNC_BIT = IOSQE_ASYNC_BIT,494 REQ_F_FORCE_ASYNC_BIT = IOSQE_ASYNC_BIT,
495 REQ_F_BUFFER_SELECT_BIT = IOSQE_BUFFER_SELECT_BIT,
493 496
494 REQ_F_LINK_NEXT_BIT,497 REQ_F_LINK_NEXT_BIT,
495 REQ_F_FAIL_LINK_BIT,498 REQ_F_FAIL_LINK_BIT,
@@ -506,6 +509,7 @@ enum { · 10 unmodified lines
506 REQ_F_NEED_CLEANUP_BIT,509 REQ_F_NEED_CLEANUP_BIT,
507 REQ_F_OVERFLOW_BIT,510 REQ_F_OVERFLOW_BIT,
508 REQ_F_POLLED_BIT,511 REQ_F_POLLED_BIT,
512 REQ_F_BUFFER_SELECTED_BIT,
509};513};
510 514
511enum {515enum {
@@ -519,6 +523,8 @@ enum { · 7 unmodified lines
519 REQ_F_HARDLINK = BIT(REQ_F_HARDLINK_BIT),523 REQ_F_HARDLINK = BIT(REQ_F_HARDLINK_BIT),
520 /* IOSQE_ASYNC */524 /* IOSQE_ASYNC */
521 REQ_F_FORCE_ASYNC = BIT(REQ_F_FORCE_ASYNC_BIT),525 REQ_F_FORCE_ASYNC = BIT(REQ_F_FORCE_ASYNC_BIT),
526 /* IOSQE_BUFFER_SELECT */
527 REQ_F_BUFFER_SELECT = BIT(REQ_F_BUFFER_SELECT_BIT),
522 528
523 /* already grabbed next link */529 /* already grabbed next link */
524 REQ_F_LINK_NEXT = BIT(REQ_F_LINK_NEXT_BIT),530 REQ_F_LINK_NEXT = BIT(REQ_F_LINK_NEXT_BIT),
@@ -550,6 +556,8 @@ enum { · 25 unmodified lines
550 REQ_F_OVERFLOW = BIT(REQ_F_OVERFLOW_BIT),556 REQ_F_OVERFLOW = BIT(REQ_F_OVERFLOW_BIT),
551 /* already went through poll handler */557 /* already went through poll handler */
552 REQ_F_POLLED = BIT(REQ_F_POLLED_BIT),558 REQ_F_POLLED = BIT(REQ_F_POLLED_BIT),
559 /* buffer already selected */
560 REQ_F_BUFFER_SELECTED = BIT(REQ_F_BUFFER_SELECTED_BIT),
553};561};
554 562
555struct async_poll {563struct async_poll {
@@ -612,6 +620,7 @@ struct io_kiocb { · 56 unmodified lines
612 struct callback_head task_work;620 struct callback_head task_work;
613 struct hlist_node hash_node;621 struct hlist_node hash_node;
614 struct async_poll *apoll;622 struct async_poll *apoll;
623 int cflags;
615 };624 };
616 struct io_wq_work work;625 struct io_wq_work work;
617 };626 };
@@ -661,6 +670,8 @@ struct io_op_def { · 43 unmodified lines
661 /* set if opcode supports polled "wait" */670 /* set if opcode supports polled "wait" */
662 unsigned pollin : 1;671 unsigned pollin : 1;
663 unsigned pollout : 1;672 unsigned pollout : 1;
673 /* op supports buffer selection */
674 unsigned buffer_select : 1;
664};675};
665 676
666static const struct io_op_def io_op_defs[] = {677static const struct io_op_def io_op_defs[] = {
@@ -770,6 +781,7 @@ static const struct io_op_def io_op_defs[] = { · 103 unmodified lines
770 .needs_file = 1,781 .needs_file = 1,
771 .unbound_nonreg_file = 1,782 .unbound_nonreg_file = 1,
772 .pollin = 1,783 .pollin = 1,
784 .buffer_select = 1,
773 },785 },
774 [IORING_OP_WRITE] = {786 [IORING_OP_WRITE] = {
775 .needs_mm = 1,787 .needs_mm = 1,
@@ -794,6 +806,7 @@ static const struct io_op_def io_op_defs[] = { · 18 unmodified lines
794 .needs_file = 1,806 .needs_file = 1,
795 .unbound_nonreg_file = 1,807 .unbound_nonreg_file = 1,
796 .pollin = 1,808 .pollin = 1,
809 .buffer_select = 1,
797 },810 },
798 [IORING_OP_OPENAT2] = {811 [IORING_OP_OPENAT2] = {
799 .needs_file = 1,812 .needs_file = 1,
@@ -1170,7 +1183,7 @@ static bool io_cqring_overflow_flush(struct io_ring_ctx *ctx, bool force) · 370 unmodified lines
1170 if (cqe) {1183 if (cqe) {
1171 WRITE_ONCE(cqe->user_data, req->user_data);1184 WRITE_ONCE(cqe->user_data, req->user_data);
1172 WRITE_ONCE(cqe->res, req->result);1185 WRITE_ONCE(cqe->res, req->result);
1173 WRITE_ONCE(cqe->flags, 0);1186 WRITE_ONCE(cqe->flags, req->cflags);
1174 } else {1187 } else {
1175 WRITE_ONCE(ctx->rings->cq_overflow,1188 WRITE_ONCE(ctx->rings->cq_overflow,
1176 atomic_inc_return(&ctx->cached_cq_overflow));1189 atomic_inc_return(&ctx->cached_cq_overflow));
@@ -1194,7 +1207,7 @@ static bool io_cqring_overflow_flush(struct io_ring_ctx *ctx, bool force) · 17 unmodified lines
1194 return cqe != NULL;1207 return cqe != NULL;
1195}1208}
1196 1209
1197static void io_cqring_fill_event(struct io_kiocb *req, long res)1210static void __io_cqring_fill_event(struct io_kiocb *req, long res, long cflags)
1198{1211{
1199 struct io_ring_ctx *ctx = req->ctx;1212 struct io_ring_ctx *ctx = req->ctx;
1200 struct io_uring_cqe *cqe;1213 struct io_uring_cqe *cqe;
@@ -1210,7 +1223,7 @@ static void io_cqring_fill_event(struct io_kiocb *req, long res) · 9 unmodified lines
1210 if (likely(cqe)) {1223 if (likely(cqe)) {
1211 WRITE_ONCE(cqe->user_data, req->user_data);1224 WRITE_ONCE(cqe->user_data, req->user_data);
1212 WRITE_ONCE(cqe->res, res);1225 WRITE_ONCE(cqe->res, res);
1213 WRITE_ONCE(cqe->flags, 0);1226 WRITE_ONCE(cqe->flags, cflags);
1214 } else if (ctx->cq_overflow_flushed) {1227 } else if (ctx->cq_overflow_flushed) {
1215 WRITE_ONCE(ctx->rings->cq_overflow,1228 WRITE_ONCE(ctx->rings->cq_overflow,
1216 atomic_inc_return(&ctx->cached_cq_overflow));1229 atomic_inc_return(&ctx->cached_cq_overflow));
@@ -1222,23 +1235,34 @@ static void io_cqring_fill_event(struct io_kiocb *req, long res) · 5 unmodified lines
1222 req->flags |= REQ_F_OVERFLOW;1235 req->flags |= REQ_F_OVERFLOW;
1223 refcount_inc(&req->refs);1236 refcount_inc(&req->refs);
1224 req->result = res;1237 req->result = res;
1238 req->cflags = cflags;
1225 list_add_tail(&req->list, &ctx->cq_overflow_list);1239 list_add_tail(&req->list, &ctx->cq_overflow_list);
1226 }1240 }
1227}1241}
1228 1242
1229static void io_cqring_add_event(struct io_kiocb *req, long res)1243static void io_cqring_fill_event(struct io_kiocb *req, long res)
1244{
1245 __io_cqring_fill_event(req, res, 0);
1246}
1247
1248static void __io_cqring_add_event(struct io_kiocb *req, long res, long cflags)
1230{1249{
1231 struct io_ring_ctx *ctx = req->ctx;1250 struct io_ring_ctx *ctx = req->ctx;
1232 unsigned long flags;1251 unsigned long flags;
1233 1252
1234 spin_lock_irqsave(&ctx->completion_lock, flags);1253 spin_lock_irqsave(&ctx->completion_lock, flags);
1235 io_cqring_fill_event(req, res);1254 __io_cqring_fill_event(req, res, cflags);
1236 io_commit_cqring(ctx);1255 io_commit_cqring(ctx);
1237 spin_unlock_irqrestore(&ctx->completion_lock, flags);1256 spin_unlock_irqrestore(&ctx->completion_lock, flags);
1238 1257
1239 io_cqring_ev_posted(ctx);1258 io_cqring_ev_posted(ctx);
1240}1259}
1241 1260
1261static void io_cqring_add_event(struct io_kiocb *req, long res)
1262{
1263 __io_cqring_add_event(req, res, 0);
1264}
1265
1242static inline bool io_is_fallback_req(struct io_kiocb *req)1266static inline bool io_is_fallback_req(struct io_kiocb *req)
1243{1267{
1244 return req == (struct io_kiocb *)1268 return req == (struct io_kiocb *)
@@ -1660,6 +1684,18 @@ static inline bool io_req_multi_free(struct req_batch *rb, struct io_kiocb *req) · 415 unmodified lines
1660 return true;1684 return true;
1661}1685}
1662 1686
1687static int io_put_kbuf(struct io_kiocb *req)
1688{
1689 struct io_buffer *kbuf = (struct io_buffer *) req->rw.addr;
1690 int cflags;
1691
1692 cflags = kbuf->bid << IORING_CQE_BUFFER_SHIFT;
1693 cflags |= IORING_CQE_F_BUFFER;
1694 req->rw.addr = 0;
1695 kfree(kbuf);
1696 return cflags;
1697}
1698
1663/*1699/*
1664 * Find and free completed poll iocbs1700 * Find and free completed poll iocbs
1665 */1701 */
@@ -1671,10 +1707,15 @@ static void io_iopoll_complete(struct io_ring_ctx *ctx, unsigned int *nr_events, · 5 unmodified lines
1671 1707
1672 rb.to_free = rb.need_iter = 0;1708 rb.to_free = rb.need_iter = 0;
1673 while (!list_empty(done)) {1709 while (!list_empty(done)) {
1710 int cflags = 0;
1711
1674 req = list_first_entry(done, struct io_kiocb, list);1712 req = list_first_entry(done, struct io_kiocb, list);
1675 list_del(&req->list);1713 list_del(&req->list);
1676 1714
1677 io_cqring_fill_event(req, req->result);1715 if (req->flags & REQ_F_BUFFER_SELECTED)
1716 cflags = io_put_kbuf(req);
1717
1718 __io_cqring_fill_event(req, req->result, cflags);
1678 (*nr_events)++;1719 (*nr_events)++;
1679 1720
1680 if (refcount_dec_and_test(&req->refs) &&1721 if (refcount_dec_and_test(&req->refs) &&
@@ -1849,13 +1890,16 @@ static inline void req_set_fail_links(struct io_kiocb *req) · 168 unmodified lines
1849static void io_complete_rw_common(struct kiocb *kiocb, long res)1890static void io_complete_rw_common(struct kiocb *kiocb, long res)
1850{1891{
1851 struct io_kiocb *req = container_of(kiocb, struct io_kiocb, rw.kiocb);1892 struct io_kiocb *req = container_of(kiocb, struct io_kiocb, rw.kiocb);
1893 int cflags = 0;
1852 1894
1853 if (kiocb->ki_flags & IOCB_WRITE)1895 if (kiocb->ki_flags & IOCB_WRITE)
1854 kiocb_end_write(req);1896 kiocb_end_write(req);
1855 1897
1856 if (res != req->result)1898 if (res != req->result)
1857 req_set_fail_links(req);1899 req_set_fail_links(req);
1858 io_cqring_add_event(req, res);1900 if (req->flags & REQ_F_BUFFER_SELECTED)
1901 cflags = io_put_kbuf(req);
1902 __io_cqring_add_event(req, res, cflags);
1859}1903}
1860 1904
1861static void io_complete_rw(struct kiocb *kiocb, long res, long res2)1905static void io_complete_rw(struct kiocb *kiocb, long res, long res2)
@@ -2033,7 +2077,7 @@ static int io_prep_rw(struct io_kiocb *req, const struct io_uring_sqe *sqe, · 171 unmodified lines
2033 2077
2034 req->rw.addr = READ_ONCE(sqe->addr);2078 req->rw.addr = READ_ONCE(sqe->addr);
2035 req->rw.len = READ_ONCE(sqe->len);2079 req->rw.len = READ_ONCE(sqe->len);
2036 /* we own ->private, reuse it for the buffer index */2080 /* we own ->private, reuse it for the buffer index / buffer ID */
2037 req->rw.kiocb.private = (void *) (unsigned long)2081 req->rw.kiocb.private = (void *) (unsigned long)
2038 READ_ONCE(sqe->buf_index);2082 READ_ONCE(sqe->buf_index);
2039 return 0;2083 return 0;
@@ -2146,8 +2190,61 @@ static ssize_t io_import_fixed(struct io_kiocb *req, int rw, · 106 unmodified lines
2146 return len;2190 return len;
2147}2191}
2148 2192
2193static void io_ring_submit_unlock(struct io_ring_ctx *ctx, bool needs_lock)
2194{
2195 if (needs_lock)
2196 mutex_unlock(&ctx->uring_lock);
2197}
2198
2199static void io_ring_submit_lock(struct io_ring_ctx *ctx, bool needs_lock)
2200{
2201 /*
2202 * "Normal" inline submissions always hold the uring_lock, since we
2203 * grab it from the system call. Same is true for the SQPOLL offload.
2204 * The only exception is when we've detached the request and issue it
2205 * from an async worker thread, grab the lock for that case.
2206 */
2207 if (needs_lock)
2208 mutex_lock(&ctx->uring_lock);
2209}
2210
2211static struct io_buffer *io_buffer_select(struct io_kiocb *req, size_t *len,
2212 int bgid, struct io_buffer *kbuf,
2213 bool needs_lock)
2214{
2215 struct io_buffer *head;
2216
2217 if (req->flags & REQ_F_BUFFER_SELECTED)
2218 return kbuf;
2219
2220 io_ring_submit_lock(req->ctx, needs_lock);
2221
2222 lockdep_assert_held(&req->ctx->uring_lock);
2223
2224 head = idr_find(&req->ctx->io_buffer_idr, bgid);
2225 if (head) {
2226 if (!list_empty(&head->list)) {
2227 kbuf = list_last_entry(&head->list, struct io_buffer,
2228 list);
2229 list_del(&kbuf->list);
2230 } else {
2231 kbuf = head;
2232 idr_remove(&req->ctx->io_buffer_idr, bgid);
2233 }
2234 if (*len > kbuf->len)
2235 *len = kbuf->len;
2236 } else {
2237 kbuf = ERR_PTR(-ENOBUFS);
2238 }
2239
2240 io_ring_submit_unlock(req->ctx, needs_lock);
2241
2242 return kbuf;
2243}
2244
2149static ssize_t io_import_iovec(int rw, struct io_kiocb *req,2245static ssize_t io_import_iovec(int rw, struct io_kiocb *req,
2150 struct iovec **iovec, struct iov_iter *iter)2246 struct iovec **iovec, struct iov_iter *iter,
2247 bool needs_lock)
2151{2248{
2152 void __user *buf = u64_to_user_ptr(req->rw.addr);2249 void __user *buf = u64_to_user_ptr(req->rw.addr);
2153 size_t sqe_len = req->rw.len;2250 size_t sqe_len = req->rw.len;
@@ -2159,12 +2256,29 @@ static ssize_t io_import_iovec(int rw, struct io_kiocb *req, · 5 unmodified lines
2159 return io_import_fixed(req, rw, iter);2256 return io_import_fixed(req, rw, iter);
2160 }2257 }
2161 2258
2162 /* buffer index only valid with fixed read/write */2259 /* buffer index only valid with fixed read/write, or buffer select */
2163 if (req->rw.kiocb.private)2260 if (req->rw.kiocb.private && !(req->flags & REQ_F_BUFFER_SELECT))
2164 return -EINVAL;2261 return -EINVAL;
2165 2262
2166 if (opcode == IORING_OP_READ || opcode == IORING_OP_WRITE) {2263 if (opcode == IORING_OP_READ || opcode == IORING_OP_WRITE) {
2167 ssize_t ret;2264 ssize_t ret;
2265
2266 if (req->flags & REQ_F_BUFFER_SELECT) {
2267 struct io_buffer *kbuf = (struct io_buffer *) req->rw.addr;
2268 int bgid;
2269
2270 bgid = (int) (unsigned long) req->rw.kiocb.private;
2271 kbuf = io_buffer_select(req, &sqe_len, bgid, kbuf,
2272 needs_lock);
2273 if (IS_ERR(kbuf)) {
2274 *iovec = NULL;
2275 return PTR_ERR(kbuf);
2276 }
2277 req->rw.addr = (u64) kbuf;
2278 req->flags |= REQ_F_BUFFER_SELECTED;
2279 buf = u64_to_user_ptr(kbuf->addr);
2280 }
2281
2168 ret = import_single_range(rw, buf, sqe_len, *iovec, iter);2282 ret = import_single_range(rw, buf, sqe_len, *iovec, iter);
2169 *iovec = NULL;2283 *iovec = NULL;
2170 return ret < 0 ? ret : sqe_len;2284 return ret < 0 ? ret : sqe_len;
@@ -2307,7 +2421,7 @@ static int io_read_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe, · 136 unmodified lines
2307 io = req->io;2421 io = req->io;
2308 io->rw.iov = io->rw.fast_iov;2422 io->rw.iov = io->rw.fast_iov;
2309 req->io = NULL;2423 req->io = NULL;
2310 ret = io_import_iovec(READ, req, &io->rw.iov, &iter);2424 ret = io_import_iovec(READ, req, &io->rw.iov, &iter, !force_nonblock);
2311 req->io = io;2425 req->io = io;
2312 if (ret < 0)2426 if (ret < 0)
2313 return ret;2427 return ret;
@@ -2324,7 +2438,7 @@ static int io_read(struct io_kiocb *req, bool force_nonblock) · 10 unmodified lines
2324 size_t iov_count;2438 size_t iov_count;
2325 ssize_t io_size, ret;2439 ssize_t io_size, ret;
2326 2440
2327 ret = io_import_iovec(READ, req, &iovec, &iter);2441 ret = io_import_iovec(READ, req, &iovec, &iter, !force_nonblock);
2328 if (ret < 0)2442 if (ret < 0)
2329 return ret;2443 return ret;
2330 2444
@@ -2396,7 +2510,7 @@ static int io_write_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe, · 65 unmodified lines
2396 io = req->io;2510 io = req->io;
2397 io->rw.iov = io->rw.fast_iov;2511 io->rw.iov = io->rw.fast_iov;
2398 req->io = NULL;2512 req->io = NULL;
2399 ret = io_import_iovec(WRITE, req, &io->rw.iov, &iter);2513 ret = io_import_iovec(WRITE, req, &io->rw.iov, &iter, !force_nonblock);
2400 req->io = io;2514 req->io = io;
2401 if (ret < 0)2515 if (ret < 0)
2402 return ret;2516 return ret;
@@ -2413,7 +2527,7 @@ static int io_write(struct io_kiocb *req, bool force_nonblock) · 10 unmodified lines
2413 size_t iov_count;2527 size_t iov_count;
2414 ssize_t ret, io_size;2528 ssize_t ret, io_size;
2415 2529
2416 ret = io_import_iovec(WRITE, req, &iovec, &iter);2530 ret = io_import_iovec(WRITE, req, &iovec, &iter, !force_nonblock);
2417 if (ret < 0)2531 if (ret < 0)
2418 return ret;2532 return ret;
2419 2533
@@ -2850,24 +2964,6 @@ static int io_add_buffers(struct io_provide_buf *pbuf, struct io_buffer **head) · 430 unmodified lines
2850 return i ? i : -ENOMEM;2964 return i ? i : -ENOMEM;
2851}2965}
2852 2966
2853static void io_ring_submit_unlock(struct io_ring_ctx *ctx, bool needs_lock)
2854{
2855 if (needs_lock)
2856 mutex_unlock(&ctx->uring_lock);
2857}
2858
2859static void io_ring_submit_lock(struct io_ring_ctx *ctx, bool needs_lock)
2860{
2861 /*
2862 * "Normal" inline submissions always hold the uring_lock, since we
2863 * grab it from the system call. Same is true for the SQPOLL offload.
2864 * The only exception is when we've detached the request and issue it
2865 * from an async worker thread, grab the lock for that case.
2866 */
2867 if (needs_lock)
2868 mutex_lock(&ctx->uring_lock);
2869}
2870
2871static int io_provide_buffers(struct io_kiocb *req, bool force_nonblock)2967static int io_provide_buffers(struct io_kiocb *req, bool force_nonblock)
2872{2968{
2873 struct io_provide_buf *p = &req->pbuf;2969 struct io_provide_buf *p = &req->pbuf;
@@ -3390,6 +3486,27 @@ static int io_send(struct io_kiocb *req, bool force_nonblock) · 516 unmodified lines
3390#endif3486#endif
3391}3487}
3392 3488
3489static struct io_buffer *io_recv_buffer_select(struct io_kiocb *req,
3490 int *cflags, bool needs_lock)
3491{
3492 struct io_sr_msg *sr = &req->sr_msg;
3493 struct io_buffer *kbuf;
3494
3495 if (!(req->flags & REQ_F_BUFFER_SELECT))
3496 return NULL;
3497
3498 kbuf = io_buffer_select(req, &sr->len, sr->bgid, sr->kbuf, needs_lock);
3499 if (IS_ERR(kbuf))
3500 return kbuf;
3501
3502 sr->kbuf = kbuf;
3503 req->flags |= REQ_F_BUFFER_SELECTED;
3504
3505 *cflags = kbuf->bid << IORING_CQE_BUFFER_SHIFT;
3506 *cflags |= IORING_CQE_F_BUFFER;
3507 return kbuf;
3508}
3509
3393static int io_recvmsg_prep(struct io_kiocb *req,3510static int io_recvmsg_prep(struct io_kiocb *req,
3394 const struct io_uring_sqe *sqe)3511 const struct io_uring_sqe *sqe)
3395{3512{
@@ -3401,6 +3518,7 @@ static int io_recvmsg_prep(struct io_kiocb *req, · 5 unmodified lines
3401 sr->msg_flags = READ_ONCE(sqe->msg_flags);3518 sr->msg_flags = READ_ONCE(sqe->msg_flags);
3402 sr->msg = u64_to_user_ptr(READ_ONCE(sqe->addr));3519 sr->msg = u64_to_user_ptr(READ_ONCE(sqe->addr));
3403 sr->len = READ_ONCE(sqe->len);3520 sr->len = READ_ONCE(sqe->len);
3521 sr->bgid = READ_ONCE(sqe->buf_group);
3404 3522
3405#ifdef CONFIG_COMPAT3523#ifdef CONFIG_COMPAT
3406 if (req->ctx->compat)3524 if (req->ctx->compat)
@@ -3490,8 +3608,9 @@ static int io_recvmsg(struct io_kiocb *req, bool force_nonblock) · 83 unmodified lines
3490static int io_recv(struct io_kiocb *req, bool force_nonblock)3608static int io_recv(struct io_kiocb *req, bool force_nonblock)
3491{3609{
3492#if defined(CONFIG_NET)3610#if defined(CONFIG_NET)
3611 struct io_buffer *kbuf = NULL;
3493 struct socket *sock;3612 struct socket *sock;
3494 int ret;3613 int ret, cflags = 0;
3495 3614
3496 if (unlikely(req->ctx->flags & IORING_SETUP_IOPOLL))3615 if (unlikely(req->ctx->flags & IORING_SETUP_IOPOLL))
3497 return -EINVAL;3616 return -EINVAL;
@@ -3499,15 +3618,25 @@ static int io_recv(struct io_kiocb *req, bool force_nonblock) · 1 unmodified line
3499 sock = sock_from_file(req->file, &ret);3618 sock = sock_from_file(req->file, &ret);
3500 if (sock) {3619 if (sock) {
3501 struct io_sr_msg *sr = &req->sr_msg;3620 struct io_sr_msg *sr = &req->sr_msg;
3621 void __user *buf = sr->buf;
3502 struct msghdr msg;3622 struct msghdr msg;
3503 struct iovec iov;3623 struct iovec iov;
3504 unsigned flags;3624 unsigned flags;
3505 3625
3506 ret = import_single_range(READ, sr->buf, sr->len, &iov,3626 kbuf = io_recv_buffer_select(req, &cflags, !force_nonblock);
3627 if (IS_ERR(kbuf))
3628 return PTR_ERR(kbuf);
3629 else if (kbuf)
3630 buf = u64_to_user_ptr(kbuf->addr);
3631
3632 ret = import_single_range(READ, buf, sr->len, &iov,
3507 &msg.msg_iter);3633 &msg.msg_iter);
3508 if (ret)3634 if (ret) {
3635 kfree(kbuf);
3509 return ret;3636 return ret;
3637 }
3510 3638
3639 req->flags |= REQ_F_NEED_CLEANUP;
3511 msg.msg_name = NULL;3640 msg.msg_name = NULL;
3512 msg.msg_control = NULL;3641 msg.msg_control = NULL;
3513 msg.msg_controllen = 0;3642 msg.msg_controllen = 0;
@@ -3528,7 +3657,9 @@ static int io_recv(struct io_kiocb *req, bool force_nonblock) · 14 unmodified lines
3528 ret = -EINTR;3657 ret = -EINTR;
3529 }3658 }
3530 3659
3531 io_cqring_add_event(req, ret);3660 kfree(kbuf);
3661 req->flags &= ~REQ_F_NEED_CLEANUP;
3662 __io_cqring_add_event(req, ret, cflags);
3532 if (ret < 0)3663 if (ret < 0)
3533 req_set_fail_links(req);3664 req_set_fail_links(req);
3534 io_put_req(req);3665 io_put_req(req);
@@ -4566,6 +4697,9 @@ static void io_cleanup_req(struct io_kiocb *req) · 1031 unmodified lines
4566 case IORING_OP_READV:4697 case IORING_OP_READV:
4567 case IORING_OP_READ_FIXED:4698 case IORING_OP_READ_FIXED:
4568 case IORING_OP_READ:4699 case IORING_OP_READ:
4700 if (req->flags & REQ_F_BUFFER_SELECTED)
4701 kfree((void *)(unsigned long)req->rw.addr);
4702 /* fallthrough */
4569 case IORING_OP_WRITEV:4703 case IORING_OP_WRITEV:
4570 case IORING_OP_WRITE_FIXED:4704 case IORING_OP_WRITE_FIXED:
4571 case IORING_OP_WRITE:4705 case IORING_OP_WRITE:
@@ -4577,6 +4711,10 @@ static void io_cleanup_req(struct io_kiocb *req) · 5 unmodified lines
4577 if (io->msg.iov != io->msg.fast_iov)4711 if (io->msg.iov != io->msg.fast_iov)
4578 kfree(io->msg.iov);4712 kfree(io->msg.iov);
4579 break;4713 break;
4714 case IORING_OP_RECV:
4715 if (req->flags & REQ_F_BUFFER_SELECTED)
4716 kfree(req->sr_msg.kbuf);
4717 break;
4580 case IORING_OP_OPENAT:4718 case IORING_OP_OPENAT:
4581 case IORING_OP_OPENAT2:4719 case IORING_OP_OPENAT2:
4582 case IORING_OP_STATX:4720 case IORING_OP_STATX:
@@ -5154,7 +5292,8 @@ static inline void io_queue_link_head(struct io_kiocb *req) · 571 unmodified lines
5154}5292}
5155 5293
5156#define SQE_VALID_FLAGS (IOSQE_FIXED_FILE|IOSQE_IO_DRAIN|IOSQE_IO_LINK| \5294#define SQE_VALID_FLAGS (IOSQE_FIXED_FILE|IOSQE_IO_DRAIN|IOSQE_IO_LINK| \
5157 IOSQE_IO_HARDLINK | IOSQE_ASYNC)5295 IOSQE_IO_HARDLINK | IOSQE_ASYNC | \
5296 IOSQE_BUFFER_SELECT)
5158 5297
5159static bool io_submit_sqe(struct io_kiocb *req, const struct io_uring_sqe *sqe,5298static bool io_submit_sqe(struct io_kiocb *req, const struct io_uring_sqe *sqe,
5160 struct io_submit_state *state, struct io_kiocb **link)5299 struct io_submit_state *state, struct io_kiocb **link)
@@ -5171,6 +5310,12 @@ static bool io_submit_sqe(struct io_kiocb *req, const struct io_uring_sqe *sqe, · 10 unmodified lines
5171 goto err_req;5310 goto err_req;
5172 }5311 }
5173 5312
5313 if ((sqe_flags & IOSQE_BUFFER_SELECT) &&
5314 !io_op_defs[req->opcode].buffer_select) {
5315 ret = -EOPNOTSUPP;
5316 goto err_req;
5317 }
5318
5174 id = READ_ONCE(sqe->personality);5319 id = READ_ONCE(sqe->personality);
5175 if (id) {5320 if (id) {
5176 req->work.creds = idr_find(&ctx->personality_idr, id);5321 req->work.creds = idr_find(&ctx->personality_idr, id);
@@ -5183,7 +5328,8 @@ static bool io_submit_sqe(struct io_kiocb *req, const struct io_uring_sqe *sqe, · 6 unmodified lines
5183 5328
5184 /* same numerical values with corresponding REQ_F_*, safe to copy */5329 /* same numerical values with corresponding REQ_F_*, safe to copy */
5185 req->flags |= sqe_flags & (IOSQE_IO_DRAIN | IOSQE_IO_HARDLINK |5330 req->flags |= sqe_flags & (IOSQE_IO_DRAIN | IOSQE_IO_HARDLINK |
5186 IOSQE_ASYNC | IOSQE_FIXED_FILE);5331 IOSQE_ASYNC | IOSQE_FIXED_FILE |
5332 IOSQE_BUFFER_SELECT);
5187 5333
5188 ret = io_req_set_file(state, req, sqe);5334 ret = io_req_set_file(state, req, sqe);
5189 if (unlikely(ret)) {5335 if (unlikely(ret)) {
include/uapi/linux/io_uring.h+14−0
@@ -66,6 +66,7 @@ enum { · 65 unmodified lines
66 IOSQE_IO_LINK_BIT,66 IOSQE_IO_LINK_BIT,
67 IOSQE_IO_HARDLINK_BIT,67 IOSQE_IO_HARDLINK_BIT,
68 IOSQE_ASYNC_BIT,68 IOSQE_ASYNC_BIT,
69 IOSQE_BUFFER_SELECT_BIT,
69};70};
70 71
71/*72/*
@@ -81,6 +82,8 @@ enum { · 9 unmodified lines
81#define IOSQE_IO_HARDLINK (1U << IOSQE_IO_HARDLINK_BIT)82#define IOSQE_IO_HARDLINK (1U << IOSQE_IO_HARDLINK_BIT)
82/* always go async */83/* always go async */
83#define IOSQE_ASYNC (1U << IOSQE_ASYNC_BIT)84#define IOSQE_ASYNC (1U << IOSQE_ASYNC_BIT)
85/* select buffer from sqe->buf_group */
86#define IOSQE_BUFFER_SELECT (1U << IOSQE_BUFFER_SELECT_BIT)
84 87
85/*88/*
86 * io_uring_setup() flags89 * io_uring_setup() flags
@@ -155,6 +158,17 @@ struct io_uring_cqe { · 68 unmodified lines
155 __u32 flags;158 __u32 flags;
156};159};
157 160
161/*
162 * cqe->flags
163 *
164 * IORING_CQE_F_BUFFER If set, the upper 16 bits are the buffer ID
165 */
166#define IORING_CQE_F_BUFFER (1U << 0)
167
168enum {
169 IORING_CQE_BUFFER_SHIFT = 16,
170};
171
158/*172/*
159 * Magic offsets for the application to mmap the data it needs173 * Magic offsets for the application to mmap the data it needs
160 */174 */