Add support for shared io-wq backends
Jens Axboe
maintainercover Add support for shared io-wq backends
Sometimes an applications wants to use multiple smaller rings, because it's more efficient than sharing a ring. The downside of that is that we'll create the io-wq backend separately for all of them, while they would be perfectly happy just sharing that.
This patchset adds support for that. io_uring_params grows an 'id' field, which denotes an identifier for the async backend. If an application wants to utilize sharing, it'll simply grab the id from the first ring created, and pass it in to the next one and set IORING_SETUP_SHARED. This allows efficient sharing of backend resources, while allowing multiple rings in the application or library.
Not a huge fan of the IORING_SETUP_SHARED name, we should probably make that better (I'm taking suggestions).
Signature · 1 line
Jens Axboe
Jens Axboe
maintainerPATCH 1/4 io-wq: make the io_wq ref counted
In preparation for sharing an io-wq across different users, add a reference count that manages destruction of it.
--- fs/io-wq.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-)
fs/io-wq.c +10 -1
@@ -113,6 +113,8 @@ struct io_wq {struct mm_struct *mm;refcount_t refs;struct completion done; + +refcount_t use_refs; };static bool io_worker_get (struct io_worker *worker)
@@ -1073,6 +1075,7 @@ struct io_wq *io_wq_create(unsigned bounded, struct io_wq_data *data) ret = -ENOMEM ; goto err; } +refcount_set (&wq->use_refs,1 );reinit_completion (&wq->done);return wq; }
@@ -1093,7 +1096,7 @@ static bool io_wq_worker_wake(struct io_worker *worker, void *data)return false; } -void io_wq_destroy (struct io_wq *wq) +static void __io_wq_destroy (struct io_wq *wq) {int node;
@@ -1113,3 +1116,9 @@ void io_wq_destroy(struct io_wq *wq)kfree (wq->wqes);kfree (wq); } + +void io_wq_destroy (struct io_wq *wq) +{ +if (refcount_dec_and_test (&wq->use_refs)) +__io_wq_destroy (wq); +}
Signature · 1 line
2.25.0
Jens Axboe
maintainerPATCH 2/4 io-wq: add 'id' to io_wq
In reply to Jens AxboeAdd each io_wq to a global list, and assign an id for each of them. This is in preparation for attaching to an existing io_wq, rather than creating a new one.
--- fs/io-wq.c | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-)
fs/io-wq.c +25 -2
@@ -16,9 +16,14 @@#include <linux/slab.h> #include <linux/kthread.h> #include <linux/rculist_nulls.h> +#include <linux/idr.h> #include "io-wq.h" +static LIST_HEAD (wq_list); +static DEFINE_MUTEX (wq_lock); +static DEFINE_IDA (wq_ida); +#define WORKER_IDLE_TIMEOUT (5 * HZ)enum {
@@ -115,6 +120,8 @@ struct io_wq {struct completion done;refcount_t use_refs; +struct list_head wq_list; +unsigned int id; };static bool io_worker_get (struct io_worker *worker)
@@ -1019,7 +1026,7 @@ void io_wq_flush(struct io_wq *wq)struct io_wq *io_wq_create (unsigned bounded,struct io_wq_data *data) { -int ret = -ENOMEM , node; +int ret = -ENOMEM , node, id;struct io_wq *wq; wq =kzalloc (sizeof (*wq),GFP_KERNEL );
@@ -1076,6 +1083,16 @@ struct io_wq *io_wq_create(unsigned bounded, struct io_wq_data *data) goto err; }refcount_set (&wq->use_refs,1 ); + + id =ida_simple_get (&wq_ida,1 ,INT_MAX ,GFP_KERNEL ); +if (id == -ENOSPC ) { + ret = -ENOMEM ; + goto err; + } +mutex_lock (&wq_lock); + wq->id = id; +list_add (&wq->wq_list, &wq_list); +mutex_unlock (&wq_lock);reinit_completion (&wq->done);return wq; }
@@ -1119,6 +1136,12 @@ static void __io_wq_destroy(struct io_wq *wq)void io_wq_destroy (struct io_wq *wq) { -if (refcount_dec_and_test (&wq->use_refs)) +if (refcount_dec_and_test (&wq->use_refs)) { +mutex_lock (&wq_lock); +ida_simple_remove (&wq_ida, wq->id); +list_del (&wq->wq_list); +mutex_unlock (&wq_lock); +__io_wq_destroy (wq); + } }
Signature · 1 line
2.25.0
Jens Axboe
maintainerPATCH 3/4 io-wq: allow lookup of existing io_wq with given id
In reply to Jens AxboeIf the id and user/creds match, return an existing io_wq if we can safely grab a reference to it.
--- fs/io-wq.c | 42 +++++++++++++++++++++++++++++++++++++++++- fs/io-wq.h | 3 +++ 2 files changed, 44 insertions(+), 1 deletion(-)
fs/io-wq.c +41 -1
@@ -1024,7 +1024,7 @@ void io_wq_flush(struct io_wq *wq) } } -struct io_wq *io_wq_create (unsigned bounded,struct io_wq_data *data) +static struct io_wq *__io_wq_create (unsigned bounded,struct io_wq_data *data) {int ret = -ENOMEM , node, id;struct io_wq *wq;
@@ -1107,6 +1107,41 @@ struct io_wq *io_wq_create(unsigned bounded, struct io_wq_data *data)return ERR_PTR (ret); } +struct io_wq *io_wq_create (unsigned bounded,struct io_wq_data *data) +{ +return __io_wq_create (bounded, data); +} + +/* +* Find and return io_wq with given id and grab a reference to it. +*/ +struct io_wq *io_wq_create_id (unsigned bounded,struct io_wq_data *data, +unsigned int id) +{ +struct io_wq *wq, *ret =NULL ; + +mutex_lock (&wq_lock); +list_for_each_entry (wq, &wq_list, wq_list) { +if (id != wq->id) +continue ; +if (data->creds != wq->creds || data->user != wq->user) +continue ; +if (data->get_work != wq->get_work || + data->put_work != wq->put_work) +continue ; +if (!refcount_inc_not_zero (&wq->use_refs)) +continue ; + ret = wq; +break ; + } +mutex_unlock (&wq_lock); + +if (!ret) + ret =io_wq_create (bounded, data); + +return ret; +} +static bool io_wq_worker_wake (struct io_worker *worker,void *data) {wake_up_process (worker->task);
@@ -1145,3 +1180,8 @@ void io_wq_destroy(struct io_wq *wq)__io_wq_destroy (wq); } } + +unsigned int io_wq_id (struct io_wq *wq) +{ +return wq->id; +}
fs/io-wq.h +3 -0
@@ -98,7 +98,10 @@ struct io_wq_data { };struct io_wq *io_wq_create (unsigned bounded,struct io_wq_data *data); +struct io_wq *io_wq_create_id (unsigned bounded,struct io_wq_data *data, +unsigned int id);void io_wq_destroy (struct io_wq *wq); +unsigned int io_wq_id (struct io_wq *wq);void io_wq_enqueue (struct io_wq *wq,struct io_wq_work *work);void io_wq_enqueue_hashed (struct io_wq *wq,struct io_wq_work *work,void *val);
Signature · 1 line
2.25.0
Re: [PATCH 3/4] io-wq: allow lookup of existing io_wq with given id
Quoted 13 lines
fs/io-wq.c +13
-0+/* +* Find and return io_wq with given id and grab a reference to it. +*/ +struct io_wq *io_wq_create_id (unsigned bounded,struct io_wq_data *data, +unsigned int id) +{ +struct io_wq *wq, *ret =NULL ; + +mutex_lock (&wq_lock); +list_for_each_entry (wq, &wq_list, wq_list) { +if (id != wq->id) +continue ; +if (data->creds != wq->creds || data->user != wq->user)
fs/io-wq.c struct io_wq *io_wq_create(unsigned bounded, struct io_wq_data *data) · line 1137
Quoted 10 lines
fs/io-wq.c +10
-0+continue ; +if (data->get_work != wq->get_work || + data->put_work != wq->put_work) +continue ; +if (!refcount_inc_not_zero (&wq->use_refs)) +continue ; + ret = wq; +break ; + } +mutex_unlock (&wq_lock);
Isn't there a more efficient ida_find function in order to avoid the loop, which won't really scale in the long run.
metze
Jens Axboe
maintainerRe: [PATCH 3/4] io-wq: allow lookup of existing io_wq with given id
Quoted 18 lines · Stefan Metzmacher
Quoted 18 lines
fs/io-wq.c +18
-0+/* +* Find and return io_wq with given id and grab a reference to it. +*/ +struct io_wq *io_wq_create_id (unsigned bounded,struct io_wq_data *data, +unsigned int id) +{ +struct io_wq *wq, *ret =NULL ; + +mutex_lock (&wq_lock); +list_for_each_entry (wq, &wq_list, wq_list) { +if (id != wq->id) +continue ; +if (data->creds != wq->creds || data->user != wq->user) +continue ; +if (data->get_work != wq->get_work || + data->put_work != wq->put_work) +continue ; +if (!refcount_inc_not_zero (&wq->use_refs))
Quoted 8 lines
fs/io-wq.c struct io_wq *io_wq_create(unsigned bounded, struct io_wq_data *data) · line 1137
Quoted 5 lines
fs/io-wq.c +5
-0+continue ; + ret = wq; +break ; + } +mutex_unlock (&wq_lock);Isn't there a more efficient
ida_findfunction in order to avoid the loop, which won't really scale in the long run.
Yeah that would be a lot better - I initially just used a sequence for this, but since I'm now using ida, might as well use it for lookup as well. I'll make the change.
Signature · 1 line
Jens Axboe
Jens Axboe
maintainerPATCH 4/4 io_uring: add support for sharing kernel io-wq workqueue
In reply to Jens AxboeAn 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.
--- fs/io_uring.c | 9 +++++++-- include/uapi/linux/io_uring.h | 4 +++- 2 files changed, 10 insertions(+), 3 deletions(-)
fs/io_uring.c +7 -2
@@ -5796,13 +5796,18 @@ 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); + +if (ctx->flags &IORING_SETUP_SHARED ) + ctx->io_wq =io_wq_create_id (concurrency, &data, p->id); +else + ctx->io_wq =io_wq_create (concurrency, &data);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);
@@ -6626,7 +6631,7 @@ 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_SHARED ))return -EINVAL ; ret =io_uring_create (entries, &p);
include/uapi/linux/io_uring.h +3 -1
@@ -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_SHARED (1U << 5)/* share workqueue */ enum {IORING_OP_NOP ,
@@ -184,7 +185,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; };
Signature · 1 line
2.25.0
Hi Jens,
Quoted 11 lines
Sometimes an applications wants to use multiple smaller rings, because it's more efficient than sharing a ring. The downside of that is that we'll create the io-wq backend separately for all of them, while they would be perfectly happy just sharing that.
This patchset adds support for that.
io_uring_paramsgrows an 'id' field, which denotes an identifier for the async backend. If an application wants to utilize sharing, it'll simply grab the id from the first ring created, and pass it in to the next one and setIORING_SETUP_SHARED. This allows efficient sharing of backend resources, while allowing multiple rings in the application or library.
But still all rings need to use the same creds, correct?
Quoted 2 lines
Not a huge fan of the
IORING_SETUP_SHAREDname, we should probably make that better (I'm taking suggestions).
The flag is supposed to be used for the new ring that attached to the existing workqueue, correct?
What about IORING_ATTACH_TO_WORKQUEUE?
metze
Jens Axboe
maintainerQuoted 7 lines · Stefan Metzmacher
Hi Jens,
Quoted 5 lines
Sometimes an applications wants to use multiple smaller rings, because it's more efficient than sharing a ring. The downside of that is that we'll create the io-wq backend separately for all of them, while they would be perfectly happy just sharing that.
Quoted 8 lines
Quoted 6 lines
This patchset adds support for that.
io_uring_paramsgrows an 'id' field, which denotes an identifier for the async backend. If an application wants to utilize sharing, it'll simply grab the id from the first ring created, and pass it in to the next one and setIORING_SETUP_SHARED. This allows efficient sharing of backend resources, while allowing multiple rings in the application or library.But still all rings need to use the same creds, correct?
Right
Quoted 5 lines
Quoted 2 lines
Not a huge fan of the
IORING_SETUP_SHAREDname, we should probably make that better (I'm taking suggestions).The flag is supposed to be used for the new ring that attached to the existing workqueue, correct?
Yes - any ring setup will return an id in the io_uring_params, attaching to an existing one is done by setting the flag and putting the id number you want to attach to in there.
Quoted 1 line
What about
IORING_ATTACH_TO_WORKQUEUE?
Trying to avoid something that is too tied to the internals, but workqueue (or wq) is probably generic enough that it can be used. IORING_SETUP_ATTACH_WQ?
Signature · 1 line
Jens Axboe
Hi Jens,
Quoted 3 lines
Trying to avoid something that is too tied to the internals, but workqueue (or wq) is probably generic enough that it can be used.
IORING_SETUP_ATTACH_WQ?
Ok :-)
metze
Jens Axboe
maintainerQuoted 7 lines · Stefan Metzmacher
Hi Jens,
Quoted 3 lines
Trying to avoid something that is too tied to the internals, but workqueue (or wq) is probably generic enough that it can be used.
IORING_SETUP_ATTACH_WQ?Ok :-)
It has been done!
Signature · 1 line
Jens Axboe
Quoted 12 lines · Jens Axboe
Sometimes an applications wants to use multiple smaller rings, because it's more efficient than sharing a ring. The downside of that is that we'll create the io-wq backend separately for all of them, while they would be perfectly happy just sharing that.
This patchset adds support for that.
io_uring_paramsgrows an 'id' field, which denotes an identifier for the async backend. If an application wants to utilize sharing, it'll simply grab the id from the first ring created, and pass it in to the next one and setIORING_SETUP_SHARED. This allows efficient sharing of backend resources, while allowing multiple rings in the application or library.
Quoted 3 lines
Not a huge fan of the
IORING_SETUP_SHAREDname, we should probably make that better (I'm taking suggestions).
Took a look at the latest version (b942f31ee0 at io_uring-vfs-shared-wq). There is an outdated commit message for the last patch mentioning renamed IORING_SETUP_SHARED, but the code looks good to me.
Signature · 1 line
Pavel Begunkov
Jens Axboe
maintainerQuoted 17 lines · Pavel Begunkov
Quoted 12 lines · Jens Axboe
Sometimes an applications wants to use multiple smaller rings, because it's more efficient than sharing a ring. The downside of that is that we'll create the io-wq backend separately for all of them, while they would be perfectly happy just sharing that.
This patchset adds support for that.
io_uring_paramsgrows an 'id' field, which denotes an identifier for the async backend. If an application wants to utilize sharing, it'll simply grab the id from the first ring created, and pass it in to the next one and setIORING_SETUP_SHARED. This allows efficient sharing of backend resources, while allowing multiple rings in the application or library.Quoted 3 lines
Not a huge fan of the
IORING_SETUP_SHAREDname, we should probably make that better (I'm taking suggestions).
Quoted 5 lines
Took a look at the latest version (
b942f31ee0at io_uring-vfs-shared-wq). There is an outdated commit message for the last patch mentioning renamedIORING_SETUP_SHARED, but the code looks good to me.Reviewed-by Pavel Begunkov <[email protected]>
Thanks for the review, I'll add your reviewed-by and fix up that commit message too.
Signature · 1 line
Jens Axboe
Quoted 13 lines · Jens Axboe
Sometimes an applications wants to use multiple smaller rings, because it's more efficient than sharing a ring. The downside of that is that we'll create the io-wq backend separately for all of them, while they would be perfectly happy just sharing that.
This patchset adds support for that.
io_uring_paramsgrows an 'id' field, which denotes an identifier for the async backend. If an application wants to utilize sharing, it'll simply grab the id from the first ring created, and pass it in to the next one and setIORING_SETUP_SHARED. This allows efficient sharing of backend resources, while allowing multiple rings in the application or library.
Quoted 2 lines
Not a huge fan of the
IORING_SETUP_SHAREDname, we should probably make that better (I'm taking suggestions).
I don't love the idea of some new type of magic user<>kernel identifier. It would be nice if the id itself was e.g. a file descriptor
What if when creating an io_uring you could pass in an existing io_uring file descriptor, and the new one would share the io-wq backend?
Quoted 10 lines · Daurnimator
On Fri, 24 Jan 2020 at 10:16, Jens Axboe <[email protected]> wrote:
I don't love the idea of some new type of magic user<>kernel identifier. It would be nice if the id itself was e.g. a file descriptor
What if when creating an
io_uringyou could pass in an existingio_uringfile descriptor, and the new one would share the io-wq backend?
Good idea! It can solve potential problems with jails, isolation, etc in the future.
May we need having other shared resources and want fine-grained control over them at some moment? It can prove helpful for the BPF plans. E.g.
io_uring_setup(share_io-wq=ring_fd1,
share_fds=ring_fd2,
share_ebpf=ring_fd3, ...);If so, it's better to have more flexible API. E.g. as follows or a pointer to a struct with @size field.
struct io_shared_resource {
int type;
int fd;
};struct io_uring_params {
...
struct io_shared_resource shared[];
};params = {
...
.shared = {{ATTACH_IO_WQ, fd1}, ..., SANTINEL_ENTRY};
};Signature · 1 line
Pavel Begunkov
Jens Axboe
maintainerQuoted 35 lines · Pavel Begunkov
Quoted 10 lines · Daurnimator
On Fri, 24 Jan 2020 at 10:16, Jens Axboe <[email protected]> wrote:
I don't love the idea of some new type of magic user<>kernel identifier. It would be nice if the id itself was e.g. a file descriptor
What if when creating an
io_uringyou could pass in an existingio_uringfile descriptor, and the new one would share the io-wq backend?Good idea! It can solve potential problems with jails, isolation, etc in the future.
May we need having other shared resources and want fine-grained control over them at some moment? It can prove helpful for the BPF plans. E.g.
io_uring_setup(share_io-wq=ring_fd1,
share_fds=ring_fd2, share_ebpf=ring_fd3, ...);If so, it's better to have more flexible API. E.g. as follows or a pointer to a struct with @size field.
struct io_shared_resource { int type; int fd; };struct io_uring_params { ... struct io_shared_resource shared[]; };
Quoted 4 lines
params = {
...
.shared = {{ATTACH_IO_WQ, fd1}, ..., SANTINEL_ENTRY};
};I'm fine with changing/extending the sharing API, please send a patch!
Signature · 1 line
Jens Axboe
Quoted 36 lines · Jens Axboe
Quoted 35 lines · Pavel Begunkov
Quoted 10 lines · Daurnimator
On Fri, 24 Jan 2020 at 10:16, Jens Axboe <[email protected]> wrote:
I don't love the idea of some new type of magic user<>kernel identifier. It would be nice if the id itself was e.g. a file descriptor
What if when creating an
io_uringyou could pass in an existingio_uringfile descriptor, and the new one would share the io-wq backend?Good idea! It can solve potential problems with jails, isolation, etc in the future.
May we need having other shared resources and want fine-grained control over them at some moment? It can prove helpful for the BPF plans. E.g.
io_uring_setup(share_io-wq=ring_fd1,
share_fds=ring_fd2, share_ebpf=ring_fd3, ...);If so, it's better to have more flexible API. E.g. as follows or a pointer to a struct with @size field.
struct io_shared_resource { int type; int fd; };struct io_uring_params { ... struct io_shared_resource shared[]; };
Quoted 8 lines
Quoted 4 lines
params = { ... .shared = {{ATTACH_IO_WQ, fd1}, ..., SANTINEL_ENTRY}; };I'm fine with changing/extending the sharing API, please send a patch!
Ok. I can't promise it'll play handy for sharing. Though, you'll be out of space in struct io_uring_params soon anyway.
Signature · 1 line
Pavel Begunkov
Jens Axboe
maintainerQuoted 42 lines · Pavel Begunkov
Quoted 41 lines · Jens Axboe
Quoted 39 lines · Pavel Begunkov
Quoted 10 lines · Daurnimator
On Fri, 24 Jan 2020 at 10:16, Jens Axboe <[email protected]> wrote:
I don't love the idea of some new type of magic user<>kernel identifier. It would be nice if the id itself was e.g. a file descriptor
What if when creating an
io_uringyou could pass in an existingio_uringfile descriptor, and the new one would share the io-wq backend?Good idea! It can solve potential problems with jails, isolation, etc in the future.
May we need having other shared resources and want fine-grained control over them at some moment? It can prove helpful for the BPF plans. E.g.
io_uring_setup(share_io-wq=ring_fd1,
share_fds=ring_fd2, share_ebpf=ring_fd3, ...);If so, it's better to have more flexible API. E.g. as follows or a pointer to a struct with @size field.
struct io_shared_resource { int type; int fd; };struct io_uring_params { ... struct io_shared_resource shared[]; };params = { ... .shared = {{ATTACH_IO_WQ, fd1}, ..., SANTINEL_ENTRY}; };
Quoted 6 lines
Quoted 3 lines
I'm fine with changing/extending the sharing API, please send a patch!
Ok. I can't promise it'll play handy for sharing. Though, you'll be out of space in struct
io_uring_paramssoon anyway.
I'm going to keep what we have for now, as I'm really not imagining a lot more sharing - what else would we share? So let's not over-design anything.
Signature · 1 line
Jens Axboe
Quoted 12 lines · Jens Axboe
Quoted 6 lines · Pavel Begunkov
Quoted 3 lines · Jens Axboe
Quoted 2 lines · Pavel Begunkov
Quoted 1 line · Daurnimator
On Fri, 24 Jan 2020 at 10:16, Jens Axboe <[email protected]> wrote:
Ok. I can't promise it'll play handy for sharing. Though, you'll be out of space in struct
io_uring_paramssoon anyway.I'm going to keep what we have for now, as I'm really not imagining a lot more sharing - what else would we share? So let's not over-design anything.
Fair enough. I prefer a ptr to an extendable struct, that will take the last u64, when needed.
However, it's still better to share through file descriptors. It's just not secure enough the way it's now.
Signature · 1 line
Pavel Begunkov
Quoted 13 lines · Pavel Begunkov
Quoted 12 lines · Jens Axboe
Quoted 6 lines · Pavel Begunkov
Quoted 3 lines · Jens Axboe
Quoted 2 lines · Pavel Begunkov
Quoted 1 line · Daurnimator
On Fri, 24 Jan 2020 at 10:16, Jens Axboe <[email protected]> wrote:
Ok. I can't promise it'll play handy for sharing. Though, you'll be out of space in struct
io_uring_paramssoon anyway.I'm going to keep what we have for now, as I'm really not imagining a lot more sharing - what else would we share? So let's not over-design anything.
Quoted 6 lines
Fair enough. I prefer a ptr to an extendable struct, that will take the last u64, when needed.
However, it's still better to share through file descriptors. It's just not secure enough the way it's now.
I'll send a patch with fd-approach shortly, just if you want to squeeze them into 5.6-rc
Signature · 1 line
Pavel Begunkov
Jens Axboe
maintainerQuoted 17 lines · Pavel Begunkov
Quoted 16 lines · Pavel Begunkov
Quoted 12 lines · Jens Axboe
Quoted 6 lines · Pavel Begunkov
Quoted 3 lines · Jens Axboe
Quoted 2 lines · Pavel Begunkov
Quoted 1 line · Daurnimator
On Fri, 24 Jan 2020 at 10:16, Jens Axboe <[email protected]> wrote:
Ok. I can't promise it'll play handy for sharing. Though, you'll be out of space in struct
io_uring_paramssoon anyway.I'm going to keep what we have for now, as I'm really not imagining a lot more sharing - what else would we share? So let's not over-design anything.
Fair enough. I prefer a ptr to an extendable struct, that will take the last u64, when needed.
Quoted 6 lines
Quoted 3 lines
However, it's still better to share through file descriptors. It's just not secure enough the way it's now.
I'll send a patch with fd-approach shortly, just if you want to squeeze them into 5.6-rc
We'll see how it pans out, I'll ship what I have now and we'll still have plenty of time to adjust if we deem that a better path.
Signature · 1 line
Jens Axboe
Jens Axboe
maintainerQuoted 13 lines · Pavel Begunkov
Quoted 12 lines · Jens Axboe
Quoted 6 lines · Pavel Begunkov
Quoted 3 lines · Jens Axboe
Quoted 2 lines · Pavel Begunkov
Quoted 1 line · Daurnimator
On Fri, 24 Jan 2020 at 10:16, Jens Axboe <[email protected]> wrote:
Ok. I can't promise it'll play handy for sharing. Though, you'll be out of space in struct
io_uring_paramssoon anyway.I'm going to keep what we have for now, as I'm really not imagining a lot more sharing - what else would we share? So let's not over-design anything.
Quoted 5 lines
Fair enough. I prefer a ptr to an extendable struct, that will take the last u64, when needed.
However, it's still better to share through file descriptors. It's just not secure enough the way it's now.
Is the file descriptor value really a good choice? We just had some confusion on ring sharing across forks. Not sure using an fd value is a sane "key" to use across processes.
Signature · 1 line
Jens Axboe
Quoted 17 lines · Jens Axboe
Quoted 16 lines · Pavel Begunkov
Quoted 12 lines · Jens Axboe
Quoted 6 lines · Pavel Begunkov
Quoted 3 lines · Jens Axboe
Quoted 2 lines · Pavel Begunkov
Quoted 1 line · Daurnimator
On Fri, 24 Jan 2020 at 10:16, Jens Axboe <[email protected]> wrote:
Ok. I can't promise it'll play handy for sharing. Though, you'll be out of space in struct
io_uring_paramssoon anyway.I'm going to keep what we have for now, as I'm really not imagining a lot more sharing - what else would we share? So let's not over-design anything.
Fair enough. I prefer a ptr to an extendable struct, that will take the last u64, when needed.
Quoted 7 lines
Quoted 2 lines
However, it's still better to share through file descriptors. It's just not secure enough the way it's now.
Is the file descriptor value really a good choice? We just had some confusion on ring sharing across forks. Not sure using an fd value is a sane "key" to use across processes.
As I see it, the problem with @mm is that uring is dead-bound to it. For example, a process can create and send uring (e.g. via socket), and then be killed. And that basically means
1. @mm of the process is locked just because of the sent uring instance.
2. a process may have an io_uring, which bound to @mm of another process, even though the layouts may be completely different.
File descriptors are different here, because io_uring doesn't know about them, They are controlled by the userspace (send, dup, fork, etc), and don't sabotage all isolation work done in the kernel. A dire example here is stealing io-wq from within a container, which is trivial with global self-made id. I would love to hear, if I am mistaken somewhere.
Is there some better option?
Signature · 1 line
Pavel Begunkov
Jens Axboe
maintainerQuoted 33 lines · Pavel Begunkov
Quoted 17 lines · Jens Axboe
Quoted 16 lines · Pavel Begunkov
Quoted 12 lines · Jens Axboe
Quoted 6 lines · Pavel Begunkov
Quoted 3 lines · Jens Axboe
Quoted 2 lines · Pavel Begunkov
Quoted 1 line · Daurnimator
On Fri, 24 Jan 2020 at 10:16, Jens Axboe <[email protected]> wrote:
Ok. I can't promise it'll play handy for sharing. Though, you'll be out of space in struct
io_uring_paramssoon anyway.I'm going to keep what we have for now, as I'm really not imagining a lot more sharing - what else would we share? So let's not over-design anything.
Fair enough. I prefer a ptr to an extendable struct, that will take the last u64, when needed.
Quoted 7 lines
Quoted 2 lines
However, it's still better to share through file descriptors. It's just not secure enough the way it's now.
Is the file descriptor value really a good choice? We just had some confusion on ring sharing across forks. Not sure using an fd value is a sane "key" to use across processes.
As I see it, the problem with @mm is that uring is dead-bound to it. For example, a process can create and send uring (e.g. via socket), and then be killed. And that basically means
1. @mm of the process is locked just because of the sent uring instance.
2. a process may have anio_uring, which bound to @mm of another process, even though the layouts may be completely different.
Quoted 8 lines
File descriptors are different here, because
io_uringdoesn't know about them, They are controlled by the userspace (send, dup, fork, etc), and don't sabotage all isolation work done in the kernel. A dire example here is stealing io-wq from within a container, which is trivial with global self-made id. I would love to hear, if I am mistaken somewhere.Is there some better option?
OK, so how about this:
- We use the 'fd' as the lookup key. This makes it easy since we can just check if it's a io_uring instance or not, we don't need to do any tracking on the side. It also means that the application asking for sharing must already have some relationship to the process that created the ring.
- mm/creds must be transferred through the work item. Any SQE done on behalf of io_uring_enter() directly already has that, if punted we must pass the creds and mm. This means we break the static setup of io_wq->mm/creds. It also means that we probably have to add that to io_wq_work, which kind of sucks, but...
I think with that we have a decent setup, that's also safe. I've dropped the sharing patches for now, from the 5.6 tree.
Signature · 1 line
Jens Axboe
Jens Axboe
maintainerQuoted 51 lines · Jens Axboe
Quoted 33 lines · Pavel Begunkov
Quoted 17 lines · Jens Axboe
Quoted 16 lines · Pavel Begunkov
Quoted 12 lines · Jens Axboe
Quoted 6 lines · Pavel Begunkov
Quoted 3 lines · Jens Axboe
Quoted 2 lines · Pavel Begunkov
Quoted 1 line · Daurnimator
On Fri, 24 Jan 2020 at 10:16, Jens Axboe <[email protected]> wrote:
Ok. I can't promise it'll play handy for sharing. Though, you'll be out of space in struct
io_uring_paramssoon anyway.I'm going to keep what we have for now, as I'm really not imagining a lot more sharing - what else would we share? So let's not over-design anything.
Fair enough. I prefer a ptr to an extendable struct, that will take the last u64, when needed.
Quoted 7 lines
Quoted 2 lines
However, it's still better to share through file descriptors. It's just not secure enough the way it's now.
Is the file descriptor value really a good choice? We just had some confusion on ring sharing across forks. Not sure using an fd value is a sane "key" to use across processes.
As I see it, the problem with @mm is that uring is dead-bound to it. For example, a process can create and send uring (e.g. via socket), and then be killed. And that basically means
1. @mm of the process is locked just because of the sent uring instance.
2. a process may have anio_uring, which bound to @mm of another process, even though the layouts may be completely different.Quoted 8 lines
File descriptors are different here, because
io_uringdoesn't know about them, They are controlled by the userspace (send, dup, fork, etc), and don't sabotage all isolation work done in the kernel. A dire example here is stealing io-wq from within a container, which is trivial with global self-made id. I would love to hear, if I am mistaken somewhere.Is there some better option?
OK, so how about this:
- We use the 'fd' as the lookup key. This makes it easy since we can just check if it's a
io_uringinstance or not, we don't need to do any tracking on the side. It also means that the application asking for sharing must already have some relationship to the process that created the ring.
Quoted 5 lines
- mm/creds must be transferred through the work item. Any SQE done on behalf of
io_uring_enter()directly already has that, if punted we must pass the creds and mm. This means we break the static setup of io_wq->mm/creds. It also means that we probably have to add that toio_wq_work, which kind of sucks, but...
It'd fix Stefan's worry too.
Quoted 2 lines
I think with that we have a decent setup, that's also safe. I've dropped the sharing patches for now, from the 5.6 tree.
So one concern might be SQPOLL, it'll have to use the ctx creds and mm as usual. I guess that is ok.
Signature · 1 line
Jens Axboe
Quoted 44 lines · Jens Axboe
Quoted 43 lines · Jens Axboe
Quoted 41 lines · Pavel Begunkov
Quoted 17 lines · Jens Axboe
Quoted 16 lines · Pavel Begunkov
Quoted 12 lines · Jens Axboe
Quoted 6 lines · Pavel Begunkov
Quoted 3 lines · Jens Axboe
Quoted 2 lines · Pavel Begunkov
Quoted 1 line · Daurnimator
On Fri, 24 Jan 2020 at 10:16, Jens Axboe <[email protected]> wrote:
Ok. I can't promise it'll play handy for sharing. Though, you'll be out of space in struct
io_uring_paramssoon anyway.I'm going to keep what we have for now, as I'm really not imagining a lot more sharing - what else would we share? So let's not over-design anything.
Fair enough. I prefer a ptr to an extendable struct, that will take the last u64, when needed.
Quoted 7 lines
Quoted 2 lines
However, it's still better to share through file descriptors. It's just not secure enough the way it's now.
Is the file descriptor value really a good choice? We just had some confusion on ring sharing across forks. Not sure using an fd value is a sane "key" to use across processes.
As I see it, the problem with @mm is that uring is dead-bound to it. For example, a process can create and send uring (e.g. via socket), and then be killed. And that basically means
1. @mm of the process is locked just because of the sent uring instance.
2. a process may have anio_uring, which bound to @mm of another process, even though the layouts may be completely different.File descriptors are different here, because
io_uringdoesn't know about them, They are controlled by the userspace (send, dup, fork, etc), and don't sabotage all isolation work done in the kernel. A dire example here is stealing io-wq from within a container, which is trivial with global self-made id. I would love to hear, if I am mistaken somewhere.Is there some better option?
Quoted 7 lines
Quoted 7 lines
OK, so how about this:
- We use the 'fd' as the lookup key. This makes it easy since we can just check if it's a
io_uringinstance or not, we don't need to do any tracking on the side. It also means that the application asking for sharing must already have some relationship to the process that created the ring.
Yeah, that's exactly the point.
Quoted 6 lines
Quoted 6 lines
- mm/creds must be transferred through the work item. Any SQE done on behalf of
io_uring_enter()directly already has that, if punted we must pass the creds and mm. This means we break the static setup of io_wq->mm/creds. It also means that we probably have to add that toio_wq_work, which kind of sucks, but...
ehh, juggling mm's... But don't have anything nicer myself.
Quoted 8 lines
It'd fix Stefan's worry too.
Quoted 2 lines
I think with that we have a decent setup, that's also safe. I've dropped the sharing patches for now, from the 5.6 tree.
So one concern might be SQPOLL, it'll have to use the ctx creds and mm as usual. I guess that is ok.
OK. I'll send the patches for the first part now, and take a look at the second one a bit latter if isn't done until then.
Signature · 1 line
Pavel Begunkov
Jens Axboe
maintainerQuoted 56 lines · Pavel Begunkov
Quoted 44 lines · Jens Axboe
Quoted 43 lines · Jens Axboe
Quoted 41 lines · Pavel Begunkov
Quoted 17 lines · Jens Axboe
Quoted 16 lines · Pavel Begunkov
Quoted 12 lines · Jens Axboe
Quoted 6 lines · Pavel Begunkov
Quoted 3 lines · Jens Axboe
Quoted 2 lines · Pavel Begunkov
Quoted 1 line · Daurnimator
On Fri, 24 Jan 2020 at 10:16, Jens Axboe <[email protected]> wrote:
Ok. I can't promise it'll play handy for sharing. Though, you'll be out of space in struct
io_uring_paramssoon anyway.I'm going to keep what we have for now, as I'm really not imagining a lot more sharing - what else would we share? So let's not over-design anything.
Fair enough. I prefer a ptr to an extendable struct, that will take the last u64, when needed.
Quoted 7 lines
Quoted 2 lines
However, it's still better to share through file descriptors. It's just not secure enough the way it's now.
Is the file descriptor value really a good choice? We just had some confusion on ring sharing across forks. Not sure using an fd value is a sane "key" to use across processes.
As I see it, the problem with @mm is that uring is dead-bound to it. For example, a process can create and send uring (e.g. via socket), and then be killed. And that basically means
1. @mm of the process is locked just because of the sent uring instance.
2. a process may have anio_uring, which bound to @mm of another process, even though the layouts may be completely different.File descriptors are different here, because
io_uringdoesn't know about them, They are controlled by the userspace (send, dup, fork, etc), and don't sabotage all isolation work done in the kernel. A dire example here is stealing io-wq from within a container, which is trivial with global self-made id. I would love to hear, if I am mistaken somewhere.Is there some better option?
Quoted 7 lines
Quoted 7 lines
OK, so how about this:
- We use the 'fd' as the lookup key. This makes it easy since we can just check if it's a
io_uringinstance or not, we don't need to do any tracking on the side. It also means that the application asking for sharing must already have some relationship to the process that created the ring.Yeah, that's exactly the point.
Quoted 1 line
Quoted 1 line
Quoted 7 lines
Quoted 5 lines
Quoted 5 lines
- mm/creds must be transferred through the work item. Any SQE done on behalf of
io_uring_enter()directly already has that, if punted we must pass the creds and mm. This means we break the static setup of io_wq->mm/creds. It also means that we probably have to add that toio_wq_work, which kind of sucks, but...ehh, juggling mm's... But don't have anything nicer myself.
We already do juggle mm's, this is no different. A worker potentially retain the mm across works if they are the same.
Quoted 11 lines
Quoted 8 lines
It'd fix Stefan's worry too.
Quoted 2 lines
I think with that we have a decent setup, that's also safe. I've dropped the sharing patches for now, from the 5.6 tree.
So one concern might be SQPOLL, it'll have to use the ctx creds and mm as usual. I guess that is ok.
OK. I'll send the patches for the first part now, and take a look at the second one a bit latter if isn't done until then.
Hang on a second, I'm doing the mm and creds bits right now. I'll push that to a branch, if you want to do the actual fd stuff on top of that, that would be great.
Signature · 1 line
Jens Axboe
Quoted 77 lines · Jens Axboe
Quoted 56 lines · Pavel Begunkov
Quoted 44 lines · Jens Axboe
Quoted 43 lines · Jens Axboe
Quoted 41 lines · Pavel Begunkov
Quoted 17 lines · Jens Axboe
Quoted 16 lines · Pavel Begunkov
Quoted 12 lines · Jens Axboe
Quoted 6 lines · Pavel Begunkov
Quoted 3 lines · Jens Axboe
Quoted 2 lines · Pavel Begunkov
Quoted 1 line · Daurnimator
On Fri, 24 Jan 2020 at 10:16, Jens Axboe <[email protected]> wrote:
Ok. I can't promise it'll play handy for sharing. Though, you'll be out of space in struct
io_uring_paramssoon anyway.I'm going to keep what we have for now, as I'm really not imagining a lot more sharing - what else would we share? So let's not over-design anything.
Fair enough. I prefer a ptr to an extendable struct, that will take the last u64, when needed.
Quoted 7 lines
Quoted 2 lines
However, it's still better to share through file descriptors. It's just not secure enough the way it's now.
Is the file descriptor value really a good choice? We just had some confusion on ring sharing across forks. Not sure using an fd value is a sane "key" to use across processes.
As I see it, the problem with @mm is that uring is dead-bound to it. For example, a process can create and send uring (e.g. via socket), and then be killed. And that basically means
1. @mm of the process is locked just because of the sent uring instance.
2. a process may have anio_uring, which bound to @mm of another process, even though the layouts may be completely different.File descriptors are different here, because
io_uringdoesn't know about them, They are controlled by the userspace (send, dup, fork, etc), and don't sabotage all isolation work done in the kernel. A dire example here is stealing io-wq from within a container, which is trivial with global self-made id. I would love to hear, if I am mistaken somewhere.Is there some better option?
Quoted 7 lines
Quoted 7 lines
OK, so how about this:
- We use the 'fd' as the lookup key. This makes it easy since we can just check if it's a
io_uringinstance or not, we don't need to do any tracking on the side. It also means that the application asking for sharing must already have some relationship to the process that created the ring.Yeah, that's exactly the point.
Quoted 1 line
Quoted 1 line
Quoted 7 lines
Quoted 5 lines
Quoted 5 lines
- mm/creds must be transferred through the work item. Any SQE done on behalf of
io_uring_enter()directly already has that, if punted we must pass the creds and mm. This means we break the static setup of io_wq->mm/creds. It also means that we probably have to add that toio_wq_work, which kind of sucks, but...ehh, juggling mm's... But don't have anything nicer myself.
We already do juggle mm's, this is no different. A worker potentially retain the mm across works if they are the same.
Quoted 9 lines
Quoted 8 lines
It'd fix Stefan's worry too.
Quoted 2 lines
I think with that we have a decent setup, that's also safe. I've dropped the sharing patches for now, from the 5.6 tree.
So one concern might be SQPOLL, it'll have to use the ctx creds and mm as usual. I guess that is ok.
Quoted 7 lines
Quoted 2 lines
OK. I'll send the patches for the first part now, and take a look at the second one a bit latter if isn't done until then.
Hang on a second, I'm doing the mm and creds bits right now. I'll push that to a branch, if you want to do the actual fd stuff on top of that, that would be great.
Sure, should be trivially mergeable.
Signature · 1 line
Pavel Begunkov
Jens Axboe
maintainerQuoted 78 lines · Pavel Begunkov
Quoted 77 lines · Jens Axboe
Quoted 56 lines · Pavel Begunkov
Quoted 44 lines · Jens Axboe
Quoted 43 lines · Jens Axboe
Quoted 41 lines · Pavel Begunkov
Quoted 17 lines · Jens Axboe
Quoted 16 lines · Pavel Begunkov
Quoted 12 lines · Jens Axboe
Quoted 6 lines · Pavel Begunkov
Quoted 3 lines · Jens Axboe
Quoted 2 lines · Pavel Begunkov
Quoted 1 line · Daurnimator
On Fri, 24 Jan 2020 at 10:16, Jens Axboe <[email protected]> wrote:
Ok. I can't promise it'll play handy for sharing. Though, you'll be out of space in struct
io_uring_paramssoon anyway.I'm going to keep what we have for now, as I'm really not imagining a lot more sharing - what else would we share? So let's not over-design anything.
Fair enough. I prefer a ptr to an extendable struct, that will take the last u64, when needed.
Quoted 7 lines
Quoted 2 lines
However, it's still better to share through file descriptors. It's just not secure enough the way it's now.
Is the file descriptor value really a good choice? We just had some confusion on ring sharing across forks. Not sure using an fd value is a sane "key" to use across processes.
As I see it, the problem with @mm is that uring is dead-bound to it. For example, a process can create and send uring (e.g. via socket), and then be killed. And that basically means
1. @mm of the process is locked just because of the sent uring instance.
2. a process may have anio_uring, which bound to @mm of another process, even though the layouts may be completely different.File descriptors are different here, because
io_uringdoesn't know about them, They are controlled by the userspace (send, dup, fork, etc), and don't sabotage all isolation work done in the kernel. A dire example here is stealing io-wq from within a container, which is trivial with global self-made id. I would love to hear, if I am mistaken somewhere.Is there some better option?
Quoted 7 lines
Quoted 7 lines
OK, so how about this:
- We use the 'fd' as the lookup key. This makes it easy since we can just check if it's a
io_uringinstance or not, we don't need to do any tracking on the side. It also means that the application asking for sharing must already have some relationship to the process that created the ring.Yeah, that's exactly the point.
Quoted 1 line
Quoted 1 line
Quoted 7 lines
Quoted 5 lines
Quoted 5 lines
- mm/creds must be transferred through the work item. Any SQE done on behalf of
io_uring_enter()directly already has that, if punted we must pass the creds and mm. This means we break the static setup of io_wq->mm/creds. It also means that we probably have to add that toio_wq_work, which kind of sucks, but...ehh, juggling mm's... But don't have anything nicer myself.
We already do juggle mm's, this is no different. A worker potentially retain the mm across works if they are the same.
Quoted 9 lines
Quoted 8 lines
It'd fix Stefan's worry too.
Quoted 2 lines
I think with that we have a decent setup, that's also safe. I've dropped the sharing patches for now, from the 5.6 tree.
So one concern might be SQPOLL, it'll have to use the ctx creds and mm as usual. I guess that is ok.
Quoted 8 lines
Quoted 7 lines
Quoted 2 lines
OK. I'll send the patches for the first part now, and take a look at the second one a bit latter if isn't done until then.
Hang on a second, I'm doing the mm and creds bits right now. I'll push that to a branch, if you want to do the actual fd stuff on top of that, that would be great.
Sure, should be trivially mergeable.
https://git.kernel.dk/cgit/linux-block/log/?h=for-5.6/io_uring-vfs-wq
Top patch there is the mm/creds passing. I kind of like it even if it means we're growing io_wq_worker (and subsequently io_kiocb) by 16 bytes, as it means we can be more flexible. This solves it for this use case, but also the case that Stefan was worried about.
If you respin the last patch I had but using the fd instead, then I think we're in business.
Signature · 1 line
Jens Axboe
Am 28.01.20 um 00:38 schrieb Jens Axboe:
Quoted 86 lines · Pavel Begunkov
Quoted 85 lines · Jens Axboe
Quoted 84 lines · Pavel Begunkov
Quoted 56 lines · Jens Axboe
Quoted 44 lines · Jens Axboe
Quoted 43 lines · Pavel Begunkov
Quoted 41 lines · Jens Axboe
Quoted 17 lines · Pavel Begunkov
Quoted 16 lines · Jens Axboe
Quoted 12 lines · Pavel Begunkov
Quoted 6 lines · Jens Axboe
Quoted 3 lines · Pavel Begunkov
Quoted 2 lines · Daurnimator
On Fri, 24 Jan 2020 at 10:16, Jens Axboe <[email protected]> wrote:
Ok. I can't promise it'll play handy for sharing. Though, you'll be out of space in struct
io_uring_paramssoon anyway.I'm going to keep what we have for now, as I'm really not imagining a lot more sharing - what else would we share? So let's not over-design anything.
Fair enough. I prefer a ptr to an extendable struct, that will take the last u64, when needed.
Quoted 7 lines
Quoted 2 lines
However, it's still better to share through file descriptors. It's just not secure enough the way it's now.
Is the file descriptor value really a good choice? We just had some confusion on ring sharing across forks. Not sure using an fd value is a sane "key" to use across processes.
As I see it, the problem with @mm is that uring is dead-bound to it. For example, a process can create and send uring (e.g. via socket), and then be killed. And that basically means
1. @mm of the process is locked just because of the sent uring instance.
2. a process may have anio_uring, which bound to @mm of another process, even though the layouts may be completely different.File descriptors are different here, because
io_uringdoesn't know about them, They are controlled by the userspace (send, dup, fork, etc), and don't sabotage all isolation work done in the kernel. A dire example here is stealing io-wq from within a container, which is trivial with global self-made id. I would love to hear, if I am mistaken somewhere.Is there some better option?
Quoted 7 lines
Quoted 7 lines
OK, so how about this:
- We use the 'fd' as the lookup key. This makes it easy since we can just check if it's a
io_uringinstance or not, we don't need to do any tracking on the side. It also means that the application asking for sharing must already have some relationship to the process that created the ring.Yeah, that's exactly the point.
Quoted 1 line
Quoted 1 line
Quoted 7 lines
Quoted 5 lines
Quoted 5 lines
- mm/creds must be transferred through the work item. Any SQE done on behalf of
io_uring_enter()directly already has that, if punted we must pass the creds and mm. This means we break the static setup of io_wq->mm/creds. It also means that we probably have to add that toio_wq_work, which kind of sucks, but...ehh, juggling mm's... But don't have anything nicer myself.
We already do juggle mm's, this is no different. A worker potentially retain the mm across works if they are the same.
Quoted 11 lines
Quoted 8 lines
It'd fix Stefan's worry too.
Quoted 2 lines
I think with that we have a decent setup, that's also safe. I've dropped the sharing patches for now, from the 5.6 tree.
So one concern might be SQPOLL, it'll have to use the ctx creds and mm as usual. I guess that is ok.
OK. I'll send the patches for the first part now, and take a look at the second one a bit latter if isn't done until then.
Hang on a second, I'm doing the mm and creds bits right now. I'll push that to a branch, if you want to do the actual fd stuff on top of that, that would be great.
Quoted 8 lines
Quoted 1 line
Sure, should be trivially mergeable.
https://git.kernel.dk/cgit/linux-block/log/?h=for-5.6/io_uring-vfs-wq
Top patch there is the mm/creds passing. I kind of like it even if it means we're growing
io_wq_worker(and subsequentlyio_kiocb) by 16 bytes, as it means we can be more flexible. This solves it for this use case, but also the case that Stefan was worried about.
Ok, that means that ctx->creds is only used in the IORING_SETUP_SQPOLL case and there it's used for all requests as get_current_cred() is the same as ctx->creds from within io_sq_thread(), correct?
And in all other cases get_current_cred() is used at io_uring_enter() time.
That's good in order to make the behavior consistent again and prevents potential random security problems.
BTW: you need to revert/drop 44d282796f81eb1debc1d7cb53245b4cb3214cb5 in that branch. Or just rebase on v5.5 final?
Thanks!
metze
Quoted 23 lines · Stefan Metzmacher
Quoted 23 lines
Quoted 13 lines
Quoted 13 lines
Quoted 13 lines
Quoted 13 lines
Quoted 13 lines
OK, so how about this:
- We use the 'fd' as the lookup key. This makes it easy since we can just check if it's a
io_uringinstance or not, we don't need to do any tracking on the side. It also means that the application asking for sharing must already have some relationship to the process that created the ring.- mm/creds must be transferred through the work item. Any SQE done on behalf of
io_uring_enter()directly already has that, if punted we must pass the creds and mm. This means we break the static setup of io_wq->mm/creds. It also means that we probably have to add that toio_wq_work, which kind of sucks, but...Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
It'd fix Stefan's worry too.
Quoted 2 lines
I think with that we have a decent setup, that's also safe. I've dropped the sharing patches for now, from the 5.6 tree.
So one concern might be SQPOLL, it'll have to use the ctx creds and mm as usual. I guess that is ok.
https://git.kernel.dk/cgit/linux-block/log/?h=for-5.6/io_uring-vfs-wq
Quoted 8 lines
Quoted 4 lines
Top patch there is the mm/creds passing. I kind of like it even if it means we're growing
io_wq_worker(and subsequentlyio_kiocb) by 16 bytes, as it means we can be more flexible. This solves it for this use case, but also the case that Stefan was worried about.Ok, that means that
ctx->credsis only used in theIORING_SETUP_SQPOLLcase and there it's used for all requests asget_current_cred()is the same asctx->credsfrom withinio_sq_thread(), correct?
Right
Quoted 1 line
And in all other cases
get_current_cred()is used atio_uring_enter()time.
Exactly
Quoted 2 lines
That's good in order to make the behavior consistent again and prevents potential random security problems.
BTW, there also can be problems with registered resources. E.g. for buffers io_uring can get_user_pages() of one process, and then use the pages from another process by passing a buffer index. This is not as bad, however.
Quoted 7 lines
BTW: you need to revert/drop
44d282796f81eb1debc1d7cb53245b4cb3214cb5in that branch. Or just rebase on v5.5 final?Thanks!
metze
Signature · 1 line
Pavel Begunkov
Hi Pavel,
Quoted 7 lines
Quoted 2 lines
That's good in order to make the behavior consistent again and prevents potential random security problems.
BTW, there also can be problems with registered resources. E.g. for buffers
io_uringcanget_user_pages()of one process, and then use the pages from another process by passing a buffer index. This is not as bad, however.
Yes, but that can only happen by intention, right?
And not randomly depending on the cache state. If the application has confidential data in the registered buffers, files then it should not share the ring fd with untrusted processes.
metze
Quoted 10 lines · Stefan Metzmacher
Hi Pavel,
Quoted 7 lines
Quoted 2 lines
That's good in order to make the behavior consistent again and prevents potential random security problems.
BTW, there also can be problems with registered resources. E.g. for buffers
io_uringcanget_user_pages()of one process, and then use the pages from another process by passing a buffer index. This is not as bad, however.
Quoted 4 lines
Yes, but that can only happen by intention, right?
And not randomly depending on the cache state. If the application has confidential data in the registered buffers, files then it should not share the ring fd with untrusted processes.
Indeed, that's why it's a mild problem. Though, that's better to be said explicitly, so users know the pitfall. Worth putting into the manual, I think.
Signature · 1 line
Pavel Begunkov