From 3401b06c5e8291a2ad946bb181ab347f18a4c8c3 Mon Sep 17 00:00:00 2001 From: Pavel Begunkov Date: Fri, 29 Sep 2023 13:09:41 +0100 Subject: [PATCH] setup: default to IORING_SETUP_NO_SQARRAY We have never exposed sq_array to users, so we can safely add IORING_SETUP_NO_SQARRAY to all rings. If the kernel is too old and it fails, we'll retry creating a ring without it. Signed-off-by: Pavel Begunkov Link: https://lore.kernel.org/r/3320b1472ff8bf5af73a17796fd6b103ed4f3e11.1695988793.git.asml.silence@gmail.com Signed-off-by: Jens Axboe --- src/setup.c | 28 +++++++++++++++++++++++----- test/accept-reuse.c | 2 +- test/helpers.h | 13 +++++++++++++ test/io_uring_enter.c | 7 +++++-- 4 files changed, 42 insertions(+), 8 deletions(-) diff --git a/src/setup.c b/src/setup.c index a0e8296ac..6b3f5381e 100644 --- a/src/setup.c +++ b/src/setup.c @@ -287,9 +287,9 @@ static int io_uring_alloc_huge(unsigned entries, struct io_uring_params *p, return (int) mem_used; } -static int __io_uring_queue_init_params(unsigned entries, struct io_uring *ring, - struct io_uring_params *p, void *buf, - size_t buf_size) +int __io_uring_queue_init_params(unsigned entries, struct io_uring *ring, + struct io_uring_params *p, void *buf, + size_t buf_size) { int fd, ret = 0; unsigned *sq_array; @@ -357,6 +357,24 @@ static int __io_uring_queue_init_params(unsigned entries, struct io_uring *ring, return ret; } +static int io_uring_queue_init_try_nosqarr(unsigned entries, struct io_uring *ring, + struct io_uring_params *p, void *buf, + size_t buf_size) +{ + unsigned flags = p->flags; + int ret; + + p->flags |= IORING_SETUP_NO_SQARRAY; + ret = __io_uring_queue_init_params(entries, ring, p, buf, buf_size); + + /* don't fallback if explicitly asked for NOSQARRAY */ + if (ret != -EINVAL || (flags & IORING_SETUP_NO_SQARRAY)) + return ret; + + p->flags = flags; + return __io_uring_queue_init_params(entries, ring, p, buf, buf_size); +} + /* * Like io_uring_queue_init_params(), except it allows the application to pass * in a pre-allocated memory range that is used for the shared data between @@ -375,7 +393,7 @@ int io_uring_queue_init_mem(unsigned entries, struct io_uring *ring, { /* should already be set... */ p->flags |= IORING_SETUP_NO_MMAP; - return __io_uring_queue_init_params(entries, ring, p, buf, buf_size); + return io_uring_queue_init_try_nosqarr(entries, ring, p, buf, buf_size); } int io_uring_queue_init_params(unsigned entries, struct io_uring *ring, @@ -383,7 +401,7 @@ int io_uring_queue_init_params(unsigned entries, struct io_uring *ring, { int ret; - ret = __io_uring_queue_init_params(entries, ring, p, NULL, 0); + ret = io_uring_queue_init_try_nosqarr(entries, ring, p, NULL, 0); return ret >= 0 ? 0 : ret; } diff --git a/test/accept-reuse.c b/test/accept-reuse.c index 1f10b45d0..716f201e2 100644 --- a/test/accept-reuse.c +++ b/test/accept-reuse.c @@ -45,7 +45,7 @@ int main(int argc, char **argv) return T_EXIT_SKIP; memset(¶ms, 0, sizeof(params)); - ret = io_uring_queue_init_params(4, &io_uring, ¶ms); + ret = t_io_uring_init_sqarray(4, &io_uring, ¶ms); if (ret) { fprintf(stderr, "io_uring_init_failed: %d\n", ret); return T_EXIT_FAIL; diff --git a/test/helpers.h b/test/helpers.h index 530732422..d91c1dc05 100644 --- a/test/helpers.h +++ b/test/helpers.h @@ -87,6 +87,19 @@ bool t_probe_defer_taskrun(void); unsigned __io_uring_flush_sq(struct io_uring *ring); +int __io_uring_queue_init_params(unsigned entries, struct io_uring *ring, + struct io_uring_params *p, void *buf, + size_t buf_size); + +static inline int t_io_uring_init_sqarray(unsigned entries, struct io_uring *ring, + struct io_uring_params *p) +{ + int ret; + + ret = __io_uring_queue_init_params(entries, ring, p, NULL, 0); + return ret >= 0 ? 0 : ret; +} + #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) void t_error(int status, int errnum, const char *format, ...); diff --git a/test/io_uring_enter.c b/test/io_uring_enter.c index ecd54ff73..2a6b6be46 100644 --- a/test/io_uring_enter.c +++ b/test/io_uring_enter.c @@ -183,13 +183,16 @@ int main(int argc, char **argv) unsigned ktail, mask, index; unsigned sq_entries; unsigned completed, dropped; + struct io_uring_params p; if (argc > 1) return T_EXIT_SKIP; - ret = io_uring_queue_init(IORING_MAX_ENTRIES, &ring, 0); + memset(&p, 0, sizeof(p)); + ret = t_io_uring_init_sqarray(IORING_MAX_ENTRIES, &ring, &p); if (ret == -ENOMEM) - ret = io_uring_queue_init(IORING_MAX_ENTRIES_FALLBACK, &ring, 0); + ret = t_io_uring_init_sqarray(IORING_MAX_ENTRIES_FALLBACK, + &ring, &p); if (ret < 0) { perror("io_uring_queue_init"); exit(T_EXIT_FAIL);