uringmachine 0.24.0 → 0.26.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.gitmodules +0 -3
- data/CHANGELOG.md +13 -0
- data/Gemfile +11 -0
- data/README.md +266 -112
- data/Rakefile +8 -0
- data/TODO.md +14 -21
- data/benchmark/common.rb +2 -0
- data/benchmark/openssl.rb +77 -0
- data/benchmark/openssl_socketpair.rb +112 -0
- data/benchmark/sqlite.rb +1 -1
- data/docs/design/buffer_pool.md +1 -1
- data/docs/wroclove.rb.md +52 -0
- data/ext/um/extconf.rb +15 -0
- data/ext/um/um.c +392 -358
- data/ext/um/um.h +48 -23
- data/ext/um/um_async_op.c +9 -8
- data/ext/um/um_async_op_class.c +34 -3
- data/ext/um/um_class.c +705 -19
- data/ext/um/um_const.c +31 -0
- data/ext/um/um_mutex_class.c +12 -0
- data/ext/um/um_op.c +15 -1
- data/ext/um/um_queue_class.c +16 -0
- data/ext/um/um_ssl.c +109 -0
- data/ext/um/um_stream.c +9 -8
- data/ext/um/um_sync.c +18 -11
- data/ext/um/um_utils.c +17 -8
- data/grant-2025/interim-report.md +1 -1
- data/grant-2025/journal.md +4 -4
- data/grant-2025/tasks.md +6 -4
- data/lib/uringmachine/dns_resolver.rb +38 -0
- data/lib/uringmachine/fiber_scheduler.rb +7 -5
- data/lib/uringmachine/version.rb +1 -1
- data/lib/uringmachine.rb +106 -6
- data/test/helper.rb +15 -0
- data/test/test_async_op.rb +3 -2
- data/test/test_fiber_scheduler.rb +41 -1
- data/test/test_ssl.rb +85 -0
- data/test/test_stream.rb +11 -0
- data/test/test_um.rb +445 -11
- data/uringmachine.gemspec +1 -7
- data/vendor/liburing/examples/send-zerocopy.c +43 -31
- data/vendor/liburing/examples/zcrx.c +260 -69
- data/vendor/liburing/liburing.spec +1 -1
- data/vendor/liburing/src/include/liburing/io_uring.h +12 -0
- data/vendor/liburing/src/include/liburing.h +3 -2
- data/vendor/liburing/src/liburing-ffi.map +4 -0
- data/vendor/liburing/src/liburing.map +4 -0
- data/vendor/liburing/src/queue.c +12 -0
- data/vendor/liburing/src/register.c +1 -0
- data/vendor/liburing/src/setup.c +15 -7
- data/vendor/liburing/test/Makefile +8 -4
- data/vendor/liburing/test/conn-unreach.c +1 -1
- data/vendor/liburing/test/epwait.c +32 -6
- data/vendor/liburing/test/io-wq-exit.c +131 -0
- data/vendor/liburing/test/iowait.c +1 -1
- data/vendor/liburing/test/min-timeout.c +3 -1
- data/vendor/liburing/test/open-close.c +39 -0
- data/vendor/liburing/test/poll-update-trigger.c +85 -0
- data/vendor/liburing/test/recvsend_bundle.c +14 -11
- data/vendor/liburing/test/sendzc-bug.c +146 -0
- data/vendor/liburing/test/sqe-mixed-nop.c +151 -7
- data/vendor/liburing/test/test.h +2 -0
- data/vendor/liburing/test/timestamp-bug.c +135 -0
- data/vendor/liburing/test/timestamp.c +5 -0
- data/vendor/liburing/test/vec-regbuf.c +136 -1
- metadata +38 -283
- data/vendor/libressl/.github/scripts/changelog.sh +0 -74
- data/vendor/libressl/.github/workflows/android.yml +0 -35
- data/vendor/libressl/.github/workflows/cifuzz.yml +0 -33
- data/vendor/libressl/.github/workflows/cmake-config.yml +0 -98
- data/vendor/libressl/.github/workflows/coverity.yml +0 -69
- data/vendor/libressl/.github/workflows/emscripten.yml +0 -71
- data/vendor/libressl/.github/workflows/fedora-rawhide.yml +0 -39
- data/vendor/libressl/.github/workflows/freebsd.yml +0 -71
- data/vendor/libressl/.github/workflows/linux.yml +0 -71
- data/vendor/libressl/.github/workflows/macos.yml +0 -37
- data/vendor/libressl/.github/workflows/release.yml +0 -81
- data/vendor/libressl/.github/workflows/rust-openssl.yml +0 -47
- data/vendor/libressl/.github/workflows/solaris.yml +0 -37
- data/vendor/libressl/.github/workflows/windows.yml +0 -70
- data/vendor/libressl/.gitignore +0 -333
- data/vendor/libressl/CMakeLists.txt +0 -581
- data/vendor/libressl/COPYING +0 -133
- data/vendor/libressl/ChangeLog +0 -3280
- data/vendor/libressl/FindLibreSSL.cmake +0 -232
- data/vendor/libressl/LibreSSLConfig.cmake.in +0 -36
- data/vendor/libressl/Makefile.am +0 -60
- data/vendor/libressl/Makefile.am.common +0 -20
- data/vendor/libressl/OPENBSD_BRANCH +0 -1
- data/vendor/libressl/README.md +0 -238
- data/vendor/libressl/README.mingw.md +0 -43
- data/vendor/libressl/apps/CMakeLists.txt +0 -18
- data/vendor/libressl/apps/Makefile.am +0 -5
- data/vendor/libressl/apps/nc/CMakeLists.txt +0 -67
- data/vendor/libressl/apps/nc/Makefile.am +0 -64
- data/vendor/libressl/apps/nc/compat/accept4.c +0 -17
- data/vendor/libressl/apps/nc/compat/readpassphrase.c +0 -205
- data/vendor/libressl/apps/nc/compat/socket.c +0 -29
- data/vendor/libressl/apps/nc/compat/sys/socket.h +0 -30
- data/vendor/libressl/apps/ocspcheck/CMakeLists.txt +0 -44
- data/vendor/libressl/apps/ocspcheck/Makefile.am +0 -45
- data/vendor/libressl/apps/ocspcheck/compat/.gitignore +0 -0
- data/vendor/libressl/apps/openssl/CMakeLists.txt +0 -97
- data/vendor/libressl/apps/openssl/Makefile.am +0 -108
- data/vendor/libressl/apps/openssl/apps_win.c +0 -138
- data/vendor/libressl/apps/openssl/certhash_win.c +0 -13
- data/vendor/libressl/apps/openssl/compat/clock_gettime_osx.c +0 -26
- data/vendor/libressl/apps/openssl/compat/poll_win.c +0 -329
- data/vendor/libressl/appveyor.yml +0 -53
- data/vendor/libressl/autogen.sh +0 -15
- data/vendor/libressl/check-release.sh +0 -86
- data/vendor/libressl/cmake_export_symbol.cmake +0 -71
- data/vendor/libressl/cmake_uninstall.cmake.in +0 -36
- data/vendor/libressl/config +0 -17
- data/vendor/libressl/configure.ac +0 -165
- data/vendor/libressl/crypto/CMakeLists.txt +0 -863
- data/vendor/libressl/crypto/Makefile.am +0 -962
- data/vendor/libressl/crypto/Makefile.am.arc4random +0 -46
- data/vendor/libressl/crypto/Makefile.am.elf-mips +0 -14
- data/vendor/libressl/crypto/Makefile.am.elf-mips64 +0 -14
- data/vendor/libressl/crypto/Makefile.am.elf-x86_64 +0 -35
- data/vendor/libressl/crypto/Makefile.am.macosx-x86_64 +0 -35
- data/vendor/libressl/crypto/Makefile.am.masm-x86_64 +0 -22
- data/vendor/libressl/crypto/Makefile.am.mingw64-x86_64 +0 -23
- data/vendor/libressl/crypto/arch/aarch64/crypto_cpu_caps_darwin.c +0 -60
- data/vendor/libressl/crypto/arch/aarch64/crypto_cpu_caps_linux.c +0 -62
- data/vendor/libressl/crypto/arch/aarch64/crypto_cpu_caps_none.c +0 -26
- data/vendor/libressl/crypto/arch/aarch64/crypto_cpu_caps_windows.c +0 -36
- data/vendor/libressl/crypto/arch/loongarch64/crypto_arch.h +0 -21
- data/vendor/libressl/crypto/arch/mips/crypto_arch.h +0 -21
- data/vendor/libressl/crypto/bn/arch/loongarch64/bn_arch.h +0 -23
- data/vendor/libressl/crypto/bn/arch/mips/bn_arch.h +0 -24
- data/vendor/libressl/crypto/compat/.gitignore +0 -31
- data/vendor/libressl/crypto/compat/arc4random.h +0 -41
- data/vendor/libressl/crypto/compat/b_win.c +0 -55
- data/vendor/libressl/crypto/compat/bsd-asprintf.c +0 -96
- data/vendor/libressl/crypto/compat/crypto_lock_win.c +0 -56
- data/vendor/libressl/crypto/compat/explicit_bzero_win.c +0 -13
- data/vendor/libressl/crypto/compat/freezero.c +0 -32
- data/vendor/libressl/crypto/compat/getdelim.c +0 -78
- data/vendor/libressl/crypto/compat/getline.c +0 -40
- data/vendor/libressl/crypto/compat/getopt_long.c +0 -528
- data/vendor/libressl/crypto/compat/getpagesize.c +0 -18
- data/vendor/libressl/crypto/compat/getprogname_linux.c +0 -23
- data/vendor/libressl/crypto/compat/getprogname_unimpl.c +0 -7
- data/vendor/libressl/crypto/compat/getprogname_windows.c +0 -13
- data/vendor/libressl/crypto/compat/posix_win.c +0 -296
- data/vendor/libressl/crypto/compat/syslog_r.c +0 -19
- data/vendor/libressl/crypto/compat/ui_openssl_win.c +0 -334
- data/vendor/libressl/dist.sh +0 -22
- data/vendor/libressl/gen-coverage-report.sh +0 -58
- data/vendor/libressl/gen-openbsd-tags.sh +0 -20
- data/vendor/libressl/include/CMakeLists.txt +0 -61
- data/vendor/libressl/include/Makefile.am +0 -79
- data/vendor/libressl/include/arch/loongarch64/opensslconf.h +0 -150
- data/vendor/libressl/include/arch/mips/opensslconf.h +0 -150
- data/vendor/libressl/include/compat/arpa/inet.h +0 -15
- data/vendor/libressl/include/compat/arpa/nameser.h +0 -25
- data/vendor/libressl/include/compat/cet.h +0 -19
- data/vendor/libressl/include/compat/dirent.h +0 -17
- data/vendor/libressl/include/compat/dirent_msvc.h +0 -611
- data/vendor/libressl/include/compat/endian.h +0 -161
- data/vendor/libressl/include/compat/err.h +0 -95
- data/vendor/libressl/include/compat/fcntl.h +0 -32
- data/vendor/libressl/include/compat/getopt.h +0 -50
- data/vendor/libressl/include/compat/limits.h +0 -25
- data/vendor/libressl/include/compat/netdb.h +0 -10
- data/vendor/libressl/include/compat/netinet/in.h +0 -19
- data/vendor/libressl/include/compat/netinet/ip.h +0 -49
- data/vendor/libressl/include/compat/netinet/tcp.h +0 -10
- data/vendor/libressl/include/compat/poll.h +0 -63
- data/vendor/libressl/include/compat/pthread.h +0 -122
- data/vendor/libressl/include/compat/readpassphrase.h +0 -44
- data/vendor/libressl/include/compat/resolv.h +0 -24
- data/vendor/libressl/include/compat/stdint.h +0 -31
- data/vendor/libressl/include/compat/stdio.h +0 -65
- data/vendor/libressl/include/compat/stdlib.h +0 -57
- data/vendor/libressl/include/compat/string.h +0 -98
- data/vendor/libressl/include/compat/sys/_null.h +0 -18
- data/vendor/libressl/include/compat/sys/ioctl.h +0 -11
- data/vendor/libressl/include/compat/sys/mman.h +0 -19
- data/vendor/libressl/include/compat/sys/param.h +0 -15
- data/vendor/libressl/include/compat/sys/queue.h +0 -536
- data/vendor/libressl/include/compat/sys/select.h +0 -10
- data/vendor/libressl/include/compat/sys/socket.h +0 -18
- data/vendor/libressl/include/compat/sys/stat.h +0 -129
- data/vendor/libressl/include/compat/sys/time.h +0 -37
- data/vendor/libressl/include/compat/sys/tree.h +0 -1006
- data/vendor/libressl/include/compat/sys/types.h +0 -69
- data/vendor/libressl/include/compat/sys/uio.h +0 -17
- data/vendor/libressl/include/compat/syslog.h +0 -38
- data/vendor/libressl/include/compat/time.h +0 -59
- data/vendor/libressl/include/compat/unistd.h +0 -83
- data/vendor/libressl/include/compat/win32netcompat.h +0 -57
- data/vendor/libressl/include/openssl/Makefile.am.tpl +0 -45
- data/vendor/libressl/libcrypto.pc.in +0 -28
- data/vendor/libressl/libressl.pub +0 -2
- data/vendor/libressl/libssl.pc.in +0 -28
- data/vendor/libressl/libtls.pc.in +0 -28
- data/vendor/libressl/m4/ax_add_fortify_source.m4 +0 -80
- data/vendor/libressl/m4/ax_check_compile_flag.m4 +0 -53
- data/vendor/libressl/m4/check-hardening-options.m4 +0 -110
- data/vendor/libressl/m4/check-libc.m4 +0 -189
- data/vendor/libressl/m4/check-os-options.m4 +0 -181
- data/vendor/libressl/m4/disable-compiler-warnings.m4 +0 -44
- data/vendor/libressl/man/CMakeLists.txt +0 -26
- data/vendor/libressl/man/links +0 -2780
- data/vendor/libressl/man/update_links.sh +0 -25
- data/vendor/libressl/openssl.pc.in +0 -11
- data/vendor/libressl/patches/bn_shift.patch +0 -34
- data/vendor/libressl/patches/crypto_arch.h.patch +0 -34
- data/vendor/libressl/patches/crypto_namespace.h.patch +0 -22
- data/vendor/libressl/patches/netcat.c.patch +0 -178
- data/vendor/libressl/patches/openssl.c.patch +0 -12
- data/vendor/libressl/patches/opensslfeatures.h.patch +0 -49
- data/vendor/libressl/patches/patch-amd64-crypto-cpu-caps.c.patch +0 -20
- data/vendor/libressl/patches/patch-i386-crypto-cpu-caps.c.patch +0 -20
- data/vendor/libressl/patches/speed.c.patch +0 -114
- data/vendor/libressl/patches/ssl_namespace.h.patch +0 -21
- data/vendor/libressl/patches/tls.h.patch +0 -16
- data/vendor/libressl/patches/tls_config.c.patch +0 -15
- data/vendor/libressl/patches/win32_amd64_bn_arch.h.patch +0 -28
- data/vendor/libressl/patches/windows_headers.patch +0 -80
- data/vendor/libressl/scripts/config.guess +0 -1774
- data/vendor/libressl/scripts/config.sub +0 -1907
- data/vendor/libressl/scripts/i686-w64-mingw32.cmake +0 -9
- data/vendor/libressl/scripts/test +0 -210
- data/vendor/libressl/scripts/wrap-compiler-for-flag-check +0 -31
- data/vendor/libressl/scripts/x86_64-w64-mingw32.cmake +0 -9
- data/vendor/libressl/ssl/CMakeLists.txt +0 -183
- data/vendor/libressl/ssl/Makefile.am +0 -187
- data/vendor/libressl/tests/CMakeLists.txt +0 -970
- data/vendor/libressl/tests/Makefile.am +0 -944
- data/vendor/libressl/tests/aeadtest.sh +0 -30
- data/vendor/libressl/tests/arc4randomforktest.sh +0 -21
- data/vendor/libressl/tests/asn1time_small.test +0 -10
- data/vendor/libressl/tests/cmake/CMakeLists.txt +0 -52
- data/vendor/libressl/tests/cmake/crypto.c +0 -7
- data/vendor/libressl/tests/cmake/ssl.c +0 -6
- data/vendor/libressl/tests/cmake/tls.c +0 -6
- data/vendor/libressl/tests/compat/pipe2.c +0 -186
- data/vendor/libressl/tests/dtlstest.sh +0 -28
- data/vendor/libressl/tests/evptest.sh +0 -22
- data/vendor/libressl/tests/keypairtest.sh +0 -27
- data/vendor/libressl/tests/mlkem_tests.sh +0 -39
- data/vendor/libressl/tests/ocsptest.bat +0 -25
- data/vendor/libressl/tests/ocsptest.sh +0 -23
- data/vendor/libressl/tests/openssl.cnf +0 -29
- data/vendor/libressl/tests/optionstest.c +0 -381
- data/vendor/libressl/tests/pidwraptest.c +0 -85
- data/vendor/libressl/tests/pidwraptest.sh +0 -26
- data/vendor/libressl/tests/quictest.bat +0 -27
- data/vendor/libressl/tests/quictest.sh +0 -30
- data/vendor/libressl/tests/renegotiation_test.bat +0 -27
- data/vendor/libressl/tests/renegotiation_test.sh +0 -30
- data/vendor/libressl/tests/rfc5280time_small.test +0 -10
- data/vendor/libressl/tests/servertest.bat +0 -27
- data/vendor/libressl/tests/servertest.sh +0 -30
- data/vendor/libressl/tests/shutdowntest.bat +0 -27
- data/vendor/libressl/tests/shutdowntest.sh +0 -30
- data/vendor/libressl/tests/ssltest.bat +0 -32
- data/vendor/libressl/tests/ssltest.sh +0 -48
- data/vendor/libressl/tests/testdsa.bat +0 -47
- data/vendor/libressl/tests/testdsa.sh +0 -57
- data/vendor/libressl/tests/testenc.bat +0 -85
- data/vendor/libressl/tests/testenc.sh +0 -93
- data/vendor/libressl/tests/testrsa.bat +0 -47
- data/vendor/libressl/tests/testrsa.sh +0 -57
- data/vendor/libressl/tests/testssl.bat +0 -171
- data/vendor/libressl/tests/tlstest.bat +0 -27
- data/vendor/libressl/tests/tlstest.sh +0 -28
- data/vendor/libressl/tls/CMakeLists.txt +0 -125
- data/vendor/libressl/tls/Makefile.am +0 -76
- data/vendor/libressl/tls/compat/ftruncate.c +0 -17
- data/vendor/libressl/tls/compat/pread.c +0 -29
- data/vendor/libressl/tls/compat/pwrite.c +0 -29
- data/vendor/libressl/update.sh +0 -460
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/* SPDX-License-Identifier: MIT */
|
|
2
|
+
/*
|
|
3
|
+
* Description: test that importing a buffer node ties the lifetime to the
|
|
4
|
+
* notification io_kiocb, not the normal request.
|
|
5
|
+
*
|
|
6
|
+
* Based on a test case from Google Big Sleep.
|
|
7
|
+
*
|
|
8
|
+
*/
|
|
9
|
+
#include <arpa/inet.h>
|
|
10
|
+
#include <err.h>
|
|
11
|
+
#include <fcntl.h>
|
|
12
|
+
#include <netinet/in.h>
|
|
13
|
+
#include <poll.h>
|
|
14
|
+
#include <pthread.h>
|
|
15
|
+
#include <stdint.h>
|
|
16
|
+
#include <stdio.h>
|
|
17
|
+
#include <stdlib.h>
|
|
18
|
+
#include <string.h>
|
|
19
|
+
#include <sys/mman.h>
|
|
20
|
+
#include <sys/socket.h>
|
|
21
|
+
#include <sys/stat.h>
|
|
22
|
+
#include <sys/syscall.h>
|
|
23
|
+
#include <sys/types.h>
|
|
24
|
+
#include <sys/wait.h>
|
|
25
|
+
#include <unistd.h>
|
|
26
|
+
|
|
27
|
+
#include "liburing.h"
|
|
28
|
+
#include "helpers.h"
|
|
29
|
+
|
|
30
|
+
#define BUF_SIZE (1024 * 1024)
|
|
31
|
+
static uint8_t read_buffer[BUF_SIZE] = { 0 };
|
|
32
|
+
|
|
33
|
+
/* Creates a pair of connected TCP sockets. */
|
|
34
|
+
static void tcp_socketpair(int sv[2])
|
|
35
|
+
{
|
|
36
|
+
struct sockaddr_in addr_in = {
|
|
37
|
+
.sin_family = AF_INET,
|
|
38
|
+
.sin_addr.s_addr = htonl(INADDR_LOOPBACK),
|
|
39
|
+
.sin_port = 0,
|
|
40
|
+
};
|
|
41
|
+
struct sockaddr *addr = (struct sockaddr *) &addr_in;
|
|
42
|
+
socklen_t addr_len = sizeof(addr_in);
|
|
43
|
+
int listener_fd;
|
|
44
|
+
|
|
45
|
+
listener_fd = socket(AF_INET, SOCK_STREAM, 0);
|
|
46
|
+
if (listener_fd < 0)
|
|
47
|
+
err(EXIT_FAILURE, "listener socket");
|
|
48
|
+
|
|
49
|
+
if (bind(listener_fd, addr, addr_len) < 0)
|
|
50
|
+
err(EXIT_FAILURE, "bind");
|
|
51
|
+
|
|
52
|
+
if (listen(listener_fd, 1) < 0)
|
|
53
|
+
err(EXIT_FAILURE, "listen");
|
|
54
|
+
|
|
55
|
+
if (getsockname(listener_fd, addr, &addr_len) < 0)
|
|
56
|
+
err(EXIT_FAILURE, "getsockname");
|
|
57
|
+
|
|
58
|
+
sv[0] = socket(AF_INET, SOCK_STREAM, 0);
|
|
59
|
+
if (sv[0] < 0)
|
|
60
|
+
err(EXIT_FAILURE, "socket(AF_INET, SOCK_STREAM, 0)");
|
|
61
|
+
|
|
62
|
+
if (connect(sv[0], addr, addr_len) < 0)
|
|
63
|
+
err(EXIT_FAILURE, "connect");
|
|
64
|
+
|
|
65
|
+
sv[1] = accept(listener_fd, NULL, NULL);
|
|
66
|
+
if (sv[1] == -1)
|
|
67
|
+
err(EXIT_FAILURE, "accept");
|
|
68
|
+
|
|
69
|
+
close(listener_fd);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
int main(int argc, char *argv[])
|
|
73
|
+
{
|
|
74
|
+
struct io_uring_sqe *sqe;
|
|
75
|
+
struct io_uring_cqe* cqe;
|
|
76
|
+
struct iovec send_iov;
|
|
77
|
+
struct io_uring ring;
|
|
78
|
+
struct iovec iov_reg;
|
|
79
|
+
struct msghdr msg = {
|
|
80
|
+
.msg_iov = &send_iov,
|
|
81
|
+
.msg_iovlen = 1,
|
|
82
|
+
};
|
|
83
|
+
void *send_buffer;
|
|
84
|
+
int sockets[2];
|
|
85
|
+
int val, ret;
|
|
86
|
+
|
|
87
|
+
if (argc > 1)
|
|
88
|
+
return T_EXIT_SKIP;
|
|
89
|
+
|
|
90
|
+
tcp_socketpair(sockets);
|
|
91
|
+
|
|
92
|
+
val = 1;
|
|
93
|
+
if (setsockopt(sockets[0], SOL_SOCKET, SO_ZEROCOPY, &val, sizeof(val)))
|
|
94
|
+
err(EXIT_FAILURE, "setsockopt(SO_ZEROCOPY)");
|
|
95
|
+
|
|
96
|
+
ret = io_uring_queue_init(1, &ring, 0);
|
|
97
|
+
if (ret < 0)
|
|
98
|
+
errx(EXIT_FAILURE, "io_uring_queue_init: %s", strerror(-ret));
|
|
99
|
+
|
|
100
|
+
/* mmap send_buffer so we can unmap it later. */
|
|
101
|
+
send_buffer = mmap(NULL, BUF_SIZE, PROT_READ | PROT_WRITE,
|
|
102
|
+
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
|
103
|
+
if (send_buffer == MAP_FAILED)
|
|
104
|
+
err(EXIT_FAILURE, "mapping iouring buffer");
|
|
105
|
+
|
|
106
|
+
iov_reg.iov_base = send_buffer;
|
|
107
|
+
iov_reg.iov_len = BUF_SIZE;
|
|
108
|
+
ret = io_uring_register_buffers(&ring, &iov_reg, 1);
|
|
109
|
+
if (ret < 0)
|
|
110
|
+
errx(EXIT_FAILURE, "io_uring_register_buffers: %s", strerror(-ret));
|
|
111
|
+
|
|
112
|
+
sqe = io_uring_get_sqe(&ring);
|
|
113
|
+
|
|
114
|
+
send_iov.iov_base = send_buffer;
|
|
115
|
+
send_iov.iov_len = BUF_SIZE;
|
|
116
|
+
|
|
117
|
+
io_uring_prep_sendmsg_zc(sqe, sockets[0], &msg, 0);
|
|
118
|
+
sqe->ioprio = IORING_RECVSEND_FIXED_BUF;
|
|
119
|
+
sqe->buf_index = 0;
|
|
120
|
+
|
|
121
|
+
memset(send_buffer, 'B', BUF_SIZE);
|
|
122
|
+
|
|
123
|
+
io_uring_submit(&ring);
|
|
124
|
+
|
|
125
|
+
ret = io_uring_wait_cqe(&ring, &cqe);
|
|
126
|
+
if (ret < 0)
|
|
127
|
+
errx(EXIT_FAILURE, "io_uring_wait_cqe: %s", strerror(-ret));
|
|
128
|
+
|
|
129
|
+
if (cqe->res < 0) {
|
|
130
|
+
if (cqe->res == -EINVAL)
|
|
131
|
+
return T_EXIT_SKIP;
|
|
132
|
+
errx(EXIT_FAILURE, "readv failed: %s", strerror(-cqe->res));
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
io_uring_cqe_seen(&ring, cqe);
|
|
136
|
+
|
|
137
|
+
io_uring_unregister_buffers(&ring);
|
|
138
|
+
munmap(send_buffer, BUF_SIZE);
|
|
139
|
+
|
|
140
|
+
ret = read(sockets[1], read_buffer, BUF_SIZE);
|
|
141
|
+
if (ret < 0)
|
|
142
|
+
err(EXIT_FAILURE, "read");
|
|
143
|
+
|
|
144
|
+
io_uring_queue_exit(&ring);
|
|
145
|
+
return T_EXIT_PASS;
|
|
146
|
+
}
|
|
@@ -9,9 +9,11 @@
|
|
|
9
9
|
#include "helpers.h"
|
|
10
10
|
#include "test.h"
|
|
11
11
|
|
|
12
|
+
#define NENTRIES 8
|
|
13
|
+
|
|
12
14
|
static int seq;
|
|
13
15
|
|
|
14
|
-
static int test_single_nop(struct io_uring *ring, bool sqe128)
|
|
16
|
+
static int test_single_nop(struct io_uring *ring, bool sqe128, int offset)
|
|
15
17
|
{
|
|
16
18
|
struct io_uring_cqe *cqe;
|
|
17
19
|
struct io_uring_sqe *sqe;
|
|
@@ -54,15 +56,123 @@ static int test_single_nop(struct io_uring *ring, bool sqe128)
|
|
|
54
56
|
return T_EXIT_FAIL;
|
|
55
57
|
}
|
|
56
58
|
|
|
57
|
-
int
|
|
59
|
+
static int check_sq(struct io_uring *ring, unsigned int ready,
|
|
60
|
+
unsigned int left, const char *msg)
|
|
61
|
+
{
|
|
62
|
+
unsigned int pspace, pready;
|
|
63
|
+
|
|
64
|
+
pready = io_uring_sq_ready(ring);
|
|
65
|
+
if (pready != ready) {
|
|
66
|
+
fprintf(stderr, "%s: %d ready, should be %d\n", msg, pready, ready);
|
|
67
|
+
return 1;
|
|
68
|
+
}
|
|
69
|
+
pspace = io_uring_sq_space_left(ring);
|
|
70
|
+
if (pspace != left) {
|
|
71
|
+
fprintf(stderr, "%s: %d entries, should be %d\n", msg, pspace, left);
|
|
72
|
+
return 1;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return 0;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
static void submit_and_reap(struct io_uring *ring, int to_reap, const char *msg)
|
|
79
|
+
{
|
|
80
|
+
struct io_uring_cqe *cqe;
|
|
81
|
+
unsigned long ud = 1000;
|
|
82
|
+
int i;
|
|
83
|
+
|
|
84
|
+
io_uring_submit(ring);
|
|
85
|
+
|
|
86
|
+
for (i = 0; i < to_reap; i++) {
|
|
87
|
+
io_uring_wait_cqe(ring, &cqe);
|
|
88
|
+
if (cqe->res < 0) {
|
|
89
|
+
fprintf(stderr, "cqe res %d\n", cqe->res);
|
|
90
|
+
io_uring_cqe_seen(ring, cqe);
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
if (cqe->user_data != ud)
|
|
94
|
+
fprintf(stderr, "%s: cqe=%d, %ld != %ld\n", msg, i, (long) cqe->user_data, ud);
|
|
95
|
+
ud++;
|
|
96
|
+
io_uring_cqe_seen(ring, cqe);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
static int test_sq_space(struct io_uring *ring, unsigned int flags)
|
|
101
|
+
{
|
|
102
|
+
struct io_uring_sqe *sqe;
|
|
103
|
+
int nop_adj;
|
|
104
|
+
|
|
105
|
+
/*
|
|
106
|
+
* For SQ_REWIND, sqe_tail resets to 0 after each submit, so we always
|
|
107
|
+
* start at position 0 and never hit wrap cases. For non-SQ_REWIND,
|
|
108
|
+
* after 32 test_single_nop iterations, sqe_tail ends up at position 7
|
|
109
|
+
* (modulo 8), so step5's sqe128 triggers the wrap case with a NOP.
|
|
110
|
+
*/
|
|
111
|
+
nop_adj = 0;
|
|
112
|
+
if (!(flags & IORING_SETUP_SQ_REWIND))
|
|
113
|
+
nop_adj = 1;
|
|
114
|
+
|
|
115
|
+
if (check_sq(ring, 0, NENTRIES, "initial"))
|
|
116
|
+
return 1;
|
|
117
|
+
|
|
118
|
+
sqe = io_uring_get_sqe(ring);
|
|
119
|
+
io_uring_prep_nop(sqe);
|
|
120
|
+
sqe->user_data = 1000;
|
|
121
|
+
|
|
122
|
+
if (check_sq(ring, 1, NENTRIES - 1, "step1"))
|
|
123
|
+
return 1;
|
|
124
|
+
|
|
125
|
+
sqe = io_uring_get_sqe128(ring);
|
|
126
|
+
io_uring_prep_nop128(sqe);
|
|
127
|
+
sqe->user_data = 1001;
|
|
128
|
+
|
|
129
|
+
if (check_sq(ring, 3, NENTRIES - 3, "step2"))
|
|
130
|
+
return 1;
|
|
131
|
+
|
|
132
|
+
sqe = io_uring_get_sqe(ring);
|
|
133
|
+
io_uring_prep_nop(sqe);
|
|
134
|
+
sqe->user_data = 1002;
|
|
135
|
+
|
|
136
|
+
if (check_sq(ring, 4, NENTRIES - 4, "step3"))
|
|
137
|
+
return 1;
|
|
138
|
+
|
|
139
|
+
submit_and_reap(ring, 3, "round1");
|
|
140
|
+
|
|
141
|
+
if (check_sq(ring, 0, NENTRIES, "step4"))
|
|
142
|
+
return 1;
|
|
143
|
+
|
|
144
|
+
sqe = io_uring_get_sqe128(ring);
|
|
145
|
+
io_uring_prep_nop128(sqe);
|
|
146
|
+
sqe->user_data = 1000;
|
|
147
|
+
|
|
148
|
+
/* SQ_REWIND: no wrap at position 0, just 2 slots. Non-rewind: wrap at 7, 3 slots */
|
|
149
|
+
if (check_sq(ring, 2 + nop_adj, NENTRIES - 2 - nop_adj, "step5"))
|
|
150
|
+
return 1;
|
|
151
|
+
|
|
152
|
+
sqe = io_uring_get_sqe(ring);
|
|
153
|
+
io_uring_prep_nop(sqe);
|
|
154
|
+
sqe->user_data = 1001;
|
|
155
|
+
|
|
156
|
+
if (check_sq(ring, 3 + nop_adj, NENTRIES - 3 - nop_adj, "step6"))
|
|
157
|
+
return 1;
|
|
158
|
+
|
|
159
|
+
sqe = io_uring_get_sqe128(ring);
|
|
160
|
+
io_uring_prep_nop128(sqe);
|
|
161
|
+
sqe->user_data = 1002;
|
|
162
|
+
|
|
163
|
+
if (check_sq(ring, 5 + nop_adj, NENTRIES - 5 - nop_adj, "step7"))
|
|
164
|
+
return 1;
|
|
165
|
+
|
|
166
|
+
submit_and_reap(ring, 3, "round2");
|
|
167
|
+
return 0;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
static int test_flags(unsigned int flags)
|
|
58
171
|
{
|
|
59
172
|
struct io_uring ring;
|
|
60
173
|
int ret, i;
|
|
61
174
|
|
|
62
|
-
|
|
63
|
-
return T_EXIT_SKIP;
|
|
64
|
-
|
|
65
|
-
ret = io_uring_queue_init(8, &ring, IORING_SETUP_SQE_MIXED);
|
|
175
|
+
ret = io_uring_queue_init(NENTRIES, &ring, IORING_SETUP_SQE_MIXED | flags);
|
|
66
176
|
if (ret) {
|
|
67
177
|
if (ret == -EINVAL)
|
|
68
178
|
return T_EXIT_SKIP;
|
|
@@ -72,11 +182,45 @@ int main(int argc, char *argv[])
|
|
|
72
182
|
|
|
73
183
|
/* alternate big and little sqe's */
|
|
74
184
|
for (i = 0; i < 32; i++) {
|
|
75
|
-
ret = test_single_nop(&ring, i & 1);
|
|
185
|
+
ret = test_single_nop(&ring, i & 1, i);
|
|
76
186
|
if (ret != T_EXIT_PASS)
|
|
77
187
|
break;
|
|
78
188
|
}
|
|
79
189
|
|
|
190
|
+
if (ret) {
|
|
191
|
+
fprintf(stderr, "Single nop test failed\n");
|
|
192
|
+
io_uring_queue_exit(&ring);
|
|
193
|
+
return ret;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
ret = test_sq_space(&ring, flags);
|
|
80
197
|
io_uring_queue_exit(&ring);
|
|
81
198
|
return ret;
|
|
199
|
+
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
int main(int argc, char *argv[])
|
|
203
|
+
{
|
|
204
|
+
int ret;
|
|
205
|
+
|
|
206
|
+
if (argc > 1)
|
|
207
|
+
return T_EXIT_SKIP;
|
|
208
|
+
|
|
209
|
+
ret = test_flags(0);
|
|
210
|
+
if (ret == T_EXIT_SKIP) {
|
|
211
|
+
return T_EXIT_SKIP;
|
|
212
|
+
} else if (ret) {
|
|
213
|
+
fprintf(stderr, "test flags 0 failed\n");
|
|
214
|
+
return T_EXIT_FAIL;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
ret = test_flags(IORING_SETUP_SQ_REWIND);
|
|
218
|
+
if (ret == T_EXIT_SKIP) {
|
|
219
|
+
return T_EXIT_SKIP;
|
|
220
|
+
} else if (ret) {
|
|
221
|
+
fprintf(stderr, "test flags REWIND failed\n");
|
|
222
|
+
return T_EXIT_FAIL;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
return ret;
|
|
82
226
|
}
|
data/vendor/liburing/test/test.h
CHANGED
|
@@ -20,6 +20,8 @@ static io_uring_test_config io_uring_test_configs[] = {
|
|
|
20
20
|
{ IORING_SETUP_SQE128, "large SQE"},
|
|
21
21
|
{ IORING_SETUP_CQE32, "large CQE"},
|
|
22
22
|
{ IORING_SETUP_SQE128 | IORING_SETUP_CQE32, "large SQE/CQE" },
|
|
23
|
+
{ IORING_SETUP_SQ_REWIND, "rewind SQ"},
|
|
24
|
+
{ IORING_SETUP_SQ_REWIND | IORING_SETUP_SQE128, "large rewind SQ"},
|
|
23
25
|
};
|
|
24
26
|
|
|
25
27
|
#define FOR_ALL_TEST_CONFIGS \
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/* SPDX-License-Identifier: MIT */
|
|
2
|
+
/*
|
|
3
|
+
* Description: verify that timestamp retrieval that needs retrying with
|
|
4
|
+
* a current list of SKBs works.
|
|
5
|
+
*
|
|
6
|
+
* Based on a test case from Google Big Sleep.
|
|
7
|
+
*
|
|
8
|
+
*/
|
|
9
|
+
#include <arpa/inet.h>
|
|
10
|
+
#include <err.h>
|
|
11
|
+
#include <fcntl.h>
|
|
12
|
+
#include <sys/time.h>
|
|
13
|
+
#include <linux/errqueue.h>
|
|
14
|
+
#include <linux/net_tstamp.h>
|
|
15
|
+
#include <netinet/in.h>
|
|
16
|
+
#include <stdio.h>
|
|
17
|
+
#include <stdlib.h>
|
|
18
|
+
#include <string.h>
|
|
19
|
+
#include <sys/socket.h>
|
|
20
|
+
#include <sys/uio.h>
|
|
21
|
+
#include <unistd.h>
|
|
22
|
+
|
|
23
|
+
#include "liburing.h"
|
|
24
|
+
#include "helpers.h"
|
|
25
|
+
|
|
26
|
+
/* Compatibility with slightly older kernel headers */
|
|
27
|
+
#ifndef SOCKET_URING_OP_TX_TIMESTAMP
|
|
28
|
+
#define SOCKET_URING_OP_TX_TIMESTAMP 4
|
|
29
|
+
#endif
|
|
30
|
+
|
|
31
|
+
/*
|
|
32
|
+
* Create a socket whose error queue contains both timestamp information and
|
|
33
|
+
* actual errors.
|
|
34
|
+
*/
|
|
35
|
+
static int create_sock_with_timestamps_and_errors(void)
|
|
36
|
+
{
|
|
37
|
+
struct sockaddr_in recv_addr = { };
|
|
38
|
+
struct sockaddr_in closed = { };
|
|
39
|
+
int recv_sock, sock, val;
|
|
40
|
+
char data = 'A';
|
|
41
|
+
|
|
42
|
+
sock = socket(AF_INET, SOCK_DGRAM, 0);
|
|
43
|
+
if (sock < 0)
|
|
44
|
+
err(1, "socket");
|
|
45
|
+
|
|
46
|
+
/* Enable TX timestamps */
|
|
47
|
+
val = SOF_TIMESTAMPING_SOFTWARE | SOF_TIMESTAMPING_TX_SOFTWARE |
|
|
48
|
+
SOF_TIMESTAMPING_OPT_ID | SOF_TIMESTAMPING_OPT_TSONLY;
|
|
49
|
+
if (setsockopt(sock, SOL_SOCKET, SO_TIMESTAMPING, &val, sizeof(val)) < 0)
|
|
50
|
+
err(1, "setsockopt(SO_TIMESTAMPING)");
|
|
51
|
+
|
|
52
|
+
/* Enable IP_RECVERR */
|
|
53
|
+
val = 1;
|
|
54
|
+
if (setsockopt(sock, IPPROTO_IP, IP_RECVERR, &val, sizeof(val)) < 0)
|
|
55
|
+
err(1, "setsockopt(IP_RECVERR)");
|
|
56
|
+
|
|
57
|
+
recv_sock = socket(AF_INET, SOCK_DGRAM, 0);
|
|
58
|
+
if (recv_sock < 0)
|
|
59
|
+
err(1, "socket");
|
|
60
|
+
|
|
61
|
+
recv_addr.sin_family = AF_INET;
|
|
62
|
+
recv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
|
|
63
|
+
if (bind(recv_sock, (struct sockaddr*)&recv_addr, sizeof(recv_addr)) < 0)
|
|
64
|
+
err(1, "bind receiver");
|
|
65
|
+
|
|
66
|
+
socklen_t recv_len = sizeof(recv_addr);
|
|
67
|
+
if (getsockname(recv_sock, (struct sockaddr*)&recv_addr, &recv_len) < 0)
|
|
68
|
+
err(1, "getsockname");
|
|
69
|
+
|
|
70
|
+
/* Send packets to generate TX timestamps. */
|
|
71
|
+
for (int i = 0; i < 2; i++) {
|
|
72
|
+
if (sendto(sock, &data, sizeof(data), 0, (struct sockaddr*)&recv_addr, sizeof(recv_addr)) < 0)
|
|
73
|
+
err(1, "sendto (%d)", i);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
closed.sin_family = AF_INET;
|
|
77
|
+
closed.sin_addr.s_addr = inet_addr("127.0.0.1");
|
|
78
|
+
closed.sin_port = htons(9); /* assuming no one is listening on port 9 */
|
|
79
|
+
if (sendto(sock, &data, sizeof(data), 0, (struct sockaddr*) &closed, sizeof(closed)) < 0)
|
|
80
|
+
warn("sendto");
|
|
81
|
+
|
|
82
|
+
return sock;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
int main(int argc, char *argv[])
|
|
86
|
+
{
|
|
87
|
+
struct io_uring_sqe *sqe;
|
|
88
|
+
struct io_uring_cqe *cqe;
|
|
89
|
+
struct io_uring ring;
|
|
90
|
+
struct io_uring_params params = {
|
|
91
|
+
.flags = IORING_SETUP_CQE32, /* required for timestamps */
|
|
92
|
+
};
|
|
93
|
+
char buf[1024], ctrl_recv[1024];
|
|
94
|
+
struct iovec iov_recv = { .iov_base = buf, .iov_len = sizeof(buf) };
|
|
95
|
+
struct msghdr msg_recv = {
|
|
96
|
+
.msg_iov = &iov_recv,
|
|
97
|
+
.msg_iovlen = 1,
|
|
98
|
+
.msg_control = ctrl_recv,
|
|
99
|
+
.msg_controllen = sizeof(ctrl_recv),
|
|
100
|
+
};
|
|
101
|
+
int sock, ret;
|
|
102
|
+
|
|
103
|
+
if (argc > 1)
|
|
104
|
+
return T_EXIT_SKIP;
|
|
105
|
+
|
|
106
|
+
sock = create_sock_with_timestamps_and_errors();
|
|
107
|
+
|
|
108
|
+
ret = io_uring_queue_init_params(1, &ring, ¶ms);
|
|
109
|
+
if (ret < 0) {
|
|
110
|
+
if (ret == -EINVAL)
|
|
111
|
+
return T_EXIT_SKIP;
|
|
112
|
+
err(1, "io_uring_queue_init_params: %d", ret);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
sqe = io_uring_get_sqe(&ring);
|
|
116
|
+
*sqe = (struct io_uring_sqe) {
|
|
117
|
+
.opcode = IORING_OP_URING_CMD,
|
|
118
|
+
.fd = sock,
|
|
119
|
+
.cmd_op = SOCKET_URING_OP_TX_TIMESTAMP,
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
io_uring_submit(&ring);
|
|
123
|
+
|
|
124
|
+
ret = io_uring_wait_cqe(&ring, &cqe);
|
|
125
|
+
if (ret < 0)
|
|
126
|
+
errx(1, "io_uring_wait_cqe: %d", ret);
|
|
127
|
+
ret = cqe->res;
|
|
128
|
+
io_uring_cqe_seen(&ring, cqe);
|
|
129
|
+
/* kernel doesn't support retrieving timestamps */
|
|
130
|
+
if (ret == -EOPNOTSUPP)
|
|
131
|
+
return T_EXIT_SKIP;
|
|
132
|
+
|
|
133
|
+
recvmsg(sock, &msg_recv, MSG_ERRQUEUE | MSG_DONTWAIT);
|
|
134
|
+
return T_EXIT_PASS;
|
|
135
|
+
}
|
|
@@ -520,6 +520,135 @@ static void test_basic(struct buf_desc *bd)
|
|
|
520
520
|
}
|
|
521
521
|
}
|
|
522
522
|
|
|
523
|
+
static int test_readv_fixed(struct buf_desc *bd, struct iovec *vecs, int nr_vec)
|
|
524
|
+
{
|
|
525
|
+
unsigned buf_idx = bd->buf_idx;
|
|
526
|
+
struct io_uring *ring = &bd->ring;
|
|
527
|
+
struct io_uring_sqe *sqe;
|
|
528
|
+
struct io_uring_cqe *cqe;
|
|
529
|
+
size_t total_len, i, offset;
|
|
530
|
+
int ret, fd;
|
|
531
|
+
char *expected;
|
|
532
|
+
char filename[] = ".readv_fixed.XXXXXX";
|
|
533
|
+
|
|
534
|
+
total_len = t_iovec_data_length(vecs, nr_vec);
|
|
535
|
+
|
|
536
|
+
expected = malloc(total_len);
|
|
537
|
+
if (!expected) {
|
|
538
|
+
fprintf(stderr, "malloc failed\n");
|
|
539
|
+
return 1;
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
/* Fill expected buffer with pattern */
|
|
543
|
+
for (i = 0; i < total_len; i++)
|
|
544
|
+
expected[i] = i & 0xff;
|
|
545
|
+
|
|
546
|
+
fd = mkstemp(filename);
|
|
547
|
+
if (fd < 0) {
|
|
548
|
+
perror("mkstemp");
|
|
549
|
+
free(expected);
|
|
550
|
+
return 1;
|
|
551
|
+
}
|
|
552
|
+
unlink(filename);
|
|
553
|
+
|
|
554
|
+
/* Write expected data to file */
|
|
555
|
+
ret = write(fd, expected, total_len);
|
|
556
|
+
if (ret != total_len) {
|
|
557
|
+
fprintf(stderr, "file write failed: %d\n", ret);
|
|
558
|
+
close(fd);
|
|
559
|
+
free(expected);
|
|
560
|
+
return 1;
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
/* Clear registered buffer before reading into it */
|
|
564
|
+
memset(bd->buf_wr, 0, bd->size);
|
|
565
|
+
|
|
566
|
+
/* Read using READV_FIXED - vecs already point to bd->buf_wr (registered) */
|
|
567
|
+
sqe = io_uring_get_sqe(ring);
|
|
568
|
+
io_uring_prep_readv_fixed(sqe, fd, vecs, nr_vec, 0, 0, buf_idx);
|
|
569
|
+
|
|
570
|
+
ret = io_uring_submit(ring);
|
|
571
|
+
if (ret != 1) {
|
|
572
|
+
fprintf(stderr, "submit failed %i\n", ret);
|
|
573
|
+
close(fd);
|
|
574
|
+
free(expected);
|
|
575
|
+
return 1;
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
ret = io_uring_wait_cqe(ring, &cqe);
|
|
579
|
+
if (ret) {
|
|
580
|
+
fprintf(stderr, "wait_cqe=%d\n", ret);
|
|
581
|
+
close(fd);
|
|
582
|
+
free(expected);
|
|
583
|
+
return 1;
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
ret = cqe->res;
|
|
587
|
+
io_uring_cqe_seen(ring, cqe);
|
|
588
|
+
|
|
589
|
+
close(fd);
|
|
590
|
+
|
|
591
|
+
if (ret != total_len) {
|
|
592
|
+
fprintf(stderr, "readv_fixed: got %d, expected %zu\n", ret, total_len);
|
|
593
|
+
free(expected);
|
|
594
|
+
return 1;
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
/* Verify data across all iovec segments */
|
|
598
|
+
offset = 0;
|
|
599
|
+
for (i = 0; i < nr_vec; i++) {
|
|
600
|
+
if (memcmp(vecs[i].iov_base, expected + offset, vecs[i].iov_len) != 0) {
|
|
601
|
+
fprintf(stderr, "readv_fixed: data mismatch at segment %zu\n", i);
|
|
602
|
+
free(expected);
|
|
603
|
+
return 1;
|
|
604
|
+
}
|
|
605
|
+
offset += vecs[i].iov_len;
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
free(expected);
|
|
609
|
+
return 0;
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
static int test_readv(struct buf_desc *bd)
|
|
613
|
+
{
|
|
614
|
+
void *p = bd->buf_wr;
|
|
615
|
+
int ret;
|
|
616
|
+
struct iovec iov_page = { .iov_base = p, .iov_len = page_sz };
|
|
617
|
+
struct iovec iov_multi[] = {
|
|
618
|
+
{ .iov_base = p, .iov_len = page_sz },
|
|
619
|
+
{ .iov_base = p + page_sz, .iov_len = page_sz },
|
|
620
|
+
{ .iov_base = p + page_sz * 2, .iov_len = page_sz },
|
|
621
|
+
};
|
|
622
|
+
struct iovec iov_unalign = { .iov_base = p + 1, .iov_len = page_sz - 1 };
|
|
623
|
+
|
|
624
|
+
reinit_ring(bd);
|
|
625
|
+
|
|
626
|
+
/* Single page read */
|
|
627
|
+
ret = test_readv_fixed(bd, &iov_page, 1);
|
|
628
|
+
if (ret) {
|
|
629
|
+
fprintf(stderr, "readv_fixed: single page failed\n");
|
|
630
|
+
return ret;
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
/* Multi-segment read */
|
|
634
|
+
reinit_ring(bd);
|
|
635
|
+
ret = test_readv_fixed(bd, iov_multi, 3);
|
|
636
|
+
if (ret) {
|
|
637
|
+
fprintf(stderr, "readv_fixed: multi-segment failed\n");
|
|
638
|
+
return ret;
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
/* Unaligned read */
|
|
642
|
+
reinit_ring(bd);
|
|
643
|
+
ret = test_readv_fixed(bd, &iov_unalign, 1);
|
|
644
|
+
if (ret) {
|
|
645
|
+
fprintf(stderr, "readv_fixed: unaligned failed\n");
|
|
646
|
+
return ret;
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
return 0;
|
|
650
|
+
}
|
|
651
|
+
|
|
523
652
|
static void test_fail(struct buf_desc *bd)
|
|
524
653
|
{
|
|
525
654
|
int ret, cqe_ret;
|
|
@@ -576,7 +705,7 @@ static void test_fail(struct buf_desc *bd)
|
|
|
576
705
|
int main(int argc, char *argv[])
|
|
577
706
|
{
|
|
578
707
|
struct buf_desc bd = {};
|
|
579
|
-
int i
|
|
708
|
+
int ret, i;
|
|
580
709
|
|
|
581
710
|
if (argc > 1)
|
|
582
711
|
return T_EXIT_SKIP;
|
|
@@ -601,6 +730,12 @@ int main(int argc, char *argv[])
|
|
|
601
730
|
test_fail(&bd);
|
|
602
731
|
}
|
|
603
732
|
|
|
733
|
+
ret = test_readv(&bd);
|
|
734
|
+
if (ret) {
|
|
735
|
+
fprintf(stderr, "test_readv failed\n");
|
|
736
|
+
return T_EXIT_FAIL;
|
|
737
|
+
}
|
|
738
|
+
|
|
604
739
|
free(bd.buf_rd);
|
|
605
740
|
io_uring_queue_exit(&bd.ring);
|
|
606
741
|
return 0;
|