diff --git a/1001-liburing-anolis-Add-percpu-io-sq-thread-support.patch b/1001-liburing-anolis-Add-percpu-io-sq-thread-support.patch new file mode 100644 index 0000000000000000000000000000000000000000..1ca7830e18c043f4bfca554000a34d95a91b19ef --- /dev/null +++ b/1001-liburing-anolis-Add-percpu-io-sq-thread-support.patch @@ -0,0 +1,54 @@ +From c629576a5f266eedf2efbf74211581c68217d67c Mon Sep 17 00:00:00 2001 +From: Xiaoguang Wang +Date: Thu, 6 Aug 2020 14:23:01 +0800 +Subject: [PATCH] Add percpu io sq thread support + +Add a new IORING_SETUP_SQPOLL_PERCPU flag, this flag is only meaningful +when IORING_SETUP_SQPOLL and IORING_SETUP_SQ_AFF are both specified, that +means if user creates multiple io_uring instances which are all bound +to one same cpu, only a kernel thread is created for this cpu to perform +these io_uring instances' submission queue polling. + +Signed-off-by: Xiaoguang Wang +Acked-by: Joseph Qi +--- + man/io_uring_setup.2 | 9 +++++++++ + src/include/liburing/io_uring.h | 2 ++ + 2 files changed, 11 insertions(+) + +diff --git a/man/io_uring_setup.2 b/man/io_uring_setup.2 +index d48bb32..3788084 100644 +--- a/man/io_uring_setup.2 ++++ b/man/io_uring_setup.2 +@@ -131,6 +131,15 @@ This flag is only meaningful when + .B IORING_SETUP_SQPOLL + is specified. + .TP ++.B IORING_SETUP_SQPOLL_PERCPU ++This flag is only meaningful when ++.B IORING_SETUP_SQPOLL ++and ++.B IORING_SETUP_SQ_AFF ++are both specified, that means if user creates multiple io_uring instances ++which are all bound to one same cpu, only a kernel thread is created for this ++cpu to perform these io_uring instances' submission queue polling. ++.TP + .B IORING_SETUP_CQSIZE + Create the completion queue with + .IR "struct io_uring_params.cq_entries" +diff --git a/src/include/liburing/io_uring.h b/src/include/liburing/io_uring.h +index 7843742..dbc3e4d 100644 +--- a/src/include/liburing/io_uring.h ++++ b/src/include/liburing/io_uring.h +@@ -94,6 +94,8 @@ enum { + #define IORING_SETUP_CQSIZE (1U << 3) /* app defines CQ size */ + #define IORING_SETUP_CLAMP (1U << 4) /* clamp SQ/CQ ring sizes */ + #define IORING_SETUP_ATTACH_WQ (1U << 5) /* attach to existing wq */ ++/* use percpu SQ poll thread */ ++#define IORING_SETUP_SQPOLL_PERCPU (1U << 31) + + enum { + IORING_OP_NOP, +-- +2.17.2 + diff --git a/1002-liburing-anolis-Revert-Make-the-liburing-header-files-again-compatib.patch b/1002-liburing-anolis-Revert-Make-the-liburing-header-files-again-compatib.patch new file mode 100644 index 0000000000000000000000000000000000000000..a997e858a1688f4f3efff39ff8a67feff3be1c39 --- /dev/null +++ b/1002-liburing-anolis-Revert-Make-the-liburing-header-files-again-compatib.patch @@ -0,0 +1,127 @@ +From d88bcf0e719c380d645d014984ec7e363163faa0 Mon Sep 17 00:00:00 2001 +From: Hao Xu +Date: Thu, 12 Nov 2020 19:22:12 +0800 +Subject: [PATCH 1/3] Revert "Make the liburing header files again compatible + with C++" + +This reverts commit 3d74c677c45eccf36b92f7ad4b3317adc1ed06bb. +--- + src/include/liburing.h | 8 ++++---- + src/include/liburing/barrier.h | 37 ++----------------------------------- + src/include/liburing/io_uring.h | 8 -------- + 3 files changed, 6 insertions(+), 47 deletions(-) + +diff --git a/src/include/liburing.h b/src/include/liburing.h +index 0505a4f50367..92e5018951d4 100644 +--- a/src/include/liburing.h ++++ b/src/include/liburing.h +@@ -2,6 +2,10 @@ + #ifndef LIB_URING_H + #define LIB_URING_H + ++#ifdef __cplusplus ++extern "C" { ++#endif ++ + #include + #include + #include +@@ -15,10 +19,6 @@ + #include "liburing/io_uring.h" + #include "liburing/barrier.h" + +-#ifdef __cplusplus +-extern "C" { +-#endif +- + /* + * Library interface to io_uring + */ +diff --git a/src/include/liburing/barrier.h b/src/include/liburing/barrier.h +index a4a59fb499d6..57324348466b 100644 +--- a/src/include/liburing/barrier.h ++++ b/src/include/liburing/barrier.h +@@ -2,6 +2,8 @@ + #ifndef LIBURING_BARRIER_H + #define LIBURING_BARRIER_H + ++#include ++ + /* + From the kernel documentation file refcount-vs-atomic.rst: + +@@ -21,40 +23,6 @@ after the acquire operation executes. This is implemented using + :c:func:`smp_acquire__after_ctrl_dep`. + */ + +-#ifdef __cplusplus +-#include +- +-template +-static inline void IO_URING_WRITE_ONCE(T &var, T val) +-{ +- std::atomic_store_explicit(reinterpret_cast *>(&var), +- val, std::memory_order_relaxed); +-} +-template +-static inline T IO_URING_READ_ONCE(const T &var) +-{ +- return std::atomic_load_explicit( +- reinterpret_cast *>(&var), +- std::memory_order_relaxed); +-} +- +-template +-static inline void io_uring_smp_store_release(T *p, T v) +-{ +- std::atomic_store_explicit(reinterpret_cast *>(p), v, +- std::memory_order_release); +-} +- +-template +-static inline T io_uring_smp_load_acquire(const T *p) +-{ +- return std::atomic_load_explicit( +- reinterpret_cast *>(p), +- std::memory_order_acquire); +-} +-#else +-#include +- + #define IO_URING_WRITE_ONCE(var, val) \ + atomic_store_explicit((_Atomic typeof(var) *)&(var), \ + (val), memory_order_relaxed) +@@ -68,6 +36,5 @@ static inline T io_uring_smp_load_acquire(const T *p) + #define io_uring_smp_load_acquire(p) \ + atomic_load_explicit((_Atomic typeof(*(p)) *)(p), \ + memory_order_acquire) +-#endif + + #endif /* defined(LIBURING_BARRIER_H) */ +diff --git a/src/include/liburing/io_uring.h b/src/include/liburing/io_uring.h +index d39b45fddb22..d65fde732518 100644 +--- a/src/include/liburing/io_uring.h ++++ b/src/include/liburing/io_uring.h +@@ -11,10 +11,6 @@ + #include + #include + +-#ifdef __cplusplus +-extern "C" { +-#endif +- + /* + * IO submission data structure (Submission Queue Entry) + */ +@@ -294,8 +290,4 @@ struct io_uring_probe { + struct io_uring_probe_op ops[0]; + }; + +-#ifdef __cplusplus +-} +-#endif +- + #endif +-- +1.8.3.1 + diff --git a/1003-liburing-anolis-Revert-src-include-liburing-barrier.h-Restore-clang-.patch b/1003-liburing-anolis-Revert-src-include-liburing-barrier.h-Restore-clang-.patch new file mode 100644 index 0000000000000000000000000000000000000000..52053ac61ec62f649d9055c10d021b4d08b9a7cd --- /dev/null +++ b/1003-liburing-anolis-Revert-src-include-liburing-barrier.h-Restore-clang-.patch @@ -0,0 +1,40 @@ +From 0b51d4b2046f6c16179fbaff6c56c90c4985a0cb Mon Sep 17 00:00:00 2001 +From: Hao Xu +Date: Thu, 12 Nov 2020 19:25:50 +0800 +Subject: [PATCH 2/3] Revert "src/include/liburing/barrier.h: Restore clang + compatibility" + +This reverts commit 56ff6c964c5078d76cb3c2da1a62ad671749fd42. +--- + src/include/liburing/barrier.h | 12 ++++-------- + 1 file changed, 4 insertions(+), 8 deletions(-) + +diff --git a/src/include/liburing/barrier.h b/src/include/liburing/barrier.h +index 57324348466b..c8aa4210371c 100644 +--- a/src/include/liburing/barrier.h ++++ b/src/include/liburing/barrier.h +@@ -24,17 +24,13 @@ after the acquire operation executes. This is implemented using + */ + + #define IO_URING_WRITE_ONCE(var, val) \ +- atomic_store_explicit((_Atomic typeof(var) *)&(var), \ +- (val), memory_order_relaxed) ++ atomic_store_explicit(&(var), (val), memory_order_relaxed) + #define IO_URING_READ_ONCE(var) \ +- atomic_load_explicit((_Atomic typeof(var) *)&(var), \ +- memory_order_relaxed) ++ atomic_load_explicit(&(var), memory_order_relaxed) + + #define io_uring_smp_store_release(p, v) \ +- atomic_store_explicit((_Atomic typeof(*(p)) *)(p), (v), \ +- memory_order_release) ++ atomic_store_explicit((p), (v), memory_order_release) + #define io_uring_smp_load_acquire(p) \ +- atomic_load_explicit((_Atomic typeof(*(p)) *)(p), \ +- memory_order_acquire) ++ atomic_load_explicit((p), memory_order_acquire) + + #endif /* defined(LIBURING_BARRIER_H) */ +-- +1.8.3.1 + diff --git a/1004-liburing-anolis-Revert-src-include-liburing-barrier.h-Use-C11-atomic.patch b/1004-liburing-anolis-Revert-src-include-liburing-barrier.h-Use-C11-atomic.patch new file mode 100644 index 0000000000000000000000000000000000000000..cb41bed2c5a50fb8b3e5707967f933c562383560 --- /dev/null +++ b/1004-liburing-anolis-Revert-src-include-liburing-barrier.h-Use-C11-atomic.patch @@ -0,0 +1,75 @@ +From 1fc7bb3aecf344847d13d0c3c25e1b98d1687219 Mon Sep 17 00:00:00 2001 +From: Hao Xu +Date: Thu, 12 Nov 2020 19:26:04 +0800 +Subject: [PATCH 3/3] Revert "src/include/liburing/barrier.h: Use C11 atomics" + +This reverts commit b9c0bf79aa879727f55f4fe7333dd41bebd0acd4. +--- + src/include/liburing/barrier.h | 44 ++++++++++++++++++++++++++++++++---------- + 1 file changed, 34 insertions(+), 10 deletions(-) + +diff --git a/src/include/liburing/barrier.h b/src/include/liburing/barrier.h +index c8aa4210371c..ad69506bb248 100644 +--- a/src/include/liburing/barrier.h ++++ b/src/include/liburing/barrier.h +@@ -2,8 +2,6 @@ + #ifndef LIBURING_BARRIER_H + #define LIBURING_BARRIER_H + +-#include +- + /* + From the kernel documentation file refcount-vs-atomic.rst: + +@@ -23,14 +21,40 @@ after the acquire operation executes. This is implemented using + :c:func:`smp_acquire__after_ctrl_dep`. + */ + +-#define IO_URING_WRITE_ONCE(var, val) \ +- atomic_store_explicit(&(var), (val), memory_order_relaxed) +-#define IO_URING_READ_ONCE(var) \ +- atomic_load_explicit(&(var), memory_order_relaxed) ++/* From tools/include/linux/compiler.h */ ++/* Optimization barrier */ ++/* The "volatile" is due to gcc bugs */ ++#define io_uring_barrier() __asm__ __volatile__("": : :"memory") ++ ++/* From tools/virtio/linux/compiler.h */ ++#define IO_URING_WRITE_ONCE(var, val) \ ++ (*((volatile __typeof(val) *)(&(var))) = (val)) ++#define IO_URING_READ_ONCE(var) (*((volatile __typeof(var) *)(&(var)))) ++ + +-#define io_uring_smp_store_release(p, v) \ +- atomic_store_explicit((p), (v), memory_order_release) +-#define io_uring_smp_load_acquire(p) \ +- atomic_load_explicit((p), memory_order_acquire) ++#if defined(__x86_64__) || defined(__i386__) ++/* Adapted from arch/x86/include/asm/barrier.h */ ++#define io_uring_smp_store_release(p, v) \ ++do { \ ++ io_uring_barrier(); \ ++ IO_URING_WRITE_ONCE(*(p), (v)); \ ++} while (0) ++ ++#define io_uring_smp_load_acquire(p) \ ++({ \ ++ __typeof(*p) ___p1 = IO_URING_READ_ONCE(*(p)); \ ++ io_uring_barrier(); \ ++ ___p1; \ ++}) ++ ++#else /* defined(__x86_64__) || defined(__i386__) */ ++/* ++ * Add arch appropriate definitions. Use built-in atomic operations for ++ * archs we don't have support for. ++ */ ++#define io_uring_smp_store_release(p, v) \ ++ __atomic_store_n(p, v, __ATOMIC_RELEASE) ++#define io_uring_smp_load_acquire(p) __atomic_load_n(p, __ATOMIC_ACQUIRE) ++#endif /* defined(__x86_64__) || defined(__i386__) */ + + #endif /* defined(LIBURING_BARRIER_H) */ +-- +1.8.3.1 + diff --git a/1005-liburing-anolis-sq_ring_needs_enter-revert-change-to-only-enter-if-s.patch b/1005-liburing-anolis-sq_ring_needs_enter-revert-change-to-only-enter-if-s.patch new file mode 100644 index 0000000000000000000000000000000000000000..e0d64f34fd1ae2c7f6dade75b46c52912cf1deb9 --- /dev/null +++ b/1005-liburing-anolis-sq_ring_needs_enter-revert-change-to-only-enter-if-s.patch @@ -0,0 +1,55 @@ +From 07b476fc25e29dda33b83e540d054bd95b82bb1e Mon Sep 17 00:00:00 2001 +From: Jens Axboe +Date: Thu, 20 Aug 2020 21:40:16 -0600 +Subject: [PATCH 1/8] sq_ring_needs_enter: revert change to only enter if + submit != 0 + +This reverts commit f0c5c54945ae92a00cdbb43bdf3abaeab6bd3a23. + +Glauber reports a regressions for his polled setup with this change. +As it's purely speculative, just revert it. + +Reported-by: Glauber Costa +Signed-off-by: Jens Axboe +--- + src/queue.c | 9 ++++----- + 1 file changed, 4 insertions(+), 5 deletions(-) + +diff --git a/src/queue.c b/src/queue.c +index be80d7a2c760..bdb473c1ba19 100644 +--- a/src/queue.c ++++ b/src/queue.c +@@ -19,10 +19,9 @@ + * or if IORING_SQ_NEED_WAKEUP is set, so submit thread must be explicitly + * awakened. For the latter case, we set the thread wakeup flag. + */ +-static inline bool sq_ring_needs_enter(struct io_uring *ring, +- unsigned submitted, unsigned *flags) ++static inline bool sq_ring_needs_enter(struct io_uring *ring, unsigned *flags) + { +- if (!(ring->flags & IORING_SETUP_SQPOLL) && submitted) ++ if (!(ring->flags & IORING_SETUP_SQPOLL)) + return true; + if (IO_URING_READ_ONCE(*ring->sq.kflags) & IORING_SQ_NEED_WAKEUP) { + *flags |= IORING_ENTER_SQ_WAKEUP; +@@ -90,7 +89,7 @@ int __io_uring_get_cqe(struct io_uring *ring, struct io_uring_cqe **cqe_ptr, + if (wait_nr || cq_overflow_flush) + flags = IORING_ENTER_GETEVENTS; + if (submit) +- sq_ring_needs_enter(ring, submit, &flags); ++ sq_ring_needs_enter(ring, &flags); + if (wait_nr || submit || cq_overflow_flush) + ret = __sys_io_uring_enter(ring->ring_fd, submit, + wait_nr, flags, sigmask); +@@ -256,7 +255,7 @@ static int __io_uring_submit(struct io_uring *ring, unsigned submitted, + int ret; + + flags = 0; +- if (sq_ring_needs_enter(ring, submitted, &flags) || wait_nr) { ++ if (sq_ring_needs_enter(ring, &flags) || wait_nr) { + if (wait_nr || (ring->flags & IORING_SETUP_IOPOLL)) + flags |= IORING_ENTER_GETEVENTS; + +-- +1.8.3.1 + diff --git a/1006-liburing-anolis-io_uring.h-update-with-5.11-pending-copy.patch b/1006-liburing-anolis-io_uring.h-update-with-5.11-pending-copy.patch new file mode 100644 index 0000000000000000000000000000000000000000..418f34266901346d1ba398dae68b50f96b781fb7 --- /dev/null +++ b/1006-liburing-anolis-io_uring.h-update-with-5.11-pending-copy.patch @@ -0,0 +1,51 @@ +From a3680c5479fb84ebc224f4626c361ec1293c1f31 Mon Sep 17 00:00:00 2001 +From: Jens Axboe +Date: Wed, 4 Nov 2020 11:25:55 -0700 +Subject: [PATCH 2/8] io_uring.h: update with 5.11-pending copy + +Backport Notes + +manully backport struct io_uring_getevents_arg since the patch +0002-Revert-Make-the-liburing-header-files-again-compatib.patch +stoped the auto backporting + +Signed-off-by: Jens Axboe +--- + src/include/liburing/io_uring.h | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/src/include/liburing/io_uring.h b/src/include/liburing/io_uring.h +index c55878e0a200..7f7701c86eb4 100644 +--- a/src/include/liburing/io_uring.h ++++ b/src/include/liburing/io_uring.h +@@ -226,6 +226,7 @@ struct io_cqring_offsets { + */ + #define IORING_ENTER_GETEVENTS (1U << 0) + #define IORING_ENTER_SQ_WAKEUP (1U << 1) ++#define IORING_ENTER_GETEVENTS_TIMEOUT (1U << 3) + + /* + * Passed in for io_uring_setup(2). Copied back with updated info on success +@@ -253,6 +254,7 @@ struct io_uring_params { + #define IORING_FEAT_CUR_PERSONALITY (1U << 4) + #define IORING_FEAT_FAST_POLL (1U << 5) + #define IORING_FEAT_POLL_32BITS (1U << 6) ++#define IORING_FEAT_GETEVENTS_TIMEOUT (1U << 8) + + /* + * io_uring_register(2) opcodes and arguments +@@ -292,4 +294,11 @@ struct io_uring_probe { + struct io_uring_probe_op ops[0]; + }; + ++struct io_uring_getevents_arg { ++ __u64 sigmask; ++ __u32 sigmask_sz; ++ __u32 pad; ++ __u64 ts; ++}; ++ + #endif +-- +1.8.3.1 + diff --git a/1007-liburing-anolis-Include-features-in-struct-io_uring.patch b/1007-liburing-anolis-Include-features-in-struct-io_uring.patch new file mode 100644 index 0000000000000000000000000000000000000000..b59f078ce2a4e17c6d135d4ae27374a5e015f8cf --- /dev/null +++ b/1007-liburing-anolis-Include-features-in-struct-io_uring.patch @@ -0,0 +1,58 @@ +From fc063be2896b15e8083d25f932758c34ef7b9540 Mon Sep 17 00:00:00 2001 +From: Jens Axboe +Date: Wed, 4 Nov 2020 11:35:41 -0700 +Subject: [PATCH 3/8] Include 'features' in struct io_uring + +Then we'll have it for later, should we need to know what features the +ring has. This grabs one of the reserved unsigneds from the struct. + +Backport Notes + +pad[4] in struct io_uring {} is introduced in +25bbcbef3e0a ("Bump major version to 2"), backporting it causes a chain +reaction of backporting __io_uring_sqring_wait(). So here we manully +add pad[3] + +Signed-off-by: Jens Axboe +--- + src/include/liburing.h | 3 +++ + src/setup.c | 7 +++++-- + 2 files changed, 8 insertions(+), 2 deletions(-) + +diff --git a/src/include/liburing.h b/src/include/liburing.h +index 92e5018951d4..ac2d4a1cbeba 100644 +--- a/src/include/liburing.h ++++ b/src/include/liburing.h +@@ -57,6 +57,9 @@ struct io_uring { + struct io_uring_cq cq; + unsigned flags; + int ring_fd; ++ ++ unsigned features; ++ unsigned pad[3]; + }; + + /* +diff --git a/src/setup.c b/src/setup.c +index 2b17b949cda6..260dd2be8e85 100644 +--- a/src/setup.c ++++ b/src/setup.c +@@ -142,10 +142,13 @@ int io_uring_queue_init_params(unsigned entries, struct io_uring *ring, + return -errno; + + ret = io_uring_queue_mmap(fd, p, ring); +- if (ret) ++ if (ret) { + close(fd); ++ return ret; ++ } + +- return ret; ++ ring->features = p->features; ++ return 0; + } + + /* +-- +1.8.3.1 + diff --git a/1008-liburing-anolis-Add-__sys_io_uring_enter2.patch b/1008-liburing-anolis-Add-__sys_io_uring_enter2.patch new file mode 100644 index 0000000000000000000000000000000000000000..15bfae26895c5f75aeca891d999e8bd0fd0b2fa8 --- /dev/null +++ b/1008-liburing-anolis-Add-__sys_io_uring_enter2.patch @@ -0,0 +1,53 @@ +From b1e4e2dfaa657de06a401d418e370b2b42e6ba3f Mon Sep 17 00:00:00 2001 +From: Jens Axboe +Date: Wed, 4 Nov 2020 11:55:25 -0700 +Subject: [PATCH 4/8] Add __sys_io_uring_enter2() + +Just like __sys_io_uring_enter(), except it allows passing in the size +of the last argument. + +Signed-off-by: Jens Axboe +--- + src/syscall.c | 11 +++++++++-- + src/syscall.h | 2 ++ + 2 files changed, 11 insertions(+), 2 deletions(-) + +diff --git a/src/syscall.c b/src/syscall.c +index c41e0998d0dd..9b455a911df8 100644 +--- a/src/syscall.c ++++ b/src/syscall.c +@@ -47,9 +47,16 @@ int __sys_io_uring_setup(unsigned entries, struct io_uring_params *p) + return syscall(__NR_io_uring_setup, entries, p); + } + ++int __sys_io_uring_enter2(int fd, unsigned to_submit, unsigned min_complete, ++ unsigned flags, sigset_t *sig, int sz) ++{ ++ return syscall(__NR_io_uring_enter, fd, to_submit, min_complete, ++ flags, sig, sz); ++} ++ + int __sys_io_uring_enter(int fd, unsigned to_submit, unsigned min_complete, + unsigned flags, sigset_t *sig) + { +- return syscall(__NR_io_uring_enter, fd, to_submit, min_complete, +- flags, sig, _NSIG / 8); ++ return __sys_io_uring_enter2(fd, to_submit, min_complete, flags, sig, ++ _NSIG / 8); + } +diff --git a/src/syscall.h b/src/syscall.h +index 7e299d419e3e..a4c8e9bbb3f7 100644 +--- a/src/syscall.h ++++ b/src/syscall.h +@@ -8,6 +8,8 @@ + extern int __sys_io_uring_setup(unsigned entries, struct io_uring_params *p); + extern int __sys_io_uring_enter(int fd, unsigned to_submit, + unsigned min_complete, unsigned flags, sigset_t *sig); ++extern int __sys_io_uring_enter2(int fd, unsigned to_submit, ++ unsigned min_complete, unsigned flags, sigset_t *sig, int sz); + extern int __sys_io_uring_register(int fd, unsigned int opcode, const void *arg, + unsigned int nr_args); + +-- +1.8.3.1 + diff --git a/1009-liburing-anolis-Add-wrapper-for-__io_uring_get_cqe.patch b/1009-liburing-anolis-Add-wrapper-for-__io_uring_get_cqe.patch new file mode 100644 index 0000000000000000000000000000000000000000..a0b6ab4950e99922399d91614c0320cffdd24715 --- /dev/null +++ b/1009-liburing-anolis-Add-wrapper-for-__io_uring_get_cqe.patch @@ -0,0 +1,117 @@ +From 12d141534e1747525656087b357440cc68a43fda Mon Sep 17 00:00:00 2001 +From: Jens Axboe +Date: Wed, 4 Nov 2020 11:44:48 -0700 +Subject: [PATCH 5/8] Add wrapper for __io_uring_get_cqe() + +In preparation for allowing passing in a timeout. + +Signed-off-by: Jens Axboe +--- + src/queue.c | 58 ++++++++++++++++++++++++++++++++++++++++++---------------- + 1 file changed, 42 insertions(+), 16 deletions(-) + +diff --git a/src/queue.c b/src/queue.c +index bdb473c1ba19..3f3099be8a6d 100644 +--- a/src/queue.c ++++ b/src/queue.c +@@ -63,11 +63,19 @@ static int __io_uring_peek_cqe(struct io_uring *ring, + return err; + } + +-int __io_uring_get_cqe(struct io_uring *ring, struct io_uring_cqe **cqe_ptr, +- unsigned submit, unsigned wait_nr, sigset_t *sigmask) ++struct get_data { ++ unsigned submit; ++ unsigned wait_nr; ++ unsigned get_flags; ++ int sz; ++ void *arg; ++}; ++ ++static int _io_uring_get_cqe(struct io_uring *ring, struct io_uring_cqe **cqe_ptr, ++ struct get_data *data) + { + struct io_uring_cqe *cqe = NULL; +- const int to_wait = wait_nr; ++ const int to_wait = data->wait_nr; + int ret = 0, err; + + do { +@@ -77,26 +85,30 @@ int __io_uring_get_cqe(struct io_uring *ring, struct io_uring_cqe **cqe_ptr, + err = __io_uring_peek_cqe(ring, &cqe); + if (err) + break; +- if (!cqe && !to_wait && !submit) { ++ ++ if (!cqe && !to_wait && !data->submit) { + if (!cq_ring_needs_flush(ring)) { + err = -EAGAIN; + break; + } + cq_overflow_flush = true; + } +- if (wait_nr && cqe) +- wait_nr--; +- if (wait_nr || cq_overflow_flush) +- flags = IORING_ENTER_GETEVENTS; +- if (submit) ++ ++ if (data->wait_nr && cqe) ++ data->wait_nr--; ++ if (data->wait_nr || cq_overflow_flush) ++ flags = IORING_ENTER_GETEVENTS | data->get_flags; ++ if (data->submit) + sq_ring_needs_enter(ring, &flags); +- if (wait_nr || submit || cq_overflow_flush) +- ret = __sys_io_uring_enter(ring->ring_fd, submit, +- wait_nr, flags, sigmask); ++ if (data->wait_nr || data->submit || cq_overflow_flush) ++ ret = __sys_io_uring_enter2(ring->ring_fd, data->submit, ++ data->wait_nr, flags, data->arg, ++ data->sz); ++ + if (ret < 0) { + err = -errno; +- } else if (ret == (int)submit) { +- submit = 0; ++ } else if (ret == (int)data->submit) { ++ data->submit = 0; + /* + * When SETUP_IOPOLL is set, __sys_io_uring enter() + * must be called to reap new completions but the call +@@ -104,9 +116,9 @@ int __io_uring_get_cqe(struct io_uring *ring, struct io_uring_cqe **cqe_ptr, + * so preserve wait_nr. + */ + if (!(ring->flags & IORING_SETUP_IOPOLL)) +- wait_nr = 0; ++ data->wait_nr = 0; + } else { +- submit -= ret; ++ data->submit -= ret; + } + if (cqe) + break; +@@ -116,6 +128,20 @@ int __io_uring_get_cqe(struct io_uring *ring, struct io_uring_cqe **cqe_ptr, + return err; + } + ++int __io_uring_get_cqe(struct io_uring *ring, struct io_uring_cqe **cqe_ptr, ++ unsigned submit, unsigned wait_nr, sigset_t *sigmask) ++{ ++ struct get_data data = { ++ .submit = submit, ++ .wait_nr = wait_nr, ++ .extra_flags = 0, ++ .sz = _NSIG / 8, ++ .arg = sigmask, ++ }; ++ ++ return _io_uring_get_cqe(ring, cqe_ptr, &data); ++} ++ + /* + * Fill in an array of IO completions up to count, if any are available. + * Returns the amount of IO completions filled. +-- +1.8.3.1 + diff --git a/1010-liburing-anolis-Use-IORING_ENTER_GETEVENTS_TIMEOUT-if-available.patch b/1010-liburing-anolis-Use-IORING_ENTER_GETEVENTS_TIMEOUT-if-available.patch new file mode 100644 index 0000000000000000000000000000000000000000..c650c9b0e0df88dfd80ac533c83aabfdd94af628 --- /dev/null +++ b/1010-liburing-anolis-Use-IORING_ENTER_GETEVENTS_TIMEOUT-if-available.patch @@ -0,0 +1,64 @@ +From 91a6a81fc75c8f02b8c5b6b2b069dd3d1e96f6b9 Mon Sep 17 00:00:00 2001 +From: Jens Axboe +Date: Wed, 4 Nov 2020 12:02:28 -0700 +Subject: [PATCH 6/8] Use IORING_ENTER_GETEVENTS_TIMEOUT if available + +If the kernel has flagged support for IORING_FEAT_GETEVENTS_TIMEOUT, +then we can pass in a timespec instead of queueing an internal timeout +request. That's more efficient (and trivial), so use it if it's +available. + +Signed-off-by: Jens Axboe +--- + src/queue.c | 28 ++++++++++++++++++++++++++++ + 1 file changed, 28 insertions(+) + +diff --git a/src/queue.c b/src/queue.c +index 3f3099be8a6d..cd800fc5b6e8 100644 +--- a/src/queue.c ++++ b/src/queue.c +@@ -218,6 +218,31 @@ out: + } + + /* ++ * If we have kernel suppor for IORING_ENTER_GETEVENTS_TIMEOUT, then we can ++ * use that more efficiently than queueing an internal timeout command. ++ */ ++static int io_uring_wait_cqes_new(struct io_uring *ring, ++ struct io_uring_cqe **cqe_ptr, ++ unsigned wait_nr, struct __kernel_timespec *ts, ++ sigset_t *sigmask) ++{ ++ struct io_uring_getevents_arg arg = { ++ .sigmask = (unsigned long) sigmask, ++ .sigmask_sz = _NSIG / 8, ++ .ts = (unsigned long) ts ++ }; ++ struct get_data data = { ++ .submit = __io_uring_flush_sq(ring), ++ .wait_nr = wait_nr, ++ .extra_flags = ts ? IORING_ENTER_GETEVENTS_TIMEOUT : 0, ++ .sz = sizeof(arg), ++ .arg = &arg ++ }; ++ ++ return _io_uring_get_cqe(ring, cqe_ptr, &data); ++} ++ ++/* + * Like io_uring_wait_cqe(), except it accepts a timeout value as well. Note + * that an sqe is used internally to handle the timeout. Applications using + * this function must never set sqe->user_data to LIBURING_UDATA_TIMEOUT! +@@ -234,6 +259,9 @@ int io_uring_wait_cqes(struct io_uring *ring, struct io_uring_cqe **cqe_ptr, + { + unsigned to_submit = 0; + ++ if (ring->features & IORING_FEAT_GETEVENTS_TIMEOUT) ++ return io_uring_wait_cqes_new(ring, cqe_ptr, wait_nr, ts, sigmask); ++ + if (ts) { + struct io_uring_sqe *sqe; + int ret; +-- +1.8.3.1 + diff --git a/1011-liburing-anolis-Update-SIG_IS_DATA-to-modified-kernel-API.patch b/1011-liburing-anolis-Update-SIG_IS_DATA-to-modified-kernel-API.patch new file mode 100644 index 0000000000000000000000000000000000000000..67ecab48e8ede0cf7b1f348b705fc4ef90d38bd9 --- /dev/null +++ b/1011-liburing-anolis-Update-SIG_IS_DATA-to-modified-kernel-API.patch @@ -0,0 +1,78 @@ +From dd75ea9d5ef1eceba7b1e49b437a08c8a2753364 Mon Sep 17 00:00:00 2001 +From: Jens Axboe +Date: Wed, 4 Nov 2020 13:57:17 -0700 +Subject: [PATCH 7/8] Update SIG_IS_DATA to modified kernel API + +Still ironing out the kinks... + +Signed-off-by: Jens Axboe +--- + src/include/liburing/io_uring.h | 4 ++-- + src/queue.c | 8 ++++---- + 2 files changed, 6 insertions(+), 6 deletions(-) + +diff --git a/src/include/liburing/io_uring.h b/src/include/liburing/io_uring.h +index 7f7701c86eb4..b892dbe77d86 100644 +--- a/src/include/liburing/io_uring.h ++++ b/src/include/liburing/io_uring.h +@@ -226,7 +226,7 @@ struct io_cqring_offsets { + */ + #define IORING_ENTER_GETEVENTS (1U << 0) + #define IORING_ENTER_SQ_WAKEUP (1U << 1) +-#define IORING_ENTER_GETEVENTS_TIMEOUT (1U << 3) ++#define IORING_ENTER_SIG_IS_DATA (1U << 3) + + /* + * Passed in for io_uring_setup(2). Copied back with updated info on success +@@ -254,7 +254,7 @@ struct io_uring_params { + #define IORING_FEAT_CUR_PERSONALITY (1U << 4) + #define IORING_FEAT_FAST_POLL (1U << 5) + #define IORING_FEAT_POLL_32BITS (1U << 6) +-#define IORING_FEAT_GETEVENTS_TIMEOUT (1U << 8) ++#define IORING_FEAT_SIG_IS_DATA (1U << 8) + + /* + * io_uring_register(2) opcodes and arguments +diff --git a/src/queue.c b/src/queue.c +index cd800fc5b6e8..6df391c33c6f 100644 +--- a/src/queue.c ++++ b/src/queue.c +@@ -134,7 +134,7 @@ int __io_uring_get_cqe(struct io_uring *ring, struct io_uring_cqe **cqe_ptr, + struct get_data data = { + .submit = submit, + .wait_nr = wait_nr, +- .extra_flags = 0, ++ .get_flags = 0, + .sz = _NSIG / 8, + .arg = sigmask, + }; +@@ -218,7 +218,7 @@ out: + } + + /* +- * If we have kernel suppor for IORING_ENTER_GETEVENTS_TIMEOUT, then we can ++ * If we have kernel support for IORING_ENTERSIG_IS_DATA, then we can + * use that more efficiently than queueing an internal timeout command. + */ + static int io_uring_wait_cqes_new(struct io_uring *ring, +@@ -234,7 +234,7 @@ static int io_uring_wait_cqes_new(struct io_uring *ring, + struct get_data data = { + .submit = __io_uring_flush_sq(ring), + .wait_nr = wait_nr, +- .extra_flags = ts ? IORING_ENTER_GETEVENTS_TIMEOUT : 0, ++ .get_flags = ts ? IORING_ENTER_SIG_IS_DATA : 0, + .sz = sizeof(arg), + .arg = &arg + }; +@@ -259,7 +259,7 @@ int io_uring_wait_cqes(struct io_uring *ring, struct io_uring_cqe **cqe_ptr, + { + unsigned to_submit = 0; + +- if (ring->features & IORING_FEAT_GETEVENTS_TIMEOUT) ++ if (ring->features & IORING_FEAT_SIG_IS_DATA) + return io_uring_wait_cqes_new(ring, cqe_ptr, wait_nr, ts, sigmask); + + if (ts) { +-- +1.8.3.1 + diff --git a/1012-liburing-anolis-Rename-SIG_IS_DATA-EXT_ARG.patch b/1012-liburing-anolis-Rename-SIG_IS_DATA-EXT_ARG.patch new file mode 100644 index 0000000000000000000000000000000000000000..8f39924fc913a75cd31fcb507e6a1c74aef1f011 --- /dev/null +++ b/1012-liburing-anolis-Rename-SIG_IS_DATA-EXT_ARG.patch @@ -0,0 +1,81 @@ +From 8424cff4705e62784b8042d71e12e22554a038ac Mon Sep 17 00:00:00 2001 +From: Jens Axboe +Date: Wed, 4 Nov 2020 14:34:03 -0700 +Subject: [PATCH 8/8] Rename SIG_IS_DATA -> EXT_ARG + +This is the final name. While doing this change, also change it so that +we only call the new variant if 'ts' is indeed set. + +Signed-off-by: Jens Axboe +--- + src/include/liburing/io_uring.h | 4 ++-- + src/queue.c | 13 +++++++------ + 2 files changed, 9 insertions(+), 8 deletions(-) + +diff --git a/src/include/liburing/io_uring.h b/src/include/liburing/io_uring.h +index b892dbe77d86..e8393b87e7bd 100644 +--- a/src/include/liburing/io_uring.h ++++ b/src/include/liburing/io_uring.h +@@ -226,7 +226,7 @@ struct io_cqring_offsets { + */ + #define IORING_ENTER_GETEVENTS (1U << 0) + #define IORING_ENTER_SQ_WAKEUP (1U << 1) +-#define IORING_ENTER_SIG_IS_DATA (1U << 3) ++#define IORING_ENTER_EXT_ARG (1U << 3) + + /* + * Passed in for io_uring_setup(2). Copied back with updated info on success +@@ -254,7 +254,7 @@ struct io_uring_params { + #define IORING_FEAT_CUR_PERSONALITY (1U << 4) + #define IORING_FEAT_FAST_POLL (1U << 5) + #define IORING_FEAT_POLL_32BITS (1U << 6) +-#define IORING_FEAT_SIG_IS_DATA (1U << 8) ++#define IORING_FEAT_EXT_ARG (1U << 8) + + /* + * io_uring_register(2) opcodes and arguments +diff --git a/src/queue.c b/src/queue.c +index 6df391c33c6f..2662e671fb34 100644 +--- a/src/queue.c ++++ b/src/queue.c +@@ -218,8 +218,8 @@ out: + } + + /* +- * If we have kernel support for IORING_ENTERSIG_IS_DATA, then we can +- * use that more efficiently than queueing an internal timeout command. ++ * If we have kernel support for IORING_ENTER_EXT_ARG, then we can use that ++ * more efficiently than queueing an internal timeout command. + */ + static int io_uring_wait_cqes_new(struct io_uring *ring, + struct io_uring_cqe **cqe_ptr, +@@ -234,7 +234,7 @@ static int io_uring_wait_cqes_new(struct io_uring *ring, + struct get_data data = { + .submit = __io_uring_flush_sq(ring), + .wait_nr = wait_nr, +- .get_flags = ts ? IORING_ENTER_SIG_IS_DATA : 0, ++ .get_flags = IORING_ENTER_EXT_ARG, + .sz = sizeof(arg), + .arg = &arg + }; +@@ -259,13 +259,14 @@ int io_uring_wait_cqes(struct io_uring *ring, struct io_uring_cqe **cqe_ptr, + { + unsigned to_submit = 0; + +- if (ring->features & IORING_FEAT_SIG_IS_DATA) +- return io_uring_wait_cqes_new(ring, cqe_ptr, wait_nr, ts, sigmask); +- + if (ts) { + struct io_uring_sqe *sqe; + int ret; + ++ if (ring->features & IORING_FEAT_EXT_ARG) ++ return io_uring_wait_cqes_new(ring, cqe_ptr, wait_nr, ++ ts, sigmask); ++ + /* + * If the SQ ring is full, we may need to submit IO first + */ +-- +1.8.3.1 + diff --git a/1013-liburing-anolis-support-async-ioctl-in-liburing.patch b/1013-liburing-anolis-support-async-ioctl-in-liburing.patch new file mode 100644 index 0000000000000000000000000000000000000000..74594b561f16df461fe777f9707450367ce9fc5f --- /dev/null +++ b/1013-liburing-anolis-support-async-ioctl-in-liburing.patch @@ -0,0 +1,46 @@ +From e8dbd563b3a355b8885f2bf5ae96be83a1624432 Mon Sep 17 00:00:00 2001 +From: Hao Xu +Date: Thu, 26 Nov 2020 14:56:58 +0800 +Subject: [PATCH] support async ioctl in liburing + +Async ioctl is now supported in io_uring kernel part. Add the +counterpart in liburing. Currently we just support BLKDISCARD. + +Signed-off-by: Hao Xu +--- + src/include/liburing.h | 6 ++++++ + src/include/liburing/io_uring.h | 1 + + 2 files changed, 7 insertions(+) + +diff --git a/src/include/liburing.h b/src/include/liburing.h +index ac2d4a1cbeba..9fa5bc92986d 100644 +--- a/src/include/liburing.h ++++ b/src/include/liburing.h +@@ -438,6 +438,12 @@ static inline void io_uring_prep_remove_buffers(struct io_uring_sqe *sqe, + sqe->buf_group = bgid; + } + ++static inline void io_uring_prep_ioctl(struct io_uring_sqe *sqe, int fd, ++ unsigned len, void *buf) ++{ ++ io_uring_prep_rw(IORING_OP_IOCTL, sqe, fd, buf, len, 0); ++} ++ + static inline unsigned io_uring_sq_ready(struct io_uring *ring) + { + /* always use real head, to avoid losing sync for short submit */ +diff --git a/src/include/liburing/io_uring.h b/src/include/liburing/io_uring.h +index e8393b87e7bd..05d58cebcfcc 100644 +--- a/src/include/liburing/io_uring.h ++++ b/src/include/liburing/io_uring.h +@@ -133,6 +133,7 @@ enum { + IORING_OP_PROVIDE_BUFFERS, + IORING_OP_REMOVE_BUFFERS, + IORING_OP_TEE, ++ IORING_OP_IOCTL, + + /* this goes last, obviously */ + IORING_OP_LAST, +-- +1.8.3.1 + diff --git a/1014-liburing-anolis-test-timeout-new-test-for-timeout-feature.patch b/1014-liburing-anolis-test-timeout-new-test-for-timeout-feature.patch new file mode 100644 index 0000000000000000000000000000000000000000..0037a516fa326211bf58b5490e40cc51e92c4885 --- /dev/null +++ b/1014-liburing-anolis-test-timeout-new-test-for-timeout-feature.patch @@ -0,0 +1,307 @@ +From ce520b2655e8d14d3a94cc9f596f128eb4c36140 Mon Sep 17 00:00:00 2001 +From: Hao Xu +Date: Sat, 12 Dec 2020 12:49:39 +0800 +Subject: [PATCH] test/timeout-new: test for timeout feature + +Tests for the new timeout feature. It covers: + - wake up when timeout, sleeping time calculated as well + - wake up by a cqe before timeout + - the above two in sqpoll thread mode + - multi child-threads wake up by a cqe issuing in main thread before + timeout + +Signed-off-by: Hao Xu +Signed-off-by: Jens Axboe +--- + test/Makefile | 7 +- + test/timeout-new.c | 246 +++++++++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 251 insertions(+), 2 deletions(-) + create mode 100644 test/timeout-new.c + +diff --git a/test/Makefile b/test/Makefile +index cbbd400391dd..0720dcd39950 100644 +--- a/test/Makefile ++++ b/test/Makefile +@@ -25,7 +25,8 @@ all_targets += poll poll-cancel ring-leak fsync io_uring_setup io_uring_register + short-read openat2 probe shared-wq personality eventfd \ + send_recv eventfd-ring across-fork sq-poll-kthread splice \ + lfs-openat lfs-openat-write iopoll d4ae271dfaae-test \ +- eventfd-disable close-opath ce593a6c480a-test cq-overflow-peek ++ eventfd-disable close-opath ce593a6c480a-test cq-overflow-peek \ ++ timeout-new + + include ../Makefile.quiet + +@@ -65,7 +66,8 @@ test_srcs := poll.c poll-cancel.c ring-leak.c fsync.c io_uring_setup.c \ + madvise.c short-read.c openat2.c probe.c shared-wq.c \ + personality.c eventfd.c eventfd-ring.c across-fork.c sq-poll-kthread.c \ + splice.c lfs-openat.c lfs-openat-write.c iopoll.c d4ae271dfaae-test.c \ +- eventfd-disable.c close-opath.c ce593a6c480a-test.c cq-overflow-peek.c ++ eventfd-disable.c close-opath.c ce593a6c480a-test.c cq-overflow-peek.c \ ++ timeout-new.c + + ifdef CONFIG_HAVE_STATX + test_srcs += statx.c +@@ -87,6 +89,7 @@ submit-reuse: XCFLAGS = -lpthread + poll-v-poll: XCFLAGS = -lpthread + across-fork: XCFLAGS = -lpthread + ce593a6c480a-test: XCFLAGS = -lpthread ++timeout-new: XCFLAGS = -lpthread + + install: $(all_targets) runtests.sh runtests-loop.sh + $(INSTALL) -D -d -m 755 $(datadir)/liburing-test/ +diff --git a/test/timeout-new.c b/test/timeout-new.c +new file mode 100644 +index 000000000000..45b9a149ae11 +--- /dev/null ++++ b/test/timeout-new.c +@@ -0,0 +1,246 @@ ++/* SPDX-License-Identifier: MIT */ ++/* ++ * Description: tests for getevents timeout ++ * ++ */ ++#include ++#include ++#include ++#include ++#include "liburing.h" ++ ++#define TIMEOUT_MSEC 200 ++#define TIMEOUT_SEC 10 ++ ++int thread_ret0, thread_ret1; ++int cnt = 0; ++pthread_mutex_t mutex; ++ ++static void msec_to_ts(struct __kernel_timespec *ts, unsigned int msec) ++{ ++ ts->tv_sec = msec / 1000; ++ ts->tv_nsec = (msec % 1000) * 1000000; ++} ++ ++static unsigned long long mtime_since(const struct timeval *s, ++ const struct timeval *e) ++{ ++ long long sec, usec; ++ ++ sec = e->tv_sec - s->tv_sec; ++ usec = (e->tv_usec - s->tv_usec); ++ if (sec > 0 && usec < 0) { ++ sec--; ++ usec += 1000000; ++ } ++ ++ sec *= 1000; ++ usec /= 1000; ++ return sec + usec; ++} ++ ++static unsigned long long mtime_since_now(struct timeval *tv) ++{ ++ struct timeval end; ++ ++ gettimeofday(&end, NULL); ++ return mtime_since(tv, &end); ++} ++ ++ ++static int test_return_before_timeout(struct io_uring *ring) ++{ ++ struct io_uring_cqe *cqe; ++ struct io_uring_sqe *sqe; ++ int ret; ++ struct __kernel_timespec ts; ++ ++ sqe = io_uring_get_sqe(ring); ++ if (!sqe) { ++ fprintf(stderr, "%s: get sqe failed\n", __FUNCTION__); ++ return 1; ++ } ++ ++ io_uring_prep_nop(sqe); ++ ++ ret = io_uring_submit(ring); ++ if (ret <= 0) { ++ fprintf(stderr, "%s: sqe submit failed: %d\n", __FUNCTION__, ret); ++ return 1; ++ } ++ ++ msec_to_ts(&ts, TIMEOUT_MSEC); ++ ret = io_uring_wait_cqe_timeout(ring, &cqe, &ts); ++ if (ret < 0) { ++ fprintf(stderr, "%s: timeout error: %d\n", __FUNCTION__, ret); ++ return 1; ++ } ++ ++ io_uring_cqe_seen(ring, cqe); ++ return 0; ++} ++ ++static int test_return_after_timeout(struct io_uring *ring) ++{ ++ struct io_uring_cqe *cqe; ++ int ret; ++ struct __kernel_timespec ts; ++ struct timeval tv; ++ unsigned long long exp; ++ ++ msec_to_ts(&ts, TIMEOUT_MSEC); ++ gettimeofday(&tv, NULL); ++ ret = io_uring_wait_cqe_timeout(ring, &cqe, &ts); ++ exp = mtime_since_now(&tv); ++ if (ret != -ETIME) { ++ fprintf(stderr, "%s: timeout error: %d\n", __FUNCTION__, ret); ++ return 1; ++ } ++ ++ if (exp < TIMEOUT_MSEC / 2 || exp > (TIMEOUT_MSEC * 3) / 2) { ++ fprintf(stderr, "%s: Timeout seems wonky (got %llu)\n", __FUNCTION__, exp); ++ return 1; ++ } ++ ++ return 0; ++} ++ ++int __reap_thread_fn(void *data) { ++ struct io_uring *ring = (struct io_uring *)data; ++ struct io_uring_cqe *cqe; ++ struct __kernel_timespec ts; ++ ++ msec_to_ts(&ts, TIMEOUT_SEC); ++ pthread_mutex_lock(&mutex); ++ cnt++; ++ pthread_mutex_unlock(&mutex); ++ return io_uring_wait_cqe_timeout(ring, &cqe, &ts); ++} ++ ++void *reap_thread_fn0(void *data) { ++ thread_ret0 = __reap_thread_fn(data); ++ return NULL; ++} ++ ++void *reap_thread_fn1(void *data) { ++ thread_ret1 = __reap_thread_fn(data); ++ return NULL; ++} ++ ++/* ++ * This is to test issuing a sqe in main thread and reaping it in two child-thread ++ * at the same time. To see if timeout feature works or not. ++ */ ++int test_multi_threads_timeout() { ++ struct io_uring ring; ++ int ret; ++ bool both_wait = false; ++ pthread_t reap_thread0, reap_thread1; ++ struct io_uring_sqe *sqe; ++ ++ ret = io_uring_queue_init(8, &ring, 0); ++ if (ret) { ++ fprintf(stderr, "%s: ring setup failed: %d\n", __FUNCTION__, ret); ++ return 1; ++ } ++ ++ pthread_create(&reap_thread0, NULL, reap_thread_fn0, &ring); ++ pthread_create(&reap_thread1, NULL, reap_thread_fn1, &ring); ++ ++ /* ++ * make two threads both enter io_uring_wait_cqe_timeout() before issuing the sqe ++ * as possible as we can. So that there are two threads in the ctx->wait queue. ++ * In this way, we can test if a cqe wakes up two threads at the same time. ++ */ ++ while(!both_wait) { ++ pthread_mutex_lock(&mutex); ++ if (cnt == 2) ++ both_wait = true; ++ pthread_mutex_unlock(&mutex); ++ sleep(1); ++ } ++ ++ sqe = io_uring_get_sqe(&ring); ++ if (!sqe) { ++ fprintf(stderr, "%s: get sqe failed\n", __FUNCTION__); ++ goto err; ++ } ++ ++ io_uring_prep_nop(sqe); ++ ++ ret = io_uring_submit(&ring); ++ if (ret <= 0) { ++ fprintf(stderr, "%s: sqe submit failed: %d\n", __FUNCTION__, ret); ++ goto err; ++ } ++ ++ pthread_join(reap_thread0, NULL); ++ pthread_join(reap_thread1, NULL); ++ ++ if ((thread_ret0 && thread_ret0 != -ETIME) || (thread_ret1 && thread_ret1 != -ETIME)) { ++ fprintf(stderr, "%s: thread wait cqe timeout failed: %d %d\n", ++ __FUNCTION__, thread_ret0, thread_ret1); ++ goto err; ++ } ++ ++ return 0; ++err: ++ return 1; ++} ++ ++int main(int argc, char *argv[]) ++{ ++ struct io_uring ring_normal, ring_sq; ++ int ret; ++ ++ if (argc > 1) ++ return 0; ++ ++ ret = io_uring_queue_init(8, &ring_normal, 0); ++ if (ret) { ++ fprintf(stderr, "ring_normal setup failed: %d\n", ret); ++ return 1; ++ } ++ if (!(ring_normal.features & IORING_FEAT_EXT_ARG)) { ++ fprintf(stderr, "feature IORING_FEAT_EXT_ARG not supported.\n"); ++ return 1; ++ } ++ ++ ret = test_return_before_timeout(&ring_normal); ++ if (ret) { ++ fprintf(stderr, "ring_normal: test_return_before_timeout failed\n"); ++ return ret; ++ } ++ ++ ret = test_return_after_timeout(&ring_normal); ++ if (ret) { ++ fprintf(stderr, "ring_normal: test_return_after_timeout failed\n"); ++ return ret; ++ } ++ ++ ret = io_uring_queue_init(8, &ring_sq, IORING_SETUP_SQPOLL); ++ if (ret) { ++ fprintf(stderr, "ring_sq setup failed: %d\n", ret); ++ return 1; ++ } ++ ++ ret = test_return_before_timeout(&ring_sq); ++ if (ret) { ++ fprintf(stderr, "ring_sq: test_return_before_timeout failed\n"); ++ return ret; ++ } ++ ++ ret = test_return_after_timeout(&ring_sq); ++ if (ret) { ++ fprintf(stderr, "ring_sq: test_return_after_timeout failed\n"); ++ return ret; ++ } ++ ++ ret = test_multi_threads_timeout(); ++ if (ret) { ++ fprintf(stderr, "test_multi_threads_timeout failed\n"); ++ return ret; ++ } ++ ++ return 0; ++} +-- +1.8.3.1 + diff --git a/1015-liburing-anolis-test-use-a-map-to-define-test-files-devices-we-need.patch b/1015-liburing-anolis-test-use-a-map-to-define-test-files-devices-we-need.patch new file mode 100644 index 0000000000000000000000000000000000000000..7bb1e7fdd72b7d6a2b4cfb744c0fae0bef7703cb --- /dev/null +++ b/1015-liburing-anolis-test-use-a-map-to-define-test-files-devices-we-need.patch @@ -0,0 +1,68 @@ +From c2f5708119a8249feda4e5e283c1e17dc90d4773 Mon Sep 17 00:00:00 2001 +From: Hao Xu +Date: Thu, 25 Feb 2021 16:39:02 +0800 +Subject: [PATCH] test: use a map to define test files / devices we need + +Different tests need different files / devices, use a map to indicate +what each test need. + +Signed-off-by: Hao Xu +Signed-off-by: Jens Axboe +--- + test/config | 2 +- + test/runtests.sh | 13 ++++++------- + 2 files changed, 7 insertions(+), 8 deletions(-) + +diff --git a/test/config b/test/config +index 80a5f467c0c4..d1ea7858ee7a 100644 +--- a/test/config ++++ b/test/config +@@ -1,4 +1,4 @@ + # Define raw test devices (or files) for test cases, if any + # Copy this to config.local, and uncomment + define test files + # +-# TEST_FILES="/dev/nvme0n1p2 /data/file" ++declare -A TEST_FILES=() +diff --git a/test/runtests.sh b/test/runtests.sh +index a891f4b91acd..171470bbd5a7 100755 +--- a/test/runtests.sh ++++ b/test/runtests.sh +@@ -6,6 +6,7 @@ RET=0 + TIMEOUT=60 + FAILED="" + MAYBE_FAILED="" ++declare -A TEST_FILES + + do_kmsg="1" + if ! [ $(id -u) = 0 ]; then +@@ -13,10 +14,9 @@ if ! [ $(id -u) = 0 ]; then + fi + + TEST_DIR=$(dirname $0) +-TEST_FILES="" + if [ -f "$TEST_DIR/config.local" ]; then + . $TEST_DIR/config.local +- for dev in $TEST_FILES; do ++ for dev in ${TEST_FILES[@]}; do + if [ ! -e "$dev" ]; then + echo "Test file $dev not valid" + exit 1 +@@ -102,11 +102,10 @@ run_test() + } + + for t in $TESTS; do +- run_test $t +- if [ ! -z "$TEST_FILES" ]; then +- for dev in $TEST_FILES; do +- run_test $t $dev +- done ++ if [ ! -n "${TEST_FILES[$t]}" ]; then ++ run_test $t ++ else ++ run_test $t ${TEST_FILES[$t]} + fi + done + +-- +1.8.3.1 + diff --git a/1016-liburing-anolis-test-add-ioctl-test.patch b/1016-liburing-anolis-test-add-ioctl-test.patch new file mode 100644 index 0000000000000000000000000000000000000000..3b35acea5d5a01c4b090513fb56100331adc53b4 --- /dev/null +++ b/1016-liburing-anolis-test-add-ioctl-test.patch @@ -0,0 +1,223 @@ +From c838127df8046c4b2ab83a8b75125f91ff4d03c2 Mon Sep 17 00:00:00 2001 +From: Hao Xu +Date: Thu, 25 Feb 2021 17:26:59 +0800 +Subject: [PATCH] test: add ioctl test + +add a test for ioctl, make sure there is a device for this test in the +TEST_FILES in conifg.local. +eg. declare -A TEST_FILES=(["ioctl"]="/dev/nvme0n1") + +Signed-off-by: Hao Xu +--- + test/Makefile | 4 +- + test/ioctl.c | 176 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 178 insertions(+), 2 deletions(-) + create mode 100644 test/ioctl.c + +diff --git a/test/Makefile b/test/Makefile +index 0720dcd39950..9e911e6a596a 100644 +--- a/test/Makefile ++++ b/test/Makefile +@@ -26,7 +26,7 @@ all_targets += poll poll-cancel ring-leak fsync io_uring_setup io_uring_register + send_recv eventfd-ring across-fork sq-poll-kthread splice \ + lfs-openat lfs-openat-write iopoll d4ae271dfaae-test \ + eventfd-disable close-opath ce593a6c480a-test cq-overflow-peek \ +- timeout-new ++ timeout-new ioctl + + include ../Makefile.quiet + +@@ -67,7 +67,7 @@ test_srcs := poll.c poll-cancel.c ring-leak.c fsync.c io_uring_setup.c \ + personality.c eventfd.c eventfd-ring.c across-fork.c sq-poll-kthread.c \ + splice.c lfs-openat.c lfs-openat-write.c iopoll.c d4ae271dfaae-test.c \ + eventfd-disable.c close-opath.c ce593a6c480a-test.c cq-overflow-peek.c \ +- timeout-new.c ++ timeout-new.c ioctl.c + + ifdef CONFIG_HAVE_STATX + test_srcs += statx.c +diff --git a/test/ioctl.c b/test/ioctl.c +new file mode 100644 +index 000000000000..33077fb5ffc7 +--- /dev/null ++++ b/test/ioctl.c +@@ -0,0 +1,176 @@ ++/* SPDX-License-Identifier: MIT */ ++/* ++ * Description: test io_uring ioctl ++ * ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "liburing.h" ++ ++#ifndef BLKDISCARD ++#define BLKDISCARD _IO(0x12,119) ++#endif ++ ++typedef unsigned long long ull; ++char *dev_path; ++ ++static int init_params(int cmd, int *fd, int *len, void **buf) ++{ ++ *len = cmd; ++ switch (cmd) { ++ case BLKDISCARD: ++ *fd = open(dev_path, O_RDWR); ++ ull *range = (ull *)malloc(sizeof(ull) * 2); ++ range[0] = 0; ++ range[1] = 1024; ++ *buf = range; ++ break; ++ default: ++ return -1; ++ } ++ ++ return 0; ++} ++ ++int ioctl_clean(int cmd, int fd, void *buf) ++{ ++ int ret; ++ if (fd > 0) { ++ ret = close(fd); ++ if (ret) ++ return ret; ++ } ++ ++ switch (cmd) { ++ case BLKDISCARD: ++ if (buf) ++ free(buf); ++ break; ++ } ++ ++ return 0; ++} ++static int ioctl_extra_check(int cmd, void *buf) ++{ ++ switch (cmd) { ++ case BLKDISCARD: ++ break; ++ } ++ return 0; ++} ++ ++static int test_ioctl(struct io_uring *ring, int cmd) ++{ ++ struct io_uring_cqe *cqe; ++ struct io_uring_sqe *sqe; ++ int fd = 0, len, ret, ret2; ++ void *buf = NULL; ++ ++ ret = init_params(cmd, &fd, &len, &buf); ++ if (ret == -1) { ++ perror("invalid command"); ++ goto err; ++ } ++ if (fd < 0) { ++ perror("open"); ++ goto err; ++ } ++ ++ sqe = io_uring_get_sqe(ring); ++ if (!sqe) { ++ fprintf(stderr, "get sqe failed\n"); ++ goto err; ++ } ++ io_uring_prep_ioctl(sqe, fd, len, buf); ++ ++ ret = io_uring_submit(ring); ++ if (ret <= 0) { ++ fprintf(stderr, "sqe submit failed: %d\n", ret); ++ goto err; ++ } ++ ++ ret = io_uring_wait_cqe(ring, &cqe); ++ if (ret < 0) { ++ fprintf(stderr, "wait completion %d\n", ret); ++ goto err; ++ } ++ ++ ret = 1; ++ switch (cqe->res) { ++ /* ++ * Two cases return -EINVAL: ++ * - sys_ioctl() itself returns it ++ * - IORING_OP_IOCTL isn't supported in io_uring ++ * ++ * To distinguish them, one solution is to return other stuff other ++ * than -EINVAL when sys_ioctl() logic returns -EINVAL. But this ++ * change the logic of the original sys_ioctl() syscall. ++ * Leave it as it is for now. ++ */ ++ case -EINVAL: ++ fprintf(stderr, "cqe->res is -EINVAL\n"); ++ break; ++ case -EFAULT: ++ fprintf(stderr, "cqe->res is -EFAULT\n"); ++ break; ++ case -EBADF: ++ fprintf(stderr, "cqe->res is -EBADF\n"); ++ break; ++ case -ENOTTY: ++ fprintf(stderr, "cqe->res is -ENOTTY\n"); ++ break; ++ default: ++ if (cqe->res) { ++ fprintf(stderr, "cqe->res is %d\n", cqe->res); ++ } else if (ioctl_extra_check(cmd, buf)) { ++ fprintf(stderr, "ioctl cmd:%d failed\n", cmd); ++ } else { ++ ret = 0; ++ } ++ } ++ ++ io_uring_cqe_seen(ring, cqe); ++err: ++ ret2 = ioctl_clean(cmd, fd, buf); ++ /* ++ * it's not a test error, just print warning, still return 0 ++ */ ++ if (ret2) ++ fprintf(stderr, "close test file failure\n"); ++ ++ return ret; ++} ++ ++int main(int argc, char *argv[]) ++{ ++ struct io_uring ring; ++ int ret; ++ ++ if (argc < 2) { ++ fprintf(stderr, "no ssd device indicated, skip.\n"); ++ return 0; ++ } ++ ++ dev_path = argv[1]; ++ ++ ret = io_uring_queue_init(8, &ring, 0); ++ if (ret) { ++ fprintf(stderr, "ring setup failed\n"); ++ return 1; ++ } ++ ++ ret = test_ioctl(&ring, BLKDISCARD); ++ if (ret) { ++ fprintf(stderr, "test_ioctl BLKDISCARD failed\n"); ++ return ret; ++ } ++ ++ return 0; ++} ++ +-- +1.8.3.1 + diff --git a/1017-liburing-anolis-test-timeout-overflow-don-t-run-on-newer-kernels.patch b/1017-liburing-anolis-test-timeout-overflow-don-t-run-on-newer-kernels.patch new file mode 100644 index 0000000000000000000000000000000000000000..fea817849486ff6aa6feb10328ec0cfe3ddbffa6 --- /dev/null +++ b/1017-liburing-anolis-test-timeout-overflow-don-t-run-on-newer-kernels.patch @@ -0,0 +1,70 @@ +From 4fe73ec45c51096459971727089a0f0b1f86f926 Mon Sep 17 00:00:00 2001 +From: Jens Axboe +Date: Thu, 13 Aug 2020 18:00:06 -0600 +Subject: [PATCH] test/timeout-overflow: don't run on newer kernels + +It's known to fail with the batched completions, just disable it +on newer kernels. + +Signed-off-by: Jens Axboe +Signed-off-by: Joseph Qi +--- + test/timeout-overflow.c | 17 ++++++++++++++--- + 1 file changed, 14 insertions(+), 3 deletions(-) + +diff --git a/test/timeout-overflow.c b/test/timeout-overflow.c +index 1074e2b..f952f80 100644 +--- a/test/timeout-overflow.c ++++ b/test/timeout-overflow.c +@@ -6,6 +6,7 @@ + #include + #include + #include ++#include + #include + + #include "liburing.h" +@@ -19,19 +20,29 @@ static void msec_to_ts(struct __kernel_timespec *ts, unsigned int msec) + ts->tv_nsec = (msec % 1000) * 1000000; + } + +-static int check_timeout_support() ++static int check_timeout_support(void) + { + struct io_uring_sqe *sqe; + struct io_uring_cqe *cqe; + struct __kernel_timespec ts; ++ struct io_uring_params p; + struct io_uring ring; + int ret; + +- ret = io_uring_queue_init(8, &ring, 0); ++ memset(&p, 0, sizeof(p)); ++ ret = io_uring_queue_init_params(1, &ring, &p); + if (ret) { + fprintf(stderr, "ring setup failed: %d\n", ret); + return 1; + } ++ ++ /* not really a match, but same kernel added batched completions */ ++ if (p.features & IORING_FEAT_POLL_32BITS) { ++ fprintf(stdout, "Skipping\n"); ++ not_supported = 1; ++ return 0; ++ } ++ + sqe = io_uring_get_sqe(&ring); + msec_to_ts(&ts, TIMEOUT_MSEC); + io_uring_prep_timeout(sqe, &ts, 1, 0); +@@ -74,7 +85,7 @@ err: + * successful after the patch. And req1/req2 will completed successful with + * req3/req4 return -ETIME without this patch! + */ +-static int test_timeout_overflow() ++static int test_timeout_overflow(void) + { + struct io_uring_sqe *sqe; + struct io_uring_cqe *cqe; +-- +1.8.3.1 + diff --git a/1018-liburing-anolis-support-us-granularity-of-io_sq_thread_idle.patch b/1018-liburing-anolis-support-us-granularity-of-io_sq_thread_idle.patch new file mode 100644 index 0000000000000000000000000000000000000000..b55d0cc2eb840657308b57bdcc5f5abdfb19f2d6 --- /dev/null +++ b/1018-liburing-anolis-support-us-granularity-of-io_sq_thread_idle.patch @@ -0,0 +1,56 @@ +From 65ac402fb0feb4ee74d71317f04c1b4422d78665 Mon Sep 17 00:00:00 2001 +From: Hao Xu +Date: Mon, 10 May 2021 11:34:29 +0800 +Subject: [PATCH] support us granularity of io_sq_thread_idle + +add flag IORING_SETUP_IDLE_US to support microsecond granularity +io_sq_thread_idle. + +Signed-off-by: Hao Xu +--- + man/io_uring_setup.2 | 9 ++++++++- + src/include/liburing/io_uring.h | 1 + + 2 files changed, 9 insertions(+), 1 deletion(-) + +diff --git a/man/io_uring_setup.2 b/man/io_uring_setup.2 +index 8c71e200d8b7..a2a9072423de 100644 +--- a/man/io_uring_setup.2 ++++ b/man/io_uring_setup.2 +@@ -80,7 +80,9 @@ doing a single system call. + + If the kernel thread is idle for more than + .I sq_thread_idle +-milliseconds, it will set the ++milliseconds/microseconds(depends on if ++.B IORING_SETUP_IDLE_US ++is set), it will set the + .B IORING_SQ_NEED_WAKEUP + bit in the + .I flags +@@ -146,6 +148,11 @@ Create the completion queue with + entries. The value must be greater than + .IR entries , + and may be rounded up to the next power-of-two. ++.TP ++.B IORING_SETUP_IDLE_US ++If this flag is set, the unit of ++.I sq_thread_idle ++is microsecond, rather than millisecond. + .PP + If no flags are specified, the io_uring instance is setup for + interrupt driven I/O. I/O may be submitted using +diff --git a/src/include/liburing/io_uring.h b/src/include/liburing/io_uring.h +index 05d58cebcfcc..8b412fb21567 100644 +--- a/src/include/liburing/io_uring.h ++++ b/src/include/liburing/io_uring.h +@@ -95,6 +95,7 @@ enum { + #define IORING_SETUP_CQSIZE (1U << 3) /* app defines CQ size */ + #define IORING_SETUP_CLAMP (1U << 4) /* clamp SQ/CQ ring sizes */ + #define IORING_SETUP_ATTACH_WQ (1U << 5) /* attach to existing wq */ ++#define IORING_SETUP_IDLE_US (1U << 30) /* unit of thread_idle is microsecond */ + /* use percpu SQ poll thread */ + #define IORING_SETUP_SQPOLL_PERCPU (1U << 31) + +-- +1.8.3.1 + diff --git a/1019-liburing-anolis-add-IORING_ENTER_SQ_SUBMIT_ON_IDLE-flag.patch b/1019-liburing-anolis-add-IORING_ENTER_SQ_SUBMIT_ON_IDLE-flag.patch new file mode 100644 index 0000000000000000000000000000000000000000..d0853d520efa115f378088b6e7bec9bf2fd0a461 --- /dev/null +++ b/1019-liburing-anolis-add-IORING_ENTER_SQ_SUBMIT_ON_IDLE-flag.patch @@ -0,0 +1,137 @@ +From edc1b76b8d8a81b26e9a8399f91f73b066b112bf Mon Sep 17 00:00:00 2001 +From: Hao Xu +Date: Mon, 10 May 2021 14:39:02 +0800 +Subject: [PATCH] add IORING_ENTER_SQ_SUBMIT_ON_IDLE flag + +add this flag to allow the original task to submit some sqes to reduce +sqthread wakeup latency. + +Signed-off-by: Hao Xu +--- + debian/liburing1.symbols | 6 ++++++ + src/include/liburing.h | 2 ++ + src/include/liburing/io_uring.h | 1 + + src/liburing.map | 3 +++ + src/queue.c | 29 ++++++++++++++++++++++------- + 5 files changed, 34 insertions(+), 7 deletions(-) + +diff --git a/debian/liburing1.symbols b/debian/liburing1.symbols +index cc4d504895d3..dccce71d0e11 100644 +--- a/debian/liburing1.symbols ++++ b/debian/liburing1.symbols +@@ -26,3 +26,9 @@ liburing.so.1 liburing1 #MINVER# + io_uring_register_probe@LIBURING_0.4 0.4-1 + io_uring_ring_dontfork@LIBURING_0.4 0.4-1 + io_uring_unregister_personality@LIBURING_0.4 0.4-1 ++ (symver)LIBURING_0.5 0.5-1 ++ (symver)LIBURING_0.6 0.6-1 ++ (symver)LIBURING_0.7 0.7-8 ++ io_uring_submit_on_idle@LIBURING_0.7 0.7-8 ++ io_uring_submit_on_idle_and_wait@LIBURING_0.7 0.7-8 ++ +diff --git a/src/include/liburing.h b/src/include/liburing.h +index 9fa5bc92986d..8a1dc7c6591f 100644 +--- a/src/include/liburing.h ++++ b/src/include/liburing.h +@@ -97,7 +97,9 @@ extern int io_uring_wait_cqes(struct io_uring *ring, + extern int io_uring_wait_cqe_timeout(struct io_uring *ring, + struct io_uring_cqe **cqe_ptr, struct __kernel_timespec *ts); + extern int io_uring_submit(struct io_uring *ring); ++extern int io_uring_submit_on_idle(struct io_uring *ring); + extern int io_uring_submit_and_wait(struct io_uring *ring, unsigned wait_nr); ++extern int io_uring_submit_on_idle_and_wait(struct io_uring *ring, unsigned wait_nr); + extern struct io_uring_sqe *io_uring_get_sqe(struct io_uring *ring); + + extern int io_uring_register_buffers(struct io_uring *ring, +diff --git a/src/include/liburing/io_uring.h b/src/include/liburing/io_uring.h +index 8b412fb21567..cd1c68a753b9 100644 +--- a/src/include/liburing/io_uring.h ++++ b/src/include/liburing/io_uring.h +@@ -229,6 +229,7 @@ struct io_cqring_offsets { + #define IORING_ENTER_GETEVENTS (1U << 0) + #define IORING_ENTER_SQ_WAKEUP (1U << 1) + #define IORING_ENTER_EXT_ARG (1U << 3) ++#define IORING_ENTER_SQ_SUBMIT_ON_IDLE (1U << 4) + + /* + * Passed in for io_uring_setup(2). Copied back with updated info on success +diff --git a/src/liburing.map b/src/liburing.map +index 38bd558a5a50..8c2ccfaca8c2 100644 +--- a/src/liburing.map ++++ b/src/liburing.map +@@ -56,4 +56,7 @@ LIBURING_0.6 { + } LIBURING_0.5; + + LIBURING_0.7 { ++ global: ++ io_uring_submit_on_idle; ++ io_uring_submit_on_idle_and_wait; + } LIBURING_0.6; +diff --git a/src/queue.c b/src/queue.c +index 2662e671fb34..d8ee64f25601 100644 +--- a/src/queue.c ++++ b/src/queue.c +@@ -304,12 +304,12 @@ int io_uring_wait_cqe_timeout(struct io_uring *ring, + * Returns number of sqes submitted + */ + static int __io_uring_submit(struct io_uring *ring, unsigned submitted, +- unsigned wait_nr) ++ unsigned wait_nr, unsigned enter_flags) + { +- unsigned flags; ++ unsigned flags = 0; + int ret; + +- flags = 0; ++ flags |= enter_flags; + if (sq_ring_needs_enter(ring, &flags) || wait_nr) { + if (wait_nr || (ring->flags & IORING_SETUP_IOPOLL)) + flags |= IORING_ENTER_GETEVENTS; +@@ -324,9 +324,10 @@ static int __io_uring_submit(struct io_uring *ring, unsigned submitted, + return ret; + } + +-static int __io_uring_submit_and_wait(struct io_uring *ring, unsigned wait_nr) ++static int __io_uring_submit_and_wait(struct io_uring *ring, unsigned wait_nr, unsigned enter_flags) + { +- return __io_uring_submit(ring, __io_uring_flush_sq(ring), wait_nr); ++ return __io_uring_submit(ring, __io_uring_flush_sq(ring), wait_nr, ++ enter_flags); + } + + /* +@@ -336,7 +337,16 @@ static int __io_uring_submit_and_wait(struct io_uring *ring, unsigned wait_nr) + */ + int io_uring_submit(struct io_uring *ring) + { +- return __io_uring_submit_and_wait(ring, 0); ++ return __io_uring_submit_and_wait(ring, 0, 0); ++} ++ ++/* ++ * Similar to io_uring_submit(), but with flag IORING_ENTER_SUBMIT_ON_IDLE ++ * to allow submitting sqes in original context when waking up sqthread. ++ */ ++int io_uring_submit_on_idle(struct io_uring *ring) ++{ ++ return __io_uring_submit_and_wait(ring, 0, IORING_ENTER_SQ_SUBMIT_ON_IDLE); + } + + /* +@@ -346,7 +356,12 @@ int io_uring_submit(struct io_uring *ring) + */ + int io_uring_submit_and_wait(struct io_uring *ring, unsigned wait_nr) + { +- return __io_uring_submit_and_wait(ring, wait_nr); ++ return __io_uring_submit_and_wait(ring, wait_nr, 0); ++} ++ ++int io_uring_submit_on_idle_and_wait(struct io_uring *ring, unsigned wait_nr) ++{ ++ return __io_uring_submit_and_wait(ring, wait_nr, IORING_ENTER_SQ_SUBMIT_ON_IDLE); + } + + static inline struct io_uring_sqe * +-- +1.8.3.1 + diff --git a/liburing.spec b/liburing.spec index 6a8f79cefa3e6cb72a1510a77dc373da586f804c..cf65dd877b5920d8c8c62ff342707670429328c0 100644 --- a/liburing.spec +++ b/liburing.spec @@ -1,12 +1,35 @@ +%define anolis_release .0.1 + Name: liburing Version: 1.0.7 -Release: 3%{?dist} +Release: 3%{anolis_release}%{?dist} Summary: Linux-native io_uring I/O access library License: LGPLv2+ Source: %{name}-%{version}.tar.bz2 URL: http://brick.kernel.dk/snaps/%{name}-%{version}.tar.bz2 BuildRequires: gcc Patch0: liburing-always-build-with-fPIC.patch +# Begin: Anolis customized patches +Patch1001: 1001-liburing-anolis-Add-percpu-io-sq-thread-support.patch +Patch1002: 1002-liburing-anolis-Revert-Make-the-liburing-header-files-again-compatib.patch +Patch1003: 1003-liburing-anolis-Revert-src-include-liburing-barrier.h-Restore-clang-.patch +Patch1004: 1004-liburing-anolis-Revert-src-include-liburing-barrier.h-Use-C11-atomic.patch +Patch1005: 1005-liburing-anolis-sq_ring_needs_enter-revert-change-to-only-enter-if-s.patch +Patch1006: 1006-liburing-anolis-io_uring.h-update-with-5.11-pending-copy.patch +Patch1007: 1007-liburing-anolis-Include-features-in-struct-io_uring.patch +Patch1008: 1008-liburing-anolis-Add-__sys_io_uring_enter2.patch +Patch1009: 1009-liburing-anolis-Add-wrapper-for-__io_uring_get_cqe.patch +Patch1010: 1010-liburing-anolis-Use-IORING_ENTER_GETEVENTS_TIMEOUT-if-available.patch +Patch1011: 1011-liburing-anolis-Update-SIG_IS_DATA-to-modified-kernel-API.patch +Patch1012: 1012-liburing-anolis-Rename-SIG_IS_DATA-EXT_ARG.patch +Patch1013: 1013-liburing-anolis-support-async-ioctl-in-liburing.patch +Patch1014: 1014-liburing-anolis-test-timeout-new-test-for-timeout-feature.patch +Patch1015: 1015-liburing-anolis-test-use-a-map-to-define-test-files-devices-we-need.patch +Patch1016: 1016-liburing-anolis-test-add-ioctl-test.patch +Patch1017: 1017-liburing-anolis-test-timeout-overflow-don-t-run-on-newer-kernels.patch +Patch1018: 1018-liburing-anolis-support-us-granularity-of-io_sq_thread_idle.patch +Patch1019: 1019-liburing-anolis-add-IORING_ENTER_SQ_SUBMIT_ON_IDLE-flag.patch +# End: Anolis customized patches %description Provides native async IO for the Linux kernel, in a fast and efficient @@ -45,6 +68,9 @@ for the Linux-native io_uring. %{_mandir}/man2/* %changelog +* Mon Nov 29 2021 Hao Xu - 1.0.7-3.0.1 +- add anolis customized patches to support features in Anolis OS Kernel + * Thu Aug 20 2020 Jeff Moyer - 1.0.7-3.el8 - Build with V=1 so that the build logs are useful. - Related: rhbz#1862551