mirror of
https://github.com/torvalds/linux.git
synced 2024-11-21 19:46:16 +00:00
io_uring/rsrc: pass 'struct io_ring_ctx' reference to rsrc helpers
`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>
This commit is contained in:
parent
af0a2ffef0
commit
0d98c50908
@ -36,20 +36,21 @@ static int io_file_bitmap_get(struct io_ring_ctx *ctx)
|
|||||||
return -ENFILE;
|
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))
|
if (io_rsrc_data_alloc(&table->data, nr_files))
|
||||||
return false;
|
return false;
|
||||||
table->bitmap = bitmap_zalloc(nr_files, GFP_KERNEL_ACCOUNT);
|
table->bitmap = bitmap_zalloc(nr_files, GFP_KERNEL_ACCOUNT);
|
||||||
if (table->bitmap)
|
if (table->bitmap)
|
||||||
return true;
|
return true;
|
||||||
io_rsrc_data_free(&table->data);
|
io_rsrc_data_free(ctx, &table->data);
|
||||||
return false;
|
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);
|
bitmap_free(table->bitmap);
|
||||||
table->bitmap = NULL;
|
table->bitmap = NULL;
|
||||||
}
|
}
|
||||||
@ -71,7 +72,7 @@ static int io_install_fixed_file(struct io_ring_ctx *ctx, struct file *file,
|
|||||||
if (!node)
|
if (!node)
|
||||||
return -ENOMEM;
|
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);
|
io_file_bitmap_set(&ctx->file_table, slot_index);
|
||||||
|
|
||||||
ctx->file_table.data.nodes[slot_index] = node;
|
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);
|
node = io_rsrc_node_lookup(&ctx->file_table.data, offset);
|
||||||
if (!node)
|
if (!node)
|
||||||
return -EBADF;
|
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);
|
io_file_bitmap_clear(&ctx->file_table, offset);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -6,8 +6,8 @@
|
|||||||
#include <linux/io_uring_types.h>
|
#include <linux/io_uring_types.h>
|
||||||
#include "rsrc.h"
|
#include "rsrc.h"
|
||||||
|
|
||||||
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);
|
||||||
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);
|
||||||
|
|
||||||
int io_fixed_fd_install(struct io_kiocb *req, unsigned int issue_flags,
|
int io_fixed_fd_install(struct io_kiocb *req, unsigned int issue_flags,
|
||||||
struct file *file, unsigned int file_slot);
|
struct file *file, unsigned int file_slot);
|
||||||
|
@ -130,13 +130,13 @@ struct io_rsrc_node *io_rsrc_node_alloc(struct io_ring_ctx *ctx, int type)
|
|||||||
return node;
|
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)
|
if (!data->nr)
|
||||||
return;
|
return;
|
||||||
while (data->nr--) {
|
while (data->nr--) {
|
||||||
if (data->nodes[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);
|
kvfree(data->nodes);
|
||||||
data->nodes = NULL;
|
data->nodes = NULL;
|
||||||
@ -184,7 +184,7 @@ static int __io_sqe_files_update(struct io_ring_ctx *ctx,
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
i = up->offset + done;
|
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);
|
io_file_bitmap_clear(&ctx->file_table, i);
|
||||||
|
|
||||||
if (fd != -1) {
|
if (fd != -1) {
|
||||||
@ -266,7 +266,7 @@ static int __io_sqe_buffers_update(struct io_ring_ctx *ctx,
|
|||||||
node->tag = tag;
|
node->tag = tag;
|
||||||
}
|
}
|
||||||
i = array_index_nospec(up->offset + done, ctx->buf_table.nr);
|
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;
|
ctx->buf_table.nodes[i] = node;
|
||||||
if (ctx->compat)
|
if (ctx->compat)
|
||||||
user_data += sizeof(struct compat_iovec);
|
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;
|
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);
|
lockdep_assert_held(&ctx->uring_lock);
|
||||||
|
|
||||||
if (node->tag)
|
if (node->tag)
|
||||||
@ -473,7 +471,7 @@ int io_sqe_files_unregister(struct io_ring_ctx *ctx)
|
|||||||
if (!ctx->file_table.data.nr)
|
if (!ctx->file_table.data.nr)
|
||||||
return -ENXIO;
|
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);
|
io_file_table_set_alloc_range(ctx, 0, 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -494,7 +492,7 @@ int io_sqe_files_register(struct io_ring_ctx *ctx, void __user *arg,
|
|||||||
return -EMFILE;
|
return -EMFILE;
|
||||||
if (nr_args > rlimit(RLIMIT_NOFILE))
|
if (nr_args > rlimit(RLIMIT_NOFILE))
|
||||||
return -EMFILE;
|
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;
|
return -ENOMEM;
|
||||||
|
|
||||||
for (i = 0; i < nr_args; i++) {
|
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)
|
if (!ctx->buf_table.nr)
|
||||||
return -ENXIO;
|
return -ENXIO;
|
||||||
io_rsrc_data_free(&ctx->buf_table);
|
io_rsrc_data_free(ctx, &ctx->buf_table);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -788,7 +786,7 @@ static struct io_rsrc_node *io_sqe_buffer_register(struct io_ring_ctx *ctx,
|
|||||||
if (ret) {
|
if (ret) {
|
||||||
kvfree(imu);
|
kvfree(imu);
|
||||||
if (node)
|
if (node)
|
||||||
io_put_rsrc_node(node);
|
io_put_rsrc_node(ctx, node);
|
||||||
node = ERR_PTR(ret);
|
node = ERR_PTR(ret);
|
||||||
}
|
}
|
||||||
kvfree(pages);
|
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.
|
* old and new nodes at this point.
|
||||||
*/
|
*/
|
||||||
if (arg->flags & IORING_REGISTER_DST_REPLACE)
|
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
|
* ctx->buf_table should be empty now - either the contents are being
|
||||||
@ -1042,7 +1040,7 @@ static int io_clone_buffers(struct io_ring_ctx *ctx, struct io_ring_ctx *src_ctx
|
|||||||
kfree(data.nodes[i]);
|
kfree(data.nodes[i]);
|
||||||
}
|
}
|
||||||
out_unlock:
|
out_unlock:
|
||||||
io_rsrc_data_free(&data);
|
io_rsrc_data_free(ctx, &data);
|
||||||
mutex_unlock(&src_ctx->uring_lock);
|
mutex_unlock(&src_ctx->uring_lock);
|
||||||
mutex_lock(&ctx->uring_lock);
|
mutex_lock(&ctx->uring_lock);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -45,8 +45,8 @@ struct io_imu_folio_data {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct io_rsrc_node *io_rsrc_node_alloc(struct io_ring_ctx *ctx, int type);
|
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_free_rsrc_node(struct io_ring_ctx *ctx, struct io_rsrc_node *node);
|
||||||
void io_rsrc_data_free(struct io_rsrc_data *data);
|
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_rsrc_data_alloc(struct io_rsrc_data *data, unsigned nr);
|
||||||
|
|
||||||
int io_import_fixed(int ddir, struct iov_iter *iter,
|
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;
|
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)
|
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];
|
struct io_rsrc_node *node = data->nodes[index];
|
||||||
|
|
||||||
if (!node)
|
if (!node)
|
||||||
return false;
|
return false;
|
||||||
io_put_rsrc_node(node);
|
io_put_rsrc_node(ctx, node);
|
||||||
data->nodes[index] = NULL;
|
data->nodes[index] = NULL;
|
||||||
return true;
|
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)
|
static inline void io_req_put_rsrc_nodes(struct io_kiocb *req)
|
||||||
{
|
{
|
||||||
if (req->file_node) {
|
if (req->file_node) {
|
||||||
io_put_rsrc_node(req->file_node);
|
io_put_rsrc_node(req->ctx, req->file_node);
|
||||||
req->file_node = NULL;
|
req->file_node = NULL;
|
||||||
}
|
}
|
||||||
if (req->flags & REQ_F_BUF_NODE) {
|
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;
|
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)
|
static inline int io_rsrc_node_type(struct io_rsrc_node *node)
|
||||||
{
|
{
|
||||||
return node->ctx_ptr & IORING_RSRC_TYPE_MASK;
|
return node->ctx_ptr & IORING_RSRC_TYPE_MASK;
|
||||||
|
@ -51,7 +51,7 @@ void io_splice_cleanup(struct io_kiocb *req)
|
|||||||
{
|
{
|
||||||
struct io_splice *sp = io_kiocb_to_cmd(req, struct io_splice);
|
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,
|
static struct file *io_splice_get_file(struct io_kiocb *req,
|
||||||
|
Loading…
Reference in New Issue
Block a user