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>
This commit is contained in:
Jens Axboe 2020-09-02 14:50:27 -06:00
parent 69fb21310f
commit aa06165de8
1 changed files with 33 additions and 0 deletions

View File

@ -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;