History

io_uring: pass in io_kiocb to fill/add CQ handlers

This is in preparation for handling CQ ring overflow a bit smarter. We should not have any functional changes in this patch. Most of the changes are fairly straight forward, the only ones that stick out a bit are the ones that change __io_free_req() to take the reference count into account. If the request hasn't been submitted yet, we know it's safe to simply ignore references and free it. But let's clean these up too, as later patches will depend on the caller doing the right thing if the completion logging grabs a reference to the request.

Jens Axboe committed 7 years ago

Commit 78e19bb1 parent 84f97dc1 file · +50 −46Browse files

Unified · Split

fs/io_uring.c+50−46
@@ -369,10 +369,10 @@ struct io_submit_state { · 368 unmodified lines
369};369};
370 370
371static void io_wq_submit_work(struct io_wq_work **workptr);371static void io_wq_submit_work(struct io_wq_work **workptr);
372static void io_cqring_fill_event(struct io_ring_ctx *ctx, u64 ki_user_data,372static void io_cqring_fill_event(struct io_kiocb *req, long res);
373 long res);
374static void __io_free_req(struct io_kiocb *req);373static void __io_free_req(struct io_kiocb *req);
375static void io_put_req(struct io_kiocb *req, struct io_kiocb **nxtptr);374static void io_put_req(struct io_kiocb *req, struct io_kiocb **nxtptr);
375static void io_double_put_req(struct io_kiocb *req);
376 376
377static struct kmem_cache *req_cachep;377static struct kmem_cache *req_cachep;
378 378
@@ -535,8 +535,8 @@ static void io_kill_timeout(struct io_kiocb *req) · 156 unmodified lines
535 if (ret != -1) {535 if (ret != -1) {
536 atomic_inc(&req->ctx->cq_timeouts);536 atomic_inc(&req->ctx->cq_timeouts);
537 list_del_init(&req->list);537 list_del_init(&req->list);
538 io_cqring_fill_event(req->ctx, req->user_data, 0);538 io_cqring_fill_event(req, 0);
539 __io_free_req(req);539 io_put_req(req, NULL);
540 }540 }
541}541}
542 542
@@ -588,12 +588,12 @@ static struct io_uring_cqe *io_get_cqring(struct io_ring_ctx *ctx) · 45 unmodified lines
588 return &rings->cqes[tail & ctx->cq_mask];588 return &rings->cqes[tail & ctx->cq_mask];
589}589}
590 590
591static void io_cqring_fill_event(struct io_ring_ctx *ctx, u64 ki_user_data,591static void io_cqring_fill_event(struct io_kiocb *req, long res)
592 long res)
593{592{
593 struct io_ring_ctx *ctx = req->ctx;
594 struct io_uring_cqe *cqe;594 struct io_uring_cqe *cqe;
595 595
596 trace_io_uring_complete(ctx, ki_user_data, res);596 trace_io_uring_complete(ctx, req->user_data, res);
597 597
598 /*598 /*
599 * If we can't get a cq entry, userspace overflowed the599 * If we can't get a cq entry, userspace overflowed the
@@ -602,7 +602,7 @@ static void io_cqring_fill_event(struct io_ring_ctx *ctx, u64 ki_user_data, · 2 unmodified lines
602 */602 */
603 cqe = io_get_cqring(ctx);603 cqe = io_get_cqring(ctx);
604 if (cqe) {604 if (cqe) {
605 WRITE_ONCE(cqe->user_data, ki_user_data);605 WRITE_ONCE(cqe->user_data, req->user_data);
606 WRITE_ONCE(cqe->res, res);606 WRITE_ONCE(cqe->res, res);
607 WRITE_ONCE(cqe->flags, 0);607 WRITE_ONCE(cqe->flags, 0);
608 } else {608 } else {
@@ -621,13 +621,13 @@ static void io_cqring_ev_posted(struct io_ring_ctx *ctx) · 12 unmodified lines
621 eventfd_signal(ctx->cq_ev_fd, 1);621 eventfd_signal(ctx->cq_ev_fd, 1);
622}622}
623 623
624static void io_cqring_add_event(struct io_ring_ctx *ctx, u64 user_data,624static void io_cqring_add_event(struct io_kiocb *req, long res)
625 long res)
626{625{
626 struct io_ring_ctx *ctx = req->ctx;
627 unsigned long flags;627 unsigned long flags;
628 628
629 spin_lock_irqsave(&ctx->completion_lock, flags);629 spin_lock_irqsave(&ctx->completion_lock, flags);
630 io_cqring_fill_event(ctx, user_data, res);630 io_cqring_fill_event(req, res);
631 io_commit_cqring(ctx);631 io_commit_cqring(ctx);
632 spin_unlock_irqrestore(&ctx->completion_lock, flags);632 spin_unlock_irqrestore(&ctx->completion_lock, flags);
633 633
@@ -721,10 +721,10 @@ static bool io_link_cancel_timeout(struct io_ring_ctx *ctx, · 87 unmodified lines
721 721
722 ret = hrtimer_try_to_cancel(&req->timeout.timer);722 ret = hrtimer_try_to_cancel(&req->timeout.timer);
723 if (ret != -1) {723 if (ret != -1) {
724 io_cqring_fill_event(ctx, req->user_data, -ECANCELED);724 io_cqring_fill_event(req, -ECANCELED);
725 io_commit_cqring(ctx);725 io_commit_cqring(ctx);
726 req->flags &= ~REQ_F_LINK;726 req->flags &= ~REQ_F_LINK;
727 __io_free_req(req);727 io_put_req(req, NULL);
728 return true;728 return true;
729 }729 }
730 730
@@ -795,8 +795,8 @@ static void io_fail_links(struct io_kiocb *req) · 64 unmodified lines
795 link->submit.sqe->opcode == IORING_OP_LINK_TIMEOUT) {795 link->submit.sqe->opcode == IORING_OP_LINK_TIMEOUT) {
796 io_link_cancel_timeout(ctx, link);796 io_link_cancel_timeout(ctx, link);
797 } else {797 } else {
798 io_cqring_fill_event(ctx, link->user_data, -ECANCELED);798 io_cqring_fill_event(link, -ECANCELED);
799 __io_free_req(link);799 io_double_put_req(link);
800 }800 }
801 }801 }
802 802
@@ -866,6 +866,13 @@ static void io_put_req(struct io_kiocb *req, struct io_kiocb **nxtptr) · 63 unmodified lines
866 }866 }
867}867}
868 868
869static void io_double_put_req(struct io_kiocb *req)
870{
871 /* drop both submit and complete references */
872 if (refcount_sub_and_test(2, &req->refs))
873 __io_free_req(req);
874}
875
869static unsigned io_cqring_events(struct io_ring_ctx *ctx)876static unsigned io_cqring_events(struct io_ring_ctx *ctx)
870{877{
871 struct io_rings *rings = ctx->rings;878 struct io_rings *rings = ctx->rings;
@@ -898,7 +905,7 @@ static void io_iopoll_complete(struct io_ring_ctx *ctx, unsigned int *nr_events, · 26 unmodified lines
898 req = list_first_entry(done, struct io_kiocb, list);905 req = list_first_entry(done, struct io_kiocb, list);
899 list_del(&req->list);906 list_del(&req->list);
900 907
901 io_cqring_fill_event(ctx, req->user_data, req->result);908 io_cqring_fill_event(req, req->result);
902 (*nr_events)++;909 (*nr_events)++;
903 910
904 if (refcount_dec_and_test(&req->refs)) {911 if (refcount_dec_and_test(&req->refs)) {
@@ -1094,7 +1101,7 @@ static void io_complete_rw_common(struct kiocb *kiocb, long res) · 189 unmodified lines
1094 1101
1095 if ((req->flags & REQ_F_LINK) && res != req->result)1102 if ((req->flags & REQ_F_LINK) && res != req->result)
1096 req->flags |= REQ_F_FAIL_LINK;1103 req->flags |= REQ_F_FAIL_LINK;
1097 io_cqring_add_event(req->ctx, req->user_data, res);1104 io_cqring_add_event(req, res);
1098}1105}
1099 1106
1100static void io_complete_rw(struct kiocb *kiocb, long res, long res2)1107static void io_complete_rw(struct kiocb *kiocb, long res, long res2)
@@ -1595,15 +1602,14 @@ out_free: · 494 unmodified lines
1595/*1602/*
1596 * IORING_OP_NOP just posts a completion event, nothing else.1603 * IORING_OP_NOP just posts a completion event, nothing else.
1597 */1604 */
1598static int io_nop(struct io_kiocb *req, u64 user_data)1605static int io_nop(struct io_kiocb *req)
1599{1606{
1600 struct io_ring_ctx *ctx = req->ctx;1607 struct io_ring_ctx *ctx = req->ctx;
1601 long err = 0;
1602 1608
1603 if (unlikely(ctx->flags & IORING_SETUP_IOPOLL))1609 if (unlikely(ctx->flags & IORING_SETUP_IOPOLL))
1604 return -EINVAL;1610 return -EINVAL;
1605 1611
1606 io_cqring_add_event(ctx, user_data, err);1612 io_cqring_add_event(req, 0);
1607 io_put_req(req, NULL);1613 io_put_req(req, NULL);
1608 return 0;1614 return 0;
1609}1615}
@@ -1650,7 +1656,7 @@ static int io_fsync(struct io_kiocb *req, const struct io_uring_sqe *sqe, · 40 unmodified lines
1650 1656
1651 if (ret < 0 && (req->flags & REQ_F_LINK))1657 if (ret < 0 && (req->flags & REQ_F_LINK))
1652 req->flags |= REQ_F_FAIL_LINK;1658 req->flags |= REQ_F_FAIL_LINK;
1653 io_cqring_add_event(req->ctx, sqe->user_data, ret);1659 io_cqring_add_event(req, ret);
1654 io_put_req(req, nxt);1660 io_put_req(req, nxt);
1655 return 0;1661 return 0;
1656}1662}
@@ -1697,7 +1703,7 @@ static int io_sync_file_range(struct io_kiocb *req, · 40 unmodified lines
1697 1703
1698 if (ret < 0 && (req->flags & REQ_F_LINK))1704 if (ret < 0 && (req->flags & REQ_F_LINK))
1699 req->flags |= REQ_F_FAIL_LINK;1705 req->flags |= REQ_F_FAIL_LINK;
1700 io_cqring_add_event(req->ctx, sqe->user_data, ret);1706 io_cqring_add_event(req, ret);
1701 io_put_req(req, nxt);1707 io_put_req(req, nxt);
1702 return 0;1708 return 0;
1703}1709}
@@ -1733,7 +1739,7 @@ static int io_send_recvmsg(struct io_kiocb *req, const struct io_uring_sqe *sqe, · 29 unmodified lines
1733 return ret;1739 return ret;
1734 }1740 }
1735 1741
1736 io_cqring_add_event(req->ctx, sqe->user_data, ret);1742 io_cqring_add_event(req, ret);
1737 if (ret < 0 && (req->flags & REQ_F_LINK))1743 if (ret < 0 && (req->flags & REQ_F_LINK))
1738 req->flags |= REQ_F_FAIL_LINK;1744 req->flags |= REQ_F_FAIL_LINK;
1739 io_put_req(req, nxt);1745 io_put_req(req, nxt);
@@ -1789,7 +1795,7 @@ static int io_accept(struct io_kiocb *req, const struct io_uring_sqe *sqe, · 49 unmodified lines
1789 }1795 }
1790 if (ret < 0 && (req->flags & REQ_F_LINK))1796 if (ret < 0 && (req->flags & REQ_F_LINK))
1791 req->flags |= REQ_F_FAIL_LINK;1797 req->flags |= REQ_F_FAIL_LINK;
1792 io_cqring_add_event(req->ctx, sqe->user_data, ret);1798 io_cqring_add_event(req, ret);
1793 io_put_req(req, nxt);1799 io_put_req(req, nxt);
1794 return 0;1800 return 0;
1795#else1801#else
@@ -1850,7 +1856,7 @@ static int io_poll_remove(struct io_kiocb *req, const struct io_uring_sqe *sqe) · 54 unmodified lines
1850 }1856 }
1851 spin_unlock_irq(&ctx->completion_lock);1857 spin_unlock_irq(&ctx->completion_lock);
1852 1858
1853 io_cqring_add_event(req->ctx, sqe->user_data, ret);1859 io_cqring_add_event(req, ret);
1854 if (ret < 0 && (req->flags & REQ_F_LINK))1860 if (ret < 0 && (req->flags & REQ_F_LINK))
1855 req->flags |= REQ_F_FAIL_LINK;1861 req->flags |= REQ_F_FAIL_LINK;
1856 io_put_req(req, NULL);1862 io_put_req(req, NULL);
@@ -1861,7 +1867,7 @@ static void io_poll_complete(struct io_ring_ctx *ctx, struct io_kiocb *req, · 4 unmodified lines
1861 __poll_t mask)1867 __poll_t mask)
1862{1868{
1863 req->poll.done = true;1869 req->poll.done = true;
1864 io_cqring_fill_event(ctx, req->user_data, mangle_poll(mask));1870 io_cqring_fill_event(req, mangle_poll(mask));
1865 io_commit_cqring(ctx);1871 io_commit_cqring(ctx);
1866}1872}
1867 1873
@@ -2055,7 +2061,7 @@ static enum hrtimer_restart io_timeout_fn(struct hrtimer *timer) · 187 unmodified lines
2055 list_del_init(&req->list);2061 list_del_init(&req->list);
2056 }2062 }
2057 2063
2058 io_cqring_fill_event(ctx, req->user_data, -ETIME);2064 io_cqring_fill_event(req, -ETIME);
2059 io_commit_cqring(ctx);2065 io_commit_cqring(ctx);
2060 spin_unlock_irqrestore(&ctx->completion_lock, flags);2066 spin_unlock_irqrestore(&ctx->completion_lock, flags);
2061 2067
@@ -2099,7 +2105,7 @@ static int io_timeout_remove(struct io_kiocb *req, · 37 unmodified lines
2099 /* didn't find timeout */2105 /* didn't find timeout */
2100 if (ret) {2106 if (ret) {
2101fill_ev:2107fill_ev:
2102 io_cqring_fill_event(ctx, req->user_data, ret);2108 io_cqring_fill_event(req, ret);
2103 io_commit_cqring(ctx);2109 io_commit_cqring(ctx);
2104 spin_unlock_irq(&ctx->completion_lock);2110 spin_unlock_irq(&ctx->completion_lock);
2105 io_cqring_ev_posted(ctx);2111 io_cqring_ev_posted(ctx);
@@ -2115,8 +2121,8 @@ fill_ev: · 9 unmodified lines
2115 goto fill_ev;2121 goto fill_ev;
2116 }2122 }
2117 2123
2118 io_cqring_fill_event(ctx, req->user_data, 0);2124 io_cqring_fill_event(req, 0);
2119 io_cqring_fill_event(ctx, treq->user_data, -ECANCELED);2125 io_cqring_fill_event(treq, -ECANCELED);
2120 io_commit_cqring(ctx);2126 io_commit_cqring(ctx);
2121 spin_unlock_irq(&ctx->completion_lock);2127 spin_unlock_irq(&ctx->completion_lock);
2122 io_cqring_ev_posted(ctx);2128 io_cqring_ev_posted(ctx);
@@ -2256,7 +2262,7 @@ static int io_async_cancel(struct io_kiocb *req, const struct io_uring_sqe *sqe, · 133 unmodified lines
2256 2262
2257 if (ret < 0 && (req->flags & REQ_F_LINK))2263 if (ret < 0 && (req->flags & REQ_F_LINK))
2258 req->flags |= REQ_F_FAIL_LINK;2264 req->flags |= REQ_F_FAIL_LINK;
2259 io_cqring_add_event(req->ctx, sqe->user_data, ret);2265 io_cqring_add_event(req, ret);
2260 io_put_req(req, nxt);2266 io_put_req(req, nxt);
2261 return 0;2267 return 0;
2262}2268}
@@ -2295,12 +2301,10 @@ static int __io_submit_sqe(struct io_ring_ctx *ctx, struct io_kiocb *req, · 32 unmodified lines
2295 int ret, opcode;2301 int ret, opcode;
2296 struct sqe_submit *s = &req->submit;2302 struct sqe_submit *s = &req->submit;
2297 2303
2298 req->user_data = READ_ONCE(s->sqe->user_data);
2299
2300 opcode = READ_ONCE(s->sqe->opcode);2304 opcode = READ_ONCE(s->sqe->opcode);
2301 switch (opcode) {2305 switch (opcode) {
2302 case IORING_OP_NOP:2306 case IORING_OP_NOP:
2303 ret = io_nop(req, req->user_data);2307 ret = io_nop(req);
2304 break;2308 break;
2305 case IORING_OP_READV:2309 case IORING_OP_READV:
2306 if (unlikely(s->sqe->buf_index))2310 if (unlikely(s->sqe->buf_index))
@@ -2409,7 +2413,7 @@ static void io_wq_submit_work(struct io_wq_work **workptr) · 102 unmodified lines
2409 if (ret) {2413 if (ret) {
2410 if (req->flags & REQ_F_LINK)2414 if (req->flags & REQ_F_LINK)
2411 req->flags |= REQ_F_FAIL_LINK;2415 req->flags |= REQ_F_FAIL_LINK;
2412 io_cqring_add_event(ctx, sqe->user_data, ret);2416 io_cqring_add_event(req, ret);
2413 io_put_req(req, NULL);2417 io_put_req(req, NULL);
2414 }2418 }
2415 2419
@@ -2539,7 +2543,7 @@ static enum hrtimer_restart io_link_timeout_fn(struct hrtimer *timer) · 123 unmodified lines
2539 ret = io_async_cancel_one(ctx, user_data);2543 ret = io_async_cancel_one(ctx, user_data);
2540 }2544 }
2541 2545
2542 io_cqring_add_event(ctx, req->user_data, ret);2546 io_cqring_add_event(req, ret);
2543 io_put_req(req, NULL);2547 io_put_req(req, NULL);
2544 return HRTIMER_NORESTART;2548 return HRTIMER_NORESTART;
2545}2549}
@@ -2582,7 +2586,7 @@ err: · 36 unmodified lines
2582 * failed by the regular submission path.2586 * failed by the regular submission path.
2583 */2587 */
2584 list_del(&nxt->list);2588 list_del(&nxt->list);
2585 io_cqring_fill_event(ctx, nxt->user_data, ret);2589 io_cqring_fill_event(nxt, ret);
2586 trace_io_uring_fail_link(req, nxt);2590 trace_io_uring_fail_link(req, nxt);
2587 io_commit_cqring(ctx);2591 io_commit_cqring(ctx);
2588 io_put_req(nxt, NULL);2592 io_put_req(nxt, NULL);
@@ -2655,7 +2659,7 @@ err: · 66 unmodified lines
2655 2659
2656 /* and drop final reference, if we failed */2660 /* and drop final reference, if we failed */
2657 if (ret) {2661 if (ret) {
2658 io_cqring_add_event(ctx, req->user_data, ret);2662 io_cqring_add_event(req, ret);
2659 if (req->flags & REQ_F_LINK)2663 if (req->flags & REQ_F_LINK)
2660 req->flags |= REQ_F_FAIL_LINK;2664 req->flags |= REQ_F_FAIL_LINK;
2661 io_put_req(req, NULL);2665 io_put_req(req, NULL);
@@ -2671,8 +2675,8 @@ static int io_queue_sqe(struct io_ring_ctx *ctx, struct io_kiocb *req) · 9 unmodified lines
2671 ret = io_req_defer(ctx, req);2675 ret = io_req_defer(ctx, req);
2672 if (ret) {2676 if (ret) {
2673 if (ret != -EIOCBQUEUED) {2677 if (ret != -EIOCBQUEUED) {
2674 io_cqring_add_event(ctx, req->submit.sqe->user_data, ret);2678 io_cqring_add_event(req, ret);
2675 io_free_req(req, NULL);2679 io_double_put_req(req);
2676 }2680 }
2677 return 0;2681 return 0;
2678 }2682 }
@@ -2698,8 +2702,8 @@ static int io_queue_link_head(struct io_ring_ctx *ctx, struct io_kiocb *req, · 19 unmodified lines
2698 ret = io_req_defer(ctx, req);2702 ret = io_req_defer(ctx, req);
2699 if (ret) {2703 if (ret) {
2700 if (ret != -EIOCBQUEUED) {2704 if (ret != -EIOCBQUEUED) {
2701 io_cqring_add_event(ctx, req->submit.sqe->user_data, ret);2705 io_cqring_add_event(req, ret);
2702 io_free_req(req, NULL);2706 io_double_put_req(req);
2703 __io_free_req(shadow);2707 __io_free_req(shadow);
2704 return 0;2708 return 0;
2705 }2709 }
@@ -2732,6 +2736,8 @@ static void io_submit_sqe(struct io_ring_ctx *ctx, struct io_kiocb *req, · 26 unmodified lines
2732 struct sqe_submit *s = &req->submit;2736 struct sqe_submit *s = &req->submit;
2733 int ret;2737 int ret;
2734 2738
2739 req->user_data = s->sqe->user_data;
2740
2735 /* enforce forwards compatibility on users */2741 /* enforce forwards compatibility on users */
2736 if (unlikely(s->sqe->flags & ~SQE_VALID_FLAGS)) {2742 if (unlikely(s->sqe->flags & ~SQE_VALID_FLAGS)) {
2737 ret = -EINVAL;2743 ret = -EINVAL;
@@ -2741,13 +2747,11 @@ static void io_submit_sqe(struct io_ring_ctx *ctx, struct io_kiocb *req, · 3 unmodified lines
2741 ret = io_req_set_file(ctx, state, req);2747 ret = io_req_set_file(ctx, state, req);
2742 if (unlikely(ret)) {2748 if (unlikely(ret)) {
2743err_req:2749err_req:
2744 io_cqring_add_event(ctx, s->sqe->user_data, ret);2750 io_cqring_add_event(req, ret);
2745 io_free_req(req, NULL);2751 io_double_put_req(req);
2746 return;2752 return;
2747 }2753 }
2748 2754
2749 req->user_data = s->sqe->user_data;
2750
2751 /*2755 /*
2752 * If we already have a head request, queue this one for async2756 * If we already have a head request, queue this one for async
2753 * submittal once the head completes. If we don't have a head but2757 * submittal once the head completes. If we don't have a head but