Compiling with -O0 revealed that compilers are too smart and complain about io_uring_query_opcode not being initialised. It's not an issue as it's passed to the kernel to be filled in, nevertheless, let's silence the warnings. Signed-off-by: Pavel Begunkov --- test/ring-query.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/ring-query.c b/test/ring-query.c index 971fd9ba..d0aa396c 100644 --- a/test/ring-query.c +++ b/test/ring-query.c @@ -36,7 +36,7 @@ static int io_uring_query(struct io_uring *ring, struct io_uring_query_hdr *arg) static int test_basic_query(void) { - struct io_uring_query_opcode op; + struct io_uring_query_opcode op = {}; struct io_uring_query_hdr hdr = { .query_op = IO_URING_QUERY_OPCODES, .query_data = uring_ptr_to_u64(&op), @@ -76,7 +76,7 @@ static int test_basic_query(void) static int test_invalid(void) { int ret; - struct io_uring_query_opcode op; + struct io_uring_query_opcode op = {}; struct io_uring_query_hdr invalid_hdr = { .query_op = -1U, .query_data = uring_ptr_to_u64(&op), @@ -119,7 +119,7 @@ static int test_invalid(void) static int test_chain(void) { int ret; - struct io_uring_query_opcode op1, op2, op3; + struct io_uring_query_opcode op1 = {}, op2 = {}, op3 = {}; struct io_uring_query_hdr hdr3 = { .query_op = IO_URING_QUERY_OPCODES, .query_data = uring_ptr_to_u64(&op3), @@ -163,7 +163,7 @@ static int test_chain(void) static int test_chain_loop(void) { int ret; - struct io_uring_query_opcode op1, op2; + struct io_uring_query_opcode op1 = {}, op2 = {}; struct io_uring_query_hdr hdr2 = { .query_op = IO_URING_QUERY_OPCODES, .query_data = uring_ptr_to_u64(&op2), @@ -201,7 +201,7 @@ static int test_chain_loop(void) static int test_compatibile_shorter(void) { int ret; - struct io_uring_query_opcode_short op; + struct io_uring_query_opcode_short op = {}; struct io_uring_query_hdr hdr = { .query_op = IO_URING_QUERY_OPCODES, .query_data = uring_ptr_to_u64(&op), @@ -234,7 +234,7 @@ static int test_compatibile_shorter(void) static int test_compatibile_larger(void) { int ret; - struct io_uring_query_opcode_large op; + struct io_uring_query_opcode_large op = {}; struct io_uring_query_hdr hdr = { .query_op = IO_URING_QUERY_OPCODES, .query_data = uring_ptr_to_u64(&op), -- 2.49.0 Expose a simple wrapper around IORING_REGISTER_QUERY to users. Signed-off-by: Pavel Begunkov --- src/include/liburing.h | 2 ++ src/liburing-ffi.map | 3 ++- src/liburing.map | 3 ++- src/register.c | 7 +++++++ test/ring-query.c | 7 ------- 5 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/include/liburing.h b/src/include/liburing.h index 3d4c6422..7eab7e42 100644 --- a/src/include/liburing.h +++ b/src/include/liburing.h @@ -359,6 +359,8 @@ int io_uring_register_clock(struct io_uring *ring, int io_uring_get_events(struct io_uring *ring) LIBURING_NOEXCEPT; int io_uring_submit_and_get_events(struct io_uring *ring) LIBURING_NOEXCEPT; +int io_uring_query(struct io_uring *ring, struct io_uring_query_hdr *arg); + /* * io_uring syscalls. */ diff --git a/src/liburing-ffi.map b/src/liburing-ffi.map index 4bf4fd51..6eed3f9f 100644 --- a/src/liburing-ffi.map +++ b/src/liburing-ffi.map @@ -253,5 +253,6 @@ LIBURING_2.12 { } LIBURING_2.11; LIBURING_2.13 { - + global: + io_uring_query; } LIBURING_2.12; diff --git a/src/liburing.map b/src/liburing.map index 0c4888e1..92c2af7b 100644 --- a/src/liburing.map +++ b/src/liburing.map @@ -132,5 +132,6 @@ LIBURING_2.12 { } LIBURING_2.11; LIBURING_2.13 { - + global: + io_uring_query; } LIBURING_2.12; diff --git a/src/register.c b/src/register.c index 93eda3fc..7265dcca 100644 --- a/src/register.c +++ b/src/register.c @@ -513,3 +513,10 @@ int io_uring_set_iowait(struct io_uring *ring, bool enable_iowait) ring->int_flags |= INT_FLAG_NO_IOWAIT; return 0; } + +int io_uring_query(struct io_uring *ring, struct io_uring_query_hdr *arg) +{ + int fd = ring ? ring->ring_fd : -1; + + return io_uring_register(fd, IORING_REGISTER_QUERY, arg, 0); +} diff --git a/test/ring-query.c b/test/ring-query.c index d0aa396c..e266b4a9 100644 --- a/test/ring-query.c +++ b/test/ring-query.c @@ -27,13 +27,6 @@ struct io_uring_query_opcode_large { static struct io_uring_query_opcode sys_ops; -static int io_uring_query(struct io_uring *ring, struct io_uring_query_hdr *arg) -{ - int fd = ring ? ring->ring_fd : -1; - - return io_uring_register(fd, IORING_REGISTER_QUERY, arg, 0); -} - static int test_basic_query(void) { struct io_uring_query_opcode op = {}; -- 2.49.0 Instead of relying on the kernel limiting the number of queries in a chain, send a signal. That must be able to abort the syscall. Signed-off-by: Pavel Begunkov --- test/ring-query.c | 41 ++++++++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 15 deletions(-) diff --git a/test/ring-query.c b/test/ring-query.c index e266b4a9..4c335d64 100644 --- a/test/ring-query.c +++ b/test/ring-query.c @@ -5,11 +5,14 @@ #include #include #include +#include #include "liburing.h" #include "test.h" #include "helpers.h" +pthread_barrier_t barrier; + struct io_uring_query_opcode_short { __u32 nr_request_opcodes; __u32 nr_register_opcodes; @@ -153,9 +156,8 @@ static int test_chain(void) return T_EXIT_PASS; } -static int test_chain_loop(void) +static void *chain_loop_thread(void *arg) { - int ret; struct io_uring_query_opcode op1 = {}, op2 = {}; struct io_uring_query_hdr hdr2 = { .query_op = IO_URING_QUERY_OPCODES, @@ -167,27 +169,36 @@ static int test_chain_loop(void) .query_data = uring_ptr_to_u64(&op1), .size = sizeof(struct io_uring_query_opcode), }; - struct io_uring_query_hdr hdr_self_circular = { - .query_op = IO_URING_QUERY_OPCODES, - .query_data = uring_ptr_to_u64(&op1), - .size = sizeof(struct io_uring_query_opcode), - .next_entry = uring_ptr_to_u64(&hdr_self_circular), - }; hdr1.next_entry = uring_ptr_to_u64(&hdr2); hdr2.next_entry = uring_ptr_to_u64(&hdr1); - ret = io_uring_query(NULL, &hdr1); - if (!ret) { - fprintf(stderr, "chain loop failed %i\n", ret); + + pthread_barrier_wait(&barrier); + + (void)io_uring_query(NULL, &hdr1); + return NULL; +} + +static int test_chain_loop(void) +{ + pthread_t thread; + int ret; + + ret = pthread_barrier_init(&barrier, NULL, 2); + if (ret != 0) { + fprintf(stderr, "pthread_barrier_init failed %i\n", ret); return T_EXIT_FAIL; } - - ret = io_uring_query(NULL, &hdr_self_circular); - if (!ret) { - fprintf(stderr, "chain loop failed %i\n", ret); + if (pthread_create(&thread, NULL, chain_loop_thread, NULL) != 0) { + fprintf(stderr, "pthread_create failed %i\n", ret); return T_EXIT_FAIL; } + pthread_barrier_wait(&barrier); + sleep(1); + pthread_kill(thread, SIGKILL); + pthread_join(thread, NULL); + pthread_barrier_destroy(&barrier); return T_EXIT_PASS; } -- 2.49.0