On Mon, Dec 02, 2024 at 09:13:14PM -0500, Martin K. Petersen wrote: > > I have things running on my end on top of Jens' tree (without error > injection, that's to come). > > One question, though: How am I to determine that the kernel supports > attr_ptr and IORING_RW_ATTR_FLAG_PI? Now that we no longer have separate > IORING_OP_{READ,WRITE}_META commands I can't use IO_URING_OP_SUPPORTED > to find out whether the running kernel supports PI passthrough. Martin, right currently there is no way to probe whether the kernel supports read/write attributes or not. Jens, Pavel how about introducing a new IO_URING_OP_* flag (something like IO_URING_OP_RW_ATTR_SUPPORTED) to probe whether read/write attributes are supported or not. Something like this [*] [*] diff --git a/include/uapi/linux/io_uring.h b/include/uapi/linux/io_uring.h index 38f0d6b10eaf..787a2df8037f 100644 --- a/include/uapi/linux/io_uring.h +++ b/include/uapi/linux/io_uring.h @@ -723,6 +723,7 @@ struct io_uring_rsrc_update2 { #define IORING_REGISTER_FILES_SKIP (-2) #define IO_URING_OP_SUPPORTED (1U << 0) +#define IO_URING_OP_RW_ATTR_SUPPORTED (1U << 1) struct io_uring_probe_op { __u8 op; diff --git a/io_uring/opdef.c b/io_uring/opdef.c index 3de75eca1c92..64e1e5d48dec 100644 --- a/io_uring/opdef.c +++ b/io_uring/opdef.c @@ -67,6 +67,7 @@ const struct io_issue_def io_issue_defs[] = { .iopoll = 1, .iopoll_queue = 1, .vectored = 1, + .rw_attr = 1, .async_size = sizeof(struct io_async_rw), .prep = io_prep_readv, .issue = io_read, @@ -82,6 +83,7 @@ const struct io_issue_def io_issue_defs[] = { .iopoll = 1, .iopoll_queue = 1, .vectored = 1, + .rw_attr = 1, .async_size = sizeof(struct io_async_rw), .prep = io_prep_writev, .issue = io_write, @@ -101,6 +103,7 @@ const struct io_issue_def io_issue_defs[] = { .ioprio = 1, .iopoll = 1, .iopoll_queue = 1, + .rw_attr = 1, .async_size = sizeof(struct io_async_rw), .prep = io_prep_read_fixed, .issue = io_read, @@ -115,6 +118,7 @@ const struct io_issue_def io_issue_defs[] = { .ioprio = 1, .iopoll = 1, .iopoll_queue = 1, + .rw_attr = 1, .async_size = sizeof(struct io_async_rw), .prep = io_prep_write_fixed, .issue = io_write, @@ -246,6 +250,7 @@ const struct io_issue_def io_issue_defs[] = { .ioprio = 1, .iopoll = 1, .iopoll_queue = 1, + .rw_attr = 1, .async_size = sizeof(struct io_async_rw), .prep = io_prep_read, .issue = io_read, @@ -260,6 +265,7 @@ const struct io_issue_def io_issue_defs[] = { .ioprio = 1, .iopoll = 1, .iopoll_queue = 1, + .rw_attr = 1, .async_size = sizeof(struct io_async_rw), .prep = io_prep_write, .issue = io_write, diff --git a/io_uring/opdef.h b/io_uring/opdef.h index 14456436ff74..61460c762ea7 100644 --- a/io_uring/opdef.h +++ b/io_uring/opdef.h @@ -27,6 +27,8 @@ struct io_issue_def { unsigned iopoll_queue : 1; /* vectored opcode, set if 1) vectored, and 2) handler needs to know */ unsigned vectored : 1; + /* supports rw attributes */ + unsigned rw_attr : 1; /* size of async data needed, if any */ unsigned short async_size; diff --git a/io_uring/register.c b/io_uring/register.c index f1698c18c7cb..a54aeaec116c 100644 --- a/io_uring/register.c +++ b/io_uring/register.c @@ -60,8 +60,11 @@ static __cold int io_probe(struct io_ring_ctx *ctx, void __user *arg, for (i = 0; i < nr_args; i++) { p->ops[i].op = i; - if (io_uring_op_supported(i)) + if (io_uring_op_supported(i)) { p->ops[i].flags = IO_URING_OP_SUPPORTED; + if (io_issue_defs[i].rw_attr) + p->ops[i].flags |= IO_URING_OP_RW_ATTR_SUPPORTED; + } } p->ops_len = i; -- 2.25.1