]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
io_uring/rsrc: pass 'struct io_ring_ctx' reference to rsrc helpers
authorMing Lei <ming.lei@redhat.com>
Thu, 7 Nov 2024 11:01:34 +0000 (19:01 +0800)
committerJens Axboe <axboe@kernel.dk>
Thu, 7 Nov 2024 22:24:33 +0000 (15:24 -0700)
`io_rsrc_node` instance won't be shared among different io_uring ctxs,
and its allocation 'ctx' is always same with the user's 'ctx', so it is
safe to pass user 'ctx' reference to rsrc helpers. Even in io_clone_buffers(),
`io_rsrc_node` instance is allocated actually for destination io_uring_ctx.

Then io_rsrc_node_ctx() can be removed, and the 8 bytes `ctx` pointer will be
removed from `io_rsrc_node` in the following patch.

Signed-off-by: Ming Lei <ming.lei@redhat.com>
Link: https://lore.kernel.org/r/20241107110149.890530-2-ming.lei@redhat.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
io_uring/filetable.c
io_uring/filetable.h
io_uring/rsrc.c
io_uring/rsrc.h
io_uring/splice.c

index 45f005f5db42e07de3f53b6789d8032cfde9016c..a21660e3145abbe1325b769abe6ec3b4eadfb743 100644 (file)
@@ -36,20 +36,21 @@ static int io_file_bitmap_get(struct io_ring_ctx *ctx)
        return -ENFILE;
 }
 
-bool io_alloc_file_tables(struct io_file_table *table, unsigned nr_files)
+bool io_alloc_file_tables(struct io_ring_ctx *ctx, struct io_file_table *table,
+                         unsigned nr_files)
 {
        if (io_rsrc_data_alloc(&table->data, nr_files))
                return false;
        table->bitmap = bitmap_zalloc(nr_files, GFP_KERNEL_ACCOUNT);
        if (table->bitmap)
                return true;
-       io_rsrc_data_free(&table->data);
+       io_rsrc_data_free(ctx, &table->data);
        return false;
 }
 
-void io_free_file_tables(struct io_file_table *table)
+void io_free_file_tables(struct io_ring_ctx *ctx, struct io_file_table *table)
 {
-       io_rsrc_data_free(&table->data);
+       io_rsrc_data_free(ctx, &table->data);
        bitmap_free(table->bitmap);
        table->bitmap = NULL;
 }
@@ -71,7 +72,7 @@ static int io_install_fixed_file(struct io_ring_ctx *ctx, struct file *file,
        if (!node)
                return -ENOMEM;
 
-       if (!io_reset_rsrc_node(&ctx->file_table.data, slot_index))
+       if (!io_reset_rsrc_node(ctx, &ctx->file_table.data, slot_index))
                io_file_bitmap_set(&ctx->file_table, slot_index);
 
        ctx->file_table.data.nodes[slot_index] = node;
@@ -130,7 +131,7 @@ int io_fixed_fd_remove(struct io_ring_ctx *ctx, unsigned int offset)
        node = io_rsrc_node_lookup(&ctx->file_table.data, offset);
        if (!node)
                return -EBADF;
-       io_reset_rsrc_node(&ctx->file_table.data, offset);
+       io_reset_rsrc_node(ctx, &ctx->file_table.data, offset);
        io_file_bitmap_clear(&ctx->file_table, offset);
        return 0;
 }
index bfacadb8d0891a06eaa61e2275eb7b1898917caf..7717ea9efd0e0d4185db5f4884f12080712ce86f 100644 (file)
@@ -6,8 +6,8 @@
 #include <linux/io_uring_types.h>
 #include "rsrc.h"
 
-bool io_alloc_file_tables(struct io_file_table *table, unsigned nr_files);
-void io_free_file_tables(struct io_file_table *table);
+bool io_alloc_file_tables(struct io_ring_ctx *ctx, struct io_file_table *table, unsigned nr_files);
+void io_free_file_tables(struct io_ring_ctx *ctx, struct io_file_table *table);
 
 int io_fixed_fd_install(struct io_kiocb *req, unsigned int issue_flags,
                        struct file *file, unsigned int file_slot);
