io_uring: use tw for putting rsrc
authorPavel Begunkov <asml.silence@gmail.com>
Wed, 7 Dec 2022 03:53:32 +0000 (03:53 +0000)
committerJens Axboe <axboe@kernel.dk>
Wed, 7 Dec 2022 13:47:13 +0000 (06:47 -0700)
Use task_work for completing rsrc removals, it'll be needed later for
spinlock optimisations.

Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
Link: https://lore.kernel.org/r/cbba5d53a11ee6fc2194dacea262c1d733c8b529.1670384893.git.asml.silence@gmail.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
include/linux/io_uring_types.h
io_uring/io_uring.c
io_uring/rsrc.c
io_uring/rsrc.h

index 6be1e1359c898576a631defe189becd684fdfdc8..dcd8a563ab522f2593fd71b8e5dc8bf3dcaea0ab 100644 (file)
@@ -328,6 +328,7 @@ struct io_ring_ctx {
        struct io_rsrc_data             *buf_data;
 
        struct delayed_work             rsrc_put_work;
+       struct callback_head            rsrc_put_tw;
        struct llist_head               rsrc_put_llist;
        struct list_head                rsrc_ref_list;
        spinlock_t                      rsrc_ref_lock;
index 13d56472dd49faeefcaf4cb168da9bddc034f1af..a29cbf9732877ceee122085dffc91086bd7d022f 100644 (file)
@@ -326,6 +326,7 @@ static __cold struct io_ring_ctx *io_ring_ctx_alloc(struct io_uring_params *p)
        spin_lock_init(&ctx->rsrc_ref_lock);
        INIT_LIST_HEAD(&ctx->rsrc_ref_list);
        INIT_DELAYED_WORK(&ctx->rsrc_put_work, io_rsrc_put_work);
+       init_task_work(&ctx->rsrc_put_tw, io_rsrc_put_tw);
        init_llist_head(&ctx->rsrc_put_llist);
        init_llist_head(&ctx->work_llist);
        INIT_LIST_HEAD(&ctx->tctx_list);
index d25309400a4591f3f45f9ae54376baa897fd3105..18de10c68a151b3b0ffc36ca956e4d0da7660eb0 100644 (file)
@@ -204,6 +204,14 @@ void io_rsrc_put_work(struct work_struct *work)
        }
 }
 
+void io_rsrc_put_tw(struct callback_head *cb)
+{
+       struct io_ring_ctx *ctx = container_of(cb, struct io_ring_ctx,
+                                              rsrc_put_tw);
+
+       io_rsrc_put_work(&ctx->rsrc_put_work.work);
+}
+
 void io_wait_rsrc_data(struct io_rsrc_data *data)
 {
        if (data && !atomic_dec_and_test(&data->refs))
@@ -242,8 +250,15 @@ static __cold void io_rsrc_node_ref_zero(struct percpu_ref *ref)
        }
        spin_unlock_irqrestore(&ctx->rsrc_ref_lock, flags);
 
-       if (first_add)
-               mod_delayed_work(system_wq, &ctx->rsrc_put_work, delay);
+       if (!first_add)
+               return;
+
+       if (ctx->submitter_task) {
+               if (!task_work_add(ctx->submitter_task, &ctx->rsrc_put_tw,
+                                  ctx->notify_method))
+                       return;
+       }
+       mod_delayed_work(system_wq, &ctx->rsrc_put_work, delay);
 }
 
 static struct io_rsrc_node *io_rsrc_node_alloc(void)
index 81445a477622bcd73286406b31f27b40053981e8..2b8743645efcbd5d29709fbd2ecff2b6d51e86f3 100644 (file)
@@ -53,6 +53,7 @@ struct io_mapped_ubuf {
        struct bio_vec  bvec[];
 };
 
+void io_rsrc_put_tw(struct callback_head *cb);
 void io_rsrc_put_work(struct work_struct *work);
 void io_rsrc_refs_refill(struct io_ring_ctx *ctx);
 void io_wait_rsrc_data(struct io_rsrc_data *data);