diff options
author | Jens Axboe <axboe@kernel.dk> | 2020-01-23 15:59:43 -0700 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2020-01-24 10:06:59 -0700 |
commit | 2d8aed73db9b966ada7202adc2d12e85e932b041 (patch) | |
tree | 21974e38cc823ca20d635945c7712e2eeaf66ded | |
parent | dfdb613443df1f9e5d592ce339efdade31322975 (diff) |
io_uring: add support for sharing kernel io-wq workqueuefor-5.6/io_uring-vfs-shared-wq
An id field is added to io_uring_params, which always returns the ID of
the io-wq backend that is associated with an io_uring context. If an 'id'
is provided and IORING_SETUP_SHARED is set in the creation flags, then
we attempt to attach to an existing io-wq instead of setting up a new one.
This allows creation of "sibling" io_urings, where we prefer to keep the
SQ/CQ private, but want to share the async backend to minimize the amount
of overhead associated with having multiple rings that belong to the same
backend.
Signed-off-by: Jens Axboe <axboe@kernel.dk>
-rw-r--r-- | fs/io_uring.c | 20 | ||||
-rw-r--r-- | include/uapi/linux/io_uring.h | 4 |
2 files changed, 20 insertions, 4 deletions
diff --git a/fs/io_uring.c b/fs/io_uring.c index 9f73586dcfb8..3dad12906db3 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -5673,7 +5673,7 @@ static int io_sq_offload_start(struct io_ring_ctx *ctx, { struct io_wq_data data; unsigned concurrency; - int ret; + int ret, id; init_waitqueue_head(&ctx->sqo_wait); mmgrab(current->mm); @@ -5724,13 +5724,23 @@ static int io_sq_offload_start(struct io_ring_ctx *ctx, /* Do QD, or 4 * CPUS, whatever is smallest */ concurrency = min(ctx->sq_entries, 4 * num_online_cpus()); - ctx->io_wq = io_wq_create(concurrency, &data); + + id = 0; + if (ctx->flags & IORING_SETUP_ATTACH_WQ) { + id = p->id; + if (!id) { + ret = -EINVAL; + goto err; + } + } + ctx->io_wq = io_wq_create_id(concurrency, &data, id); if (IS_ERR(ctx->io_wq)) { ret = PTR_ERR(ctx->io_wq); ctx->io_wq = NULL; goto err; } + p->id = io_wq_id(ctx->io_wq); return 0; err: io_finish_async(ctx); @@ -6554,7 +6564,11 @@ static long io_uring_setup(u32 entries, struct io_uring_params __user *params) if (p.flags & ~(IORING_SETUP_IOPOLL | IORING_SETUP_SQPOLL | IORING_SETUP_SQ_AFF | IORING_SETUP_CQSIZE | - IORING_SETUP_CLAMP)) + IORING_SETUP_CLAMP | IORING_SETUP_ATTACH_WQ)) + return -EINVAL; + + /* id isn't valid without ATTACH_WQ being set */ + if (!(p.flags & IORING_SETUP_ATTACH_WQ) && p.id) return -EINVAL; ret = io_uring_create(entries, &p); diff --git a/include/uapi/linux/io_uring.h b/include/uapi/linux/io_uring.h index 57d05cc5e271..f66e53c74a3d 100644 --- a/include/uapi/linux/io_uring.h +++ b/include/uapi/linux/io_uring.h @@ -75,6 +75,7 @@ enum { #define IORING_SETUP_SQ_AFF (1U << 2) /* sq_thread_cpu is valid */ #define IORING_SETUP_CQSIZE (1U << 3) /* app defines CQ size */ #define IORING_SETUP_CLAMP (1U << 4) /* clamp SQ/CQ ring sizes */ +#define IORING_SETUP_ATTACH_WQ (1U << 5) /* attach to existing wq */ enum { IORING_OP_NOP, @@ -183,7 +184,8 @@ struct io_uring_params { __u32 sq_thread_cpu; __u32 sq_thread_idle; __u32 features; - __u32 resv[4]; + __u32 id; + __u32 resv[3]; struct io_sqring_offsets sq_off; struct io_cqring_offsets cq_off; }; |