]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
io_uring: buffer registration infrastructure
authorJens Axboe <axboe@kernel.dk>
Sun, 23 Feb 2020 23:23:11 +0000 (16:23 -0700)
committerJens Axboe <axboe@kernel.dk>
Wed, 4 Mar 2020 18:49:14 +0000 (11:49 -0700)
This just prepares the ring for having lists of buffers associated with
it, that the application can provide for SQEs to consume instead of
providing their own.

The buffers are organized by group ID.

Signed-off-by: Jens Axboe <axboe@kernel.dk>
fs/io_uring.c

index 0d6f4b3b8f13224c87908bf2aae98b248e81478d..1f3ae208f6a66502d8115868f0624e6a19bfd4f8 100644 (file)
@@ -195,6 +195,13 @@ struct fixed_file_data {
        struct completion               done;
 };
 
+struct io_buffer {
+       struct list_head list;
+       __u64 addr;
+       __s32 len;
+       __u16 bid;
+};
+
 struct io_ring_ctx {
        struct {
                struct percpu_ref       refs;
@@ -272,6 +279,8 @@ struct io_ring_ctx {
        struct socket           *ring_sock;
 #endif
 
+       struct idr              io_buffer_idr;
+
        struct idr              personality_idr;
 
        struct {
@@ -875,6 +884,7 @@ static struct io_ring_ctx *io_ring_ctx_alloc(struct io_uring_params *p)
        INIT_LIST_HEAD(&ctx->cq_overflow_list);
        init_completion(&ctx->completions[0]);
        init_completion(&ctx->completions[1]);
+       idr_init(&ctx->io_buffer_idr);
        idr_init(&ctx->personality_idr);
        mutex_init(&ctx->uring_lock);
        init_waitqueue_head(&ctx->wait);
@@ -6524,6 +6534,30 @@ static int io_eventfd_unregister(struct io_ring_ctx *ctx)
        return -ENXIO;
 }
 
+static int __io_destroy_buffers(int id, void *p, void *data)
+{
+       struct io_ring_ctx *ctx = data;
+       struct io_buffer *buf = p;
+
+       /* the head kbuf is the list itself */
+       while (!list_empty(&buf->list)) {
+               struct io_buffer *nxt;
+
+               nxt = list_first_entry(&buf->list, struct io_buffer, list);
+               list_del(&nxt->list);
+               kfree(nxt);
+       }
+       kfree(buf);
+       idr_remove(&ctx->io_buffer_idr, id);
+       return 0;
+}
+
+static void io_destroy_buffers(struct io_ring_ctx *ctx)
+{
+       idr_for_each(&ctx->io_buffer_idr, __io_destroy_buffers, ctx);
+       idr_destroy(&ctx->io_buffer_idr);
+}
+
 static void io_ring_ctx_free(struct io_ring_ctx *ctx)
 {
        io_finish_async(ctx);
@@ -6534,6 +6568,7 @@ static void io_ring_ctx_free(struct io_ring_ctx *ctx)
        io_sqe_buffer_unregister(ctx);
        io_sqe_files_unregister(ctx);
        io_eventfd_unregister(ctx);
+       io_destroy_buffers(ctx);
        idr_destroy(&ctx->personality_idr);
 
 #if defined(CONFIG_UNIX)