Message ID | 20250301001610.678223-2-csander@purestorage.com (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | [1/2] io_uring/rsrc: declare io_find_buf_node() in header file | expand |
On 3/1/25 00:16, Caleb Sander Mateos wrote: > Call io_find_buf_node() to avoid duplicating it in io_nop(). IORING_NOP_FIXED_BUFFER interface looks odd, instead of pretending to use a buffer, it basically pokes directly into internal infra, it's not something userspace should be able to do. Jens, did use it anywhere? It's new, I'd rather kill it or align with how requests consume buffers, i.e. addr+len, and then do io_import_reg_buf() instead. That'd break the api though, but would anyone care? > Signed-off-by: Caleb Sander Mateos <csander@purestorage.com> > --- > io_uring/nop.c | 13 ++----------- > 1 file changed, 2 insertions(+), 11 deletions(-) > > diff --git a/io_uring/nop.c b/io_uring/nop.c > index ea539531cb5f..28f06285fdc2 100644 > --- a/io_uring/nop.c > +++ b/io_uring/nop.c > @@ -59,21 +59,12 @@ int io_nop(struct io_kiocb *req, unsigned int issue_flags) > ret = -EBADF; > goto done; > } > } > if (nop->flags & IORING_NOP_FIXED_BUFFER) { > - struct io_ring_ctx *ctx = req->ctx; > - struct io_rsrc_node *node; > - > - ret = -EFAULT; > - io_ring_submit_lock(ctx, issue_flags); > - node = io_rsrc_node_lookup(&ctx->buf_table, req->buf_index); > - if (node) { > - io_req_assign_buf_node(req, node); > - ret = 0; > - } > - io_ring_submit_unlock(ctx, issue_flags); > + if (!io_find_buf_node(req, issue_flags)) > + ret = -EFAULT; > } > done: > if (ret < 0) > req_set_fail(req); > io_req_set_res(req, nop->result, 0);
On Fri, Feb 28, 2025 at 5:40 PM Pavel Begunkov <asml.silence@gmail.com> wrote: > > On 3/1/25 00:16, Caleb Sander Mateos wrote: > > Call io_find_buf_node() to avoid duplicating it in io_nop(). > > IORING_NOP_FIXED_BUFFER interface looks odd, instead of pretending > to use a buffer, it basically pokes directly into internal infra, > it's not something userspace should be able to do. I assumed it was just for benchmarking the overhead of fixed buffer lookup. Since a normal IORING_OP_NOP doesn't use any buffer, it makes sense for IORING_NOP_FIXED_BUFFER not to do anything with the fixed buffer either. Added in this commit: commit a85f31052bce52111b4e9d5a536003481d0421d0 Author: Jens Axboe <axboe@kernel.dk> Date: Sun Oct 27 08:59:10 2024 io_uring/nop: add support for testing registered files and buffers Useful for testing performance/efficiency impact of registered files and buffers, vs (particularly) non-registered files. Signed-off-by: Jens Axboe <axboe@kernel.dk> Best, Caleb > > Jens, did use it anywhere? It's new, I'd rather kill it or align with > how requests consume buffers, i.e. addr+len, and then do > io_import_reg_buf() instead. That'd break the api though, but would > anyone care? > > > > Signed-off-by: Caleb Sander Mateos <csander@purestorage.com> > > --- > > io_uring/nop.c | 13 ++----------- > > 1 file changed, 2 insertions(+), 11 deletions(-) > > > > diff --git a/io_uring/nop.c b/io_uring/nop.c > > index ea539531cb5f..28f06285fdc2 100644 > > --- a/io_uring/nop.c > > +++ b/io_uring/nop.c > > @@ -59,21 +59,12 @@ int io_nop(struct io_kiocb *req, unsigned int issue_flags) > > ret = -EBADF; > > goto done; > > } > > } > > if (nop->flags & IORING_NOP_FIXED_BUFFER) { > > - struct io_ring_ctx *ctx = req->ctx; > > - struct io_rsrc_node *node; > > - > > - ret = -EFAULT; > > - io_ring_submit_lock(ctx, issue_flags); > > - node = io_rsrc_node_lookup(&ctx->buf_table, req->buf_index); > > - if (node) { > > - io_req_assign_buf_node(req, node); > > - ret = 0; > > - } > > - io_ring_submit_unlock(ctx, issue_flags); > > + if (!io_find_buf_node(req, issue_flags)) > > + ret = -EFAULT; > > } > > done: > > if (ret < 0) > > req_set_fail(req); > > io_req_set_res(req, nop->result, 0); > > -- > Pavel Begunkov >
On 2/28/25 6:58 PM, Caleb Sander Mateos wrote: > On Fri, Feb 28, 2025 at 5:40 PM Pavel Begunkov <asml.silence@gmail.com> wrote: >> >> On 3/1/25 00:16, Caleb Sander Mateos wrote: >>> Call io_find_buf_node() to avoid duplicating it in io_nop(). >> >> IORING_NOP_FIXED_BUFFER interface looks odd, instead of pretending >> to use a buffer, it basically pokes directly into internal infra, >> it's not something userspace should be able to do. > > I assumed it was just for benchmarking the overhead of fixed buffer > lookup. Since a normal IORING_OP_NOP doesn't use any buffer, it makes > sense for IORING_NOP_FIXED_BUFFER not to do anything with the fixed > buffer either. That's exactly right, it's just for benchmarking purposes. NOP doesn't transfer anything, obviously, so it doesn't do anything with it.
On 3/1/25 01:58, Caleb Sander Mateos wrote: > On Fri, Feb 28, 2025 at 5:40 PM Pavel Begunkov <asml.silence@gmail.com> wrote: >> >> On 3/1/25 00:16, Caleb Sander Mateos wrote: >>> Call io_find_buf_node() to avoid duplicating it in io_nop(). >> >> IORING_NOP_FIXED_BUFFER interface looks odd, instead of pretending >> to use a buffer, it basically pokes directly into internal infra, >> it's not something userspace should be able to do. > > I assumed it was just for benchmarking the overhead of fixed buffer Right > lookup. Since a normal IORING_OP_NOP doesn't use any buffer, it makes > sense for IORING_NOP_FIXED_BUFFER not to do anything with the fixed > buffer either. That's a special api that benchmarks internal details that no other request knows about, no, that's not great.
On 3/1/25 01:41, Pavel Begunkov wrote: > On 3/1/25 00:16, Caleb Sander Mateos wrote: >> Call io_find_buf_node() to avoid duplicating it in io_nop(). > > IORING_NOP_FIXED_BUFFER interface looks odd, instead of pretending > to use a buffer, it basically pokes directly into internal infra, > it's not something userspace should be able to do. > > Jens, did use it anywhere? It's new, I'd rather kill it or align with > how requests consume buffers, i.e. addr+len, and then do > io_import_reg_buf() instead. That'd break the api though, but would > anyone care? 3rd option is to ignore the flag and let the req succeed.
On 2/28/25 7:15 PM, Pavel Begunkov wrote: > On 3/1/25 01:41, Pavel Begunkov wrote: >> On 3/1/25 00:16, Caleb Sander Mateos wrote: >>> Call io_find_buf_node() to avoid duplicating it in io_nop(). >> >> IORING_NOP_FIXED_BUFFER interface looks odd, instead of pretending >> to use a buffer, it basically pokes directly into internal infra, >> it's not something userspace should be able to do. >> >> Jens, did use it anywhere? It's new, I'd rather kill it or align with >> how requests consume buffers, i.e. addr+len, and then do >> io_import_reg_buf() instead. That'd break the api though, but would >> anyone care? > > 3rd option is to ignore the flag and let the req succeed. Honestly what is the problem here? NOP isn't doing anything that other commands types can't or aren't already. So no, it should stay, it's been handy for testing overheads, which is why it was added in the first place.
On 3/1/25 02:21, Jens Axboe wrote: > On 2/28/25 7:15 PM, Pavel Begunkov wrote: >> On 3/1/25 01:41, Pavel Begunkov wrote: >>> On 3/1/25 00:16, Caleb Sander Mateos wrote: >>>> Call io_find_buf_node() to avoid duplicating it in io_nop(). >>> >>> IORING_NOP_FIXED_BUFFER interface looks odd, instead of pretending >>> to use a buffer, it basically pokes directly into internal infra, >>> it's not something userspace should be able to do. >>> >>> Jens, did use it anywhere? It's new, I'd rather kill it or align with >>> how requests consume buffers, i.e. addr+len, and then do >>> io_import_reg_buf() instead. That'd break the api though, but would >>> anyone care? >> >> 3rd option is to ignore the flag and let the req succeed. > > Honestly what is the problem here? NOP isn't doing anything that > other commands types can't or aren't already. So no, it should stay, It completely ignores any checking and buffer importing stopping half way at looking at nodes, the behaviour other requests don't do. We can also add a request that take a lock and releases it back because other requests do that as well but as a part of some useful sequence of actions. > it's been handy for testing overheads, which is why it was added in > the first place.
On 2/28/25 7:36 PM, Pavel Begunkov wrote: > On 3/1/25 02:21, Jens Axboe wrote: >> On 2/28/25 7:15 PM, Pavel Begunkov wrote: >>> On 3/1/25 01:41, Pavel Begunkov wrote: >>>> On 3/1/25 00:16, Caleb Sander Mateos wrote: >>>>> Call io_find_buf_node() to avoid duplicating it in io_nop(). >>>> >>>> IORING_NOP_FIXED_BUFFER interface looks odd, instead of pretending >>>> to use a buffer, it basically pokes directly into internal infra, >>>> it's not something userspace should be able to do. >>>> >>>> Jens, did use it anywhere? It's new, I'd rather kill it or align with >>>> how requests consume buffers, i.e. addr+len, and then do >>>> io_import_reg_buf() instead. That'd break the api though, but would >>>> anyone care? >>> >>> 3rd option is to ignore the flag and let the req succeed. >> >> Honestly what is the problem here? NOP isn't doing anything that >> other commands types can't or aren't already. So no, it should stay, > > It completely ignores any checking and buffer importing stopping > half way at looking at nodes, the behaviour other requests don't > do. We can also add a request that take a lock and releases it > back because other requests do that as well but as a part of some > useful sequence of actions. Let's not resort to hyperbole - it's useful to be able to test (and hence quantify) provided buffer usage. I used it while doing the resource node rework. We also have a NOP opcode to be able to test generic overhead for that very reason. For testing _io_uring_ infrastructure it was already useful for me. Of course we should not add random things that test things like lock acquire and release, that's not the scope of NOP. Sure you could add import as well, but a) nop doesn't touch the data, and b) that's largely testing generic kernel infrastructure as well. The whole point of NOP is to be able to test io_uring infrastructure.
On 3/1/25 02:39, Jens Axboe wrote: > On 2/28/25 7:36 PM, Pavel Begunkov wrote: >> On 3/1/25 02:21, Jens Axboe wrote: >>> On 2/28/25 7:15 PM, Pavel Begunkov wrote: >>>> On 3/1/25 01:41, Pavel Begunkov wrote: >>>>> On 3/1/25 00:16, Caleb Sander Mateos wrote: >>>>>> Call io_find_buf_node() to avoid duplicating it in io_nop(). >>>>> >>>>> IORING_NOP_FIXED_BUFFER interface looks odd, instead of pretending >>>>> to use a buffer, it basically pokes directly into internal infra, >>>>> it's not something userspace should be able to do. >>>>> >>>>> Jens, did use it anywhere? It's new, I'd rather kill it or align with >>>>> how requests consume buffers, i.e. addr+len, and then do >>>>> io_import_reg_buf() instead. That'd break the api though, but would >>>>> anyone care? >>>> >>>> 3rd option is to ignore the flag and let the req succeed. >>> >>> Honestly what is the problem here? NOP isn't doing anything that >>> other commands types can't or aren't already. So no, it should stay, >> >> It completely ignores any checking and buffer importing stopping >> half way at looking at nodes, the behaviour other requests don't >> do. We can also add a request that take a lock and releases it >> back because other requests do that as well but as a part of some >> useful sequence of actions. > > Let's not resort to hyperbole - it's useful to be able to test (and That's not a hyperbole, it's a direct analogy. > hence quantify) provided buffer usage. I used it while doing the > resource node rework. We also have a NOP opcode to be able to test > generic overhead for that very reason. For testing _io_uring_ > infrastructure it was already useful for me. Of course we should not add > random things that test things like lock acquire and release, that's not > the scope of NOP. > > Sure you could add import as well, but a) nop doesn't touch the data, > and b) that's largely testing generic kernel infrastructure as well. > > The whole point of NOP is to be able to test io_uring infrastructure. And now we add overhead to test overhead of the very path we add overhead to, just splendid. It's intrusive, it looks into guts of infra that can change, and the way not to be intrusive is to follow the way others use the concept, which is why I'm suggesting importing the buffer, and that would be another direct analogy with the pure NOP (w/o flags).
diff --git a/io_uring/nop.c b/io_uring/nop.c index ea539531cb5f..28f06285fdc2 100644 --- a/io_uring/nop.c +++ b/io_uring/nop.c @@ -59,21 +59,12 @@ int io_nop(struct io_kiocb *req, unsigned int issue_flags) ret = -EBADF; goto done; } } if (nop->flags & IORING_NOP_FIXED_BUFFER) { - struct io_ring_ctx *ctx = req->ctx; - struct io_rsrc_node *node; - - ret = -EFAULT; - io_ring_submit_lock(ctx, issue_flags); - node = io_rsrc_node_lookup(&ctx->buf_table, req->buf_index); - if (node) { - io_req_assign_buf_node(req, node); - ret = 0; - } - io_ring_submit_unlock(ctx, issue_flags); + if (!io_find_buf_node(req, issue_flags)) + ret = -EFAULT; } done: if (ret < 0) req_set_fail(req); io_req_set_res(req, nop->result, 0);
Call io_find_buf_node() to avoid duplicating it in io_nop(). Signed-off-by: Caleb Sander Mateos <csander@purestorage.com> --- io_uring/nop.c | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-)