summaryrefslogtreecommitdiff
path: root/fs/io_uring.c
diff options
context:
space:
mode:
authorJens Axboe <axboe@kernel.dk>2020-09-02 23:50:27 +0300
committerJens Axboe <axboe@kernel.dk>2020-10-01 05:32:33 +0300
commitaa06165de863a09bceebef65ecaf19294b26fd2e (patch)
tree58e146c6b9d8d47a4ec8dfe35f007c41f5fa1b1b /fs/io_uring.c
parent69fb21310fd36aad96370e05953f2c2366f492e4 (diff)
downloadlinux-aa06165de863a09bceebef65ecaf19294b26fd2e.tar.xz
io_uring: enable IORING_SETUP_ATTACH_WQ to attach to SQPOLL thread too
We support using IORING_SETUP_ATTACH_WQ to share async backends between rings created by the same process, this now also allows the same to happen with SQPOLL. The setup procedure remains the same, the caller sets io_uring_params->wq_fd to the 'parent' context, and then the newly created ring will attach to that async backend. This means that multiple rings can share the same SQPOLL thread, saving resources. Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'fs/io_uring.c')
-rw-r--r--fs/io_uring.c33
1 files changed, 33 insertions, 0 deletions
diff --git a/fs/io_uring.c b/fs/io_uring.c
index 0a9eced754cb..546bc1fbf482 100644
--- a/fs/io_uring.c
+++ b/fs/io_uring.c
@@ -6996,10 +6996,39 @@ static void io_put_sq_data(struct io_sq_data *sqd)
}
}
+static struct io_sq_data *io_attach_sq_data(struct io_uring_params *p)
+{
+ struct io_ring_ctx *ctx_attach;
+ struct io_sq_data *sqd;
+ struct fd f;
+
+ f = fdget(p->wq_fd);
+ if (!f.file)
+ return ERR_PTR(-ENXIO);
+ if (f.file->f_op != &io_uring_fops) {
+ fdput(f);
+ return ERR_PTR(-EINVAL);
+ }
+
+ ctx_attach = f.file->private_data;
+ sqd = ctx_attach->sq_data;
+ if (!sqd) {
+ fdput(f);
+ return ERR_PTR(-EINVAL);
+ }
+
+ refcount_inc(&sqd->refs);
+ fdput(f);
+ return sqd;
+}
+
static struct io_sq_data *io_get_sq_data(struct io_uring_params *p)
{
struct io_sq_data *sqd;
+ if (p->flags & IORING_SETUP_ATTACH_WQ)
+ return io_attach_sq_data(p);
+
sqd = kzalloc(sizeof(*sqd), GFP_KERNEL);
if (!sqd)
return ERR_PTR(-ENOMEM);
@@ -7751,6 +7780,9 @@ static int io_sq_offload_create(struct io_ring_ctx *ctx,
if (!ctx->sq_thread_idle)
ctx->sq_thread_idle = HZ;
+ if (sqd->thread)
+ goto done;
+
if (p->flags & IORING_SETUP_SQ_AFF) {
int cpu = p->sq_thread_cpu;
@@ -7780,6 +7812,7 @@ static int io_sq_offload_create(struct io_ring_ctx *ctx,
goto err;
}
+done:
ret = io_init_wq_offload(ctx, p);
if (ret)
goto err;