io_uring/net: fix zc fixed buf lifetime
authorPavel Begunkov <asml.silence@gmail.com>
Fri, 16 Sep 2022 22:22:57 +0000 (23:22 +0100)
committerJens Axboe <axboe@kernel.dk>
Sun, 18 Sep 2022 11:07:51 +0000 (05:07 -0600)
Notifications usually outlive requests, so we need to pin buffers with
it by assigning a rsrc to it instead of the request.

Fixed: b48c312be05e8 ("io_uring/net: simplify zerocopy send user API")
Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
Link: https://lore.kernel.org/r/dd6406ff8a90887f2b36ed6205dac9fda17c1f35.1663366886.git.asml.silence@gmail.com
Reviewed-by: Stefan Metzmacher <metze@samba.org>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
io_uring/net.c

index e9efed4..60e392f 100644 (file)
@@ -905,6 +905,13 @@ int io_sendzc_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
        if (zc->flags & ~(IORING_RECVSEND_POLL_FIRST |
                          IORING_RECVSEND_FIXED_BUF))
                return -EINVAL;
+       notif = zc->notif = io_alloc_notif(ctx);
+       if (!notif)
+               return -ENOMEM;
+       notif->cqe.user_data = req->cqe.user_data;
+       notif->cqe.res = 0;
+       notif->cqe.flags = IORING_CQE_F_NOTIF;
+       req->flags |= REQ_F_NEED_CLEANUP;
        if (zc->flags & IORING_RECVSEND_FIXED_BUF) {
                unsigned idx = READ_ONCE(sqe->buf_index);
 
@@ -912,15 +919,8 @@ int io_sendzc_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
                        return -EFAULT;
                idx = array_index_nospec(idx, ctx->nr_user_bufs);
                req->imu = READ_ONCE(ctx->user_bufs[idx]);
-               io_req_set_rsrc_node(req, ctx, 0);
+               io_req_set_rsrc_node(notif, ctx, 0);
        }
-       notif = zc->notif = io_alloc_notif(ctx);
-       if (!notif)
-               return -ENOMEM;
-       notif->cqe.user_data = req->cqe.user_data;
-       notif->cqe.res = 0;
-       notif->cqe.flags = IORING_CQE_F_NOTIF;
-       req->flags |= REQ_F_NEED_CLEANUP;
 
        zc->buf = u64_to_user_ptr(READ_ONCE(sqe->addr));
        zc->len = READ_ONCE(sqe->len);