index 2fb1791d7255b4d337b9e471f8241b1987d5aad4..d7db36a2c66e5c2c8f810edeb94eb940d40dd793 100644 (file)
@@ -130,13 +130,13 @@ struct io_rsrc_node *io_rsrc_node_alloc(struct io_ring_ctx *ctx, int type)
        return node;
 }
 
-__cold void io_rsrc_data_free(struct io_rsrc_data *data)
+__cold void io_rsrc_data_free(struct io_ring_ctx *ctx, struct io_rsrc_data *data)
 {
        if (!data->nr)
                return;
        while (data->nr--) {
                if (data->nodes[data->nr])
-                       io_put_rsrc_node(data->nodes[data->nr]);
+                       io_put_rsrc_node(ctx, data->nodes[data->nr]);
        }
        kvfree(data->nodes);
        data->nodes = NULL;
@@ -184,7 +184,7 @@ static int __io_sqe_files_update(struct io_ring_ctx *ctx,
                        continue;
 
                i = up->offset + done;
-               if (io_reset_rsrc_node(&ctx->file_table.data, i))
+               if (io_reset_rsrc_node(ctx, &ctx->file_table.data, i))
                        io_file_bitmap_clear(&ctx->file_table, i);
 
                if (fd != -1) {
@@ -266,7 +266,7 @@ static int __io_sqe_buffers_update(struct io_ring_ctx *ctx,
                        node->tag = tag;
                }
                i = array_index_nospec(up->offset + done, ctx->buf_table.nr);
-               io_reset_rsrc_node(&ctx->buf_table, i);
+               io_reset_rsrc_node(ctx, &ctx->buf_table, i);
                ctx->buf_table.nodes[i] = node;
                if (ctx->compat)
                        user_data += sizeof(struct compat_iovec);
@@ -442,10 +442,8 @@ int io_files_update(struct io_kiocb *req, unsigned int issue_flags)
        return IOU_OK;
 }
 
-void io_free_rsrc_node(struct io_rsrc_node *node)
+void io_free_rsrc_node(struct io_ring_ctx *ctx, struct io_rsrc_node *node)
 {
-       struct io_ring_ctx *ctx = io_rsrc_node_ctx(node);
-
        lockdep_assert_held(&ctx->uring_lock);
 
        if (node->tag)
@@ -473,7 +471,7 @@ int io_sqe_files_unregister(struct io_ring_ctx *ctx)
        if (!ctx->file_table.data.nr)
                return -ENXIO;
 
-       io_free_file_tables(&ctx->file_table);
+       io_free_file_tables(ctx, &ctx->file_table);
        io_file_table_set_alloc_range(ctx, 0, 0);
        return 0;
 }
@@ -494,7 +492,7 @@ int io_sqe_files_register(struct io_ring_ctx *ctx, void __user *arg,
                return -EMFILE;
        if (nr_args > rlimit(RLIMIT_NOFILE))
                return -EMFILE;
-       if (!io_alloc_file_tables(&ctx->file_table, nr_args))
+       if (!io_alloc_file_tables(ctx, &ctx->file_table, nr_args))
                return -ENOMEM;
 
        for (i = 0; i < nr_args; i++) {
@@ -551,7 +549,7 @@ int io_sqe_buffers_unregister(struct io_ring_ctx *ctx)
 {
        if (!ctx->buf_table.nr)
                return -ENXIO;
-       io_rsrc_data_free(&ctx->buf_table);
+       io_rsrc_data_free(ctx, &ctx->buf_table);
        return 0;
 }
 
@@ -788,7 +786,7 @@ done:
        if (ret) {
                kvfree(imu);
                if (node)
-                       io_put_rsrc_node(node);
+                       io_put_rsrc_node(ctx, node);
                node = ERR_PTR(ret);
        }
        kvfree(pages);
@@ -1018,7 +1016,7 @@ static int io_clone_buffers(struct io_ring_ctx *ctx, struct io_ring_ctx *src_ctx
         * old and new nodes at this point.
         */
        if (arg->flags & IORING_REGISTER_DST_REPLACE)
-               io_rsrc_data_free(&ctx->buf_table);
+               io_rsrc_data_free(ctx, &ctx->buf_table);
 
        /*
         * ctx->buf_table should be empty now - either the contents are being
@@ -1042,7 +1040,7 @@ out_put_free:
                kfree(data.nodes[i]);
        }
 out_unlock:
-       io_rsrc_data_free(&data);
+       io_rsrc_data_free(ctx, &data);
        mutex_unlock(&src_ctx->uring_lock);
        mutex_lock(&ctx->uring_lock);
        return ret;
index bc3a863b14bb97f7d6fdba5ae3b283840765b197..c9057f7a06f503ce09c7c48177f473d43b212e49 100644 (file)
@@ -45,8 +45,8 @@ struct io_imu_folio_data {
 };
 
 struct io_rsrc_node *io_rsrc_node_alloc(struct io_ring_ctx *ctx, int type);
-void io_free_rsrc_node(struct io_rsrc_node *node);
-void io_rsrc_data_free(struct io_rsrc_data *data);
+void io_free_rsrc_node(struct io_ring_ctx *ctx, struct io_rsrc_node *node);
+void io_rsrc_data_free(struct io_ring_ctx *ctx, struct io_rsrc_data *data);
 int io_rsrc_data_alloc(struct io_rsrc_data *data, unsigned nr);
 
 int io_import_fixed(int ddir, struct iov_iter *iter,
@@ -76,19 +76,20 @@ static inline struct io_rsrc_node *io_rsrc_node_lookup(struct io_rsrc_data *data
        return NULL;
 }
 
-static inline void io_put_rsrc_node(struct io_rsrc_node *node)
+static inline void io_put_rsrc_node(struct io_ring_ctx *ctx, struct io_rsrc_node *node)
 {
        if (node && !--node->refs)
-               io_free_rsrc_node(node);
+               io_free_rsrc_node(ctx, node);
 }
 
-static inline bool io_reset_rsrc_node(struct io_rsrc_data *data, int index)
+static inline bool io_reset_rsrc_node(struct io_ring_ctx *ctx,
+                                     struct io_rsrc_data *data, int index)
 {
        struct io_rsrc_node *node = data->nodes[index];
 
        if (!node)
                return false;
-       io_put_rsrc_node(node);
+       io_put_rsrc_node(ctx, node);
        data->nodes[index] = NULL;
        return true;
 }
@@ -96,20 +97,15 @@ static inline bool io_reset_rsrc_node(struct io_rsrc_data *data, int index)
 static inline void io_req_put_rsrc_nodes(struct io_kiocb *req)
 {
        if (req->file_node) {
-               io_put_rsrc_node(req->file_node);
+               io_put_rsrc_node(req->ctx, req->file_node);
                req->file_node = NULL;
        }
        if (req->flags & REQ_F_BUF_NODE) {
-               io_put_rsrc_node(req->buf_node);
+               io_put_rsrc_node(req->ctx, req->buf_node);
                req->buf_node = NULL;
        }
 }
 
-static inline struct io_ring_ctx *io_rsrc_node_ctx(struct io_rsrc_node *node)
-{
-       return (struct io_ring_ctx *) (node->ctx_ptr & ~IORING_RSRC_TYPE_MASK);
-}
-
 static inline int io_rsrc_node_type(struct io_rsrc_node *node)
 {
        return node->ctx_ptr & IORING_RSRC_TYPE_MASK;
index e8ed15f4ea1a548f0287f079193f71718cb54b87..5b84f16306116e4d5cc85de3013a058f0030c623 100644 (file)
@@ -51,7 +51,7 @@ void io_splice_cleanup(struct io_kiocb *req)
 {
        struct io_splice *sp = io_kiocb_to_cmd(req, struct io_splice);
 
-       io_put_rsrc_node(sp->rsrc_node);
+       io_put_rsrc_node(req->ctx, sp->rsrc_node);
 }
 
 static struct file *io_splice_get_file(struct io_kiocb *req,