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
data/uringmachine.gemspec
CHANGED
|
@@ -15,14 +15,8 @@ Gem::Specification.new do |s|
|
|
|
15
15
|
"changelog_uri" => "https://github.com/digital-fabric/uringmachine/blob/master/CHANGELOG.md"
|
|
16
16
|
}
|
|
17
17
|
s.rdoc_options = ["--title", "UringMachine", "--main", "README.md"]
|
|
18
|
-
s.extra_rdoc_files =
|
|
18
|
+
s.extra_rdoc_files = `git ls-files -z *.rdoc *.md lib/*.rb lib/**/*.rb ext/um/*.c ext/um/*.h benchmark/*.md benchmark/*.png`.split("\x0")
|
|
19
19
|
s.extensions = ["ext/um/extconf.rb"]
|
|
20
20
|
s.require_paths = ["lib"]
|
|
21
21
|
s.required_ruby_version = '>= 3.5'
|
|
22
|
-
|
|
23
|
-
s.add_development_dependency 'rake-compiler', '~>1.3.0'
|
|
24
|
-
s.add_development_dependency 'minitest', '~>5.26.2'
|
|
25
|
-
s.add_development_dependency 'benchmark'
|
|
26
|
-
s.add_development_dependency 'benchmark-ips'
|
|
27
|
-
s.add_development_dependency 'http_parser.rb', '~>0.8.0'
|
|
28
22
|
end
|
|
@@ -60,6 +60,9 @@ struct thread_data {
|
|
|
60
60
|
int fd;
|
|
61
61
|
};
|
|
62
62
|
|
|
63
|
+
static int page_size;
|
|
64
|
+
static size_t alloc_size;
|
|
65
|
+
|
|
63
66
|
static bool cfg_reg_ringfd = true;
|
|
64
67
|
static bool cfg_fixed_files = 1;
|
|
65
68
|
static bool cfg_zc = 1;
|
|
@@ -83,7 +86,6 @@ static bool cfg_verify;
|
|
|
83
86
|
static socklen_t cfg_alen;
|
|
84
87
|
static char *str_addr = NULL;
|
|
85
88
|
|
|
86
|
-
static char payload_buf[IP_MAXPACKET + PATTERN_SIZE] __attribute__((aligned(4096)));
|
|
87
89
|
static char *payload;
|
|
88
90
|
static struct thread_data threads[MAX_THREADS];
|
|
89
91
|
static pthread_barrier_t barrier;
|
|
@@ -521,7 +523,7 @@ static void usage(const char *filepath)
|
|
|
521
523
|
static void parse_opts(int argc, char **argv)
|
|
522
524
|
{
|
|
523
525
|
const char *cfg_test;
|
|
524
|
-
const int
|
|
526
|
+
const int max_udp_payload_len = IP_MAXPACKET -
|
|
525
527
|
sizeof(struct ipv6hdr) -
|
|
526
528
|
sizeof(struct tcphdr) -
|
|
527
529
|
40 /* max tcp options */;
|
|
@@ -533,7 +535,7 @@ static void parse_opts(int argc, char **argv)
|
|
|
533
535
|
exit(0);
|
|
534
536
|
}
|
|
535
537
|
|
|
536
|
-
cfg_payload_len =
|
|
538
|
+
cfg_payload_len = max_udp_payload_len;
|
|
537
539
|
|
|
538
540
|
while ((c = getopt(argc, argv, "46D:p:s:t:n:z:I:b:l:dC:T:Ryv")) != -1) {
|
|
539
541
|
switch (c) {
|
|
@@ -607,21 +609,25 @@ static void parse_opts(int argc, char **argv)
|
|
|
607
609
|
else
|
|
608
610
|
t_error(1, 0, "unknown cfg_test %s", cfg_test);
|
|
609
611
|
|
|
610
|
-
if (
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
612
|
+
if (!cfg_rx) {
|
|
613
|
+
if (cfg_nr_reqs > MAX_SUBMIT_NR)
|
|
614
|
+
t_error(1, 0, "-n: submit batch nr exceeds max (%d)", MAX_SUBMIT_NR);
|
|
615
|
+
if (!cfg_nr_reqs)
|
|
616
|
+
t_error(1, 0, "-n: submit batch can't be zero");
|
|
617
|
+
if (cfg_nr_reqs > 1 && cfg_type == SOCK_STREAM) {
|
|
618
|
+
printf("warning: submit batching >1 with TCP sockets will cause data reordering");
|
|
619
|
+
if (cfg_verify)
|
|
620
|
+
t_error(1, 0, "can't verify data because of reordering");
|
|
621
|
+
}
|
|
622
|
+
} else {
|
|
623
|
+
if (cfg_ifname)
|
|
624
|
+
t_error(1, 0, "Interface can only be specified for tx");
|
|
620
625
|
if (cfg_verify)
|
|
621
|
-
t_error(1, 0, "
|
|
626
|
+
t_error(1, 0, "Server mode doesn't support data verification");
|
|
622
627
|
}
|
|
623
|
-
|
|
624
|
-
|
|
628
|
+
|
|
629
|
+
if (cfg_type == SOCK_DGRAM && cfg_payload_len > max_udp_payload_len)
|
|
630
|
+
t_error(1, 0, "-s: UDP payload exceeds max (%d)", max_udp_payload_len);
|
|
625
631
|
|
|
626
632
|
str_addr = daddr;
|
|
627
633
|
|
|
@@ -631,28 +637,25 @@ static void parse_opts(int argc, char **argv)
|
|
|
631
637
|
|
|
632
638
|
static void init_buffers(void)
|
|
633
639
|
{
|
|
634
|
-
|
|
640
|
+
unsigned map_flags = MAP_PRIVATE | MAP_ANONYMOUS;
|
|
635
641
|
int i;
|
|
636
642
|
|
|
637
|
-
|
|
638
|
-
|
|
643
|
+
alloc_size = cfg_payload_len + PATTERN_SIZE;
|
|
644
|
+
alloc_size = (alloc_size + page_size - 1) / page_size * page_size;
|
|
639
645
|
|
|
640
646
|
if (cfg_hugetlb) {
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
if (payload == MAP_FAILED)
|
|
646
|
-
t_error(0, 1, "huge pages alloc failed");
|
|
647
|
+
size_t huge_size = 1 << 21;
|
|
648
|
+
|
|
649
|
+
alloc_size = (alloc_size + huge_size - 1) / huge_size * huge_size;
|
|
650
|
+
map_flags |= MAP_HUGETLB | MAP_HUGE_2MB;
|
|
647
651
|
}
|
|
648
652
|
|
|
649
|
-
|
|
650
|
-
|
|
653
|
+
payload = mmap(NULL, alloc_size, PROT_READ | PROT_WRITE, map_flags, -1, 0);
|
|
654
|
+
if (payload == MAP_FAILED)
|
|
655
|
+
t_error(0, 1, "buffer alloc failed (size %zu)\n", alloc_size);
|
|
651
656
|
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
payload[i] = 'a' + (i % PATTERN_SIZE);
|
|
655
|
-
}
|
|
657
|
+
for (i = 0; i < alloc_size; i++)
|
|
658
|
+
payload[i] = 'a' + (i % PATTERN_SIZE);
|
|
656
659
|
}
|
|
657
660
|
|
|
658
661
|
int main(int argc, char **argv)
|
|
@@ -663,6 +666,12 @@ int main(int argc, char **argv)
|
|
|
663
666
|
unsigned int i;
|
|
664
667
|
void *res;
|
|
665
668
|
|
|
669
|
+
page_size = sysconf(_SC_PAGESIZE);
|
|
670
|
+
if (page_size < 0) {
|
|
671
|
+
perror("sysconf(_SC_PAGESIZE)");
|
|
672
|
+
return 1;
|
|
673
|
+
}
|
|
674
|
+
|
|
666
675
|
parse_opts(argc, argv);
|
|
667
676
|
init_buffers();
|
|
668
677
|
set_cpu_affinity();
|
|
@@ -700,6 +709,9 @@ int main(int argc, char **argv)
|
|
|
700
709
|
packets * 1000 / tsum,
|
|
701
710
|
(bytes >> 20) * 1000 / tsum);
|
|
702
711
|
}
|
|
712
|
+
|
|
713
|
+
if (payload)
|
|
714
|
+
munmap(payload, alloc_size);
|
|
703
715
|
pthread_barrier_destroy(&barrier);
|
|
704
716
|
return 0;
|
|
705
717
|
}
|
|
@@ -44,6 +44,14 @@
|
|
|
44
44
|
#include "liburing.h"
|
|
45
45
|
#include "helpers.h"
|
|
46
46
|
|
|
47
|
+
enum {
|
|
48
|
+
AFFINITY_MODE_NONE,
|
|
49
|
+
AFFINITY_MODE_SAME,
|
|
50
|
+
AFFINITY_MODE_DIFFERENT,
|
|
51
|
+
|
|
52
|
+
__AFFINITY_MODE_MAX,
|
|
53
|
+
};
|
|
54
|
+
|
|
47
55
|
enum {
|
|
48
56
|
RQ_ALLOC_USER,
|
|
49
57
|
RQ_ALLOC_KERNEL,
|
|
@@ -51,9 +59,6 @@ enum {
|
|
|
51
59
|
__RQ_ALLOC_MAX,
|
|
52
60
|
};
|
|
53
61
|
|
|
54
|
-
static long page_size;
|
|
55
|
-
#define AREA_SIZE (8192 * page_size)
|
|
56
|
-
|
|
57
62
|
#define REQ_TYPE_SHIFT 3
|
|
58
63
|
#define REQ_TYPE_MASK ((1UL << REQ_TYPE_SHIFT) - 1)
|
|
59
64
|
|
|
@@ -69,28 +74,92 @@ enum {
|
|
|
69
74
|
REQ_TYPE_RX = 2,
|
|
70
75
|
};
|
|
71
76
|
|
|
77
|
+
struct zc_conn {
|
|
78
|
+
int sockfd;
|
|
79
|
+
unsigned long received;
|
|
80
|
+
unsigned stat_nr_reqs;
|
|
81
|
+
unsigned stat_nr_cqes;
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
static unsigned cfg_rq_entries = 8192;
|
|
85
|
+
static unsigned cfg_cq_entries = 8192;
|
|
86
|
+
static long cfg_area_size = 256 * 1024 * 1024;
|
|
72
87
|
static int cfg_port = 8000;
|
|
73
88
|
static const char *cfg_ifname;
|
|
74
89
|
static int cfg_queue_id = -1;
|
|
75
90
|
static bool cfg_verify_data = false;
|
|
76
91
|
static size_t cfg_size = 0;
|
|
92
|
+
static unsigned cfg_affinity_mode = AFFINITY_MODE_NONE;
|
|
77
93
|
static unsigned cfg_rq_alloc_mode = RQ_ALLOC_USER;
|
|
78
94
|
static unsigned cfg_area_type = AREA_TYPE_NORMAL;
|
|
79
95
|
static struct sockaddr_in6 cfg_addr;
|
|
80
96
|
|
|
97
|
+
static long page_size;
|
|
98
|
+
|
|
81
99
|
static void *area_ptr;
|
|
82
100
|
static void *ring_ptr;
|
|
83
101
|
static size_t ring_size;
|
|
84
102
|
static struct io_uring_zcrx_rq rq_ring;
|
|
85
103
|
static unsigned long area_token;
|
|
86
|
-
static int connfd;
|
|
87
104
|
static bool stop;
|
|
88
|
-
static size_t received;
|
|
89
105
|
static __u32 zcrx_id;
|
|
90
106
|
|
|
91
107
|
static int dmabuf_fd;
|
|
92
108
|
static int memfd;
|
|
93
109
|
|
|
110
|
+
static int listen_fd;
|
|
111
|
+
static int target_cpu = -1;
|
|
112
|
+
|
|
113
|
+
static int get_sock_cpu(int sockfd)
|
|
114
|
+
{
|
|
115
|
+
int cpu;
|
|
116
|
+
socklen_t len = sizeof(cpu);
|
|
117
|
+
|
|
118
|
+
if (getsockopt(sockfd, SOL_SOCKET, SO_INCOMING_CPU, &cpu, &len))
|
|
119
|
+
t_error(1, errno, "getsockopt failed\n");
|
|
120
|
+
return cpu;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
static void set_affinity(int sockfd)
|
|
124
|
+
{
|
|
125
|
+
int new_cpu = -1;
|
|
126
|
+
int sock_cpu;
|
|
127
|
+
cpu_set_t mask;
|
|
128
|
+
|
|
129
|
+
if (cfg_affinity_mode == AFFINITY_MODE_NONE)
|
|
130
|
+
return;
|
|
131
|
+
|
|
132
|
+
sock_cpu = get_sock_cpu(sockfd);
|
|
133
|
+
if (sock_cpu == -1)
|
|
134
|
+
t_error(1, 0, "Can't socket's CPU");
|
|
135
|
+
|
|
136
|
+
if (cfg_affinity_mode == AFFINITY_MODE_SAME) {
|
|
137
|
+
new_cpu = sock_cpu;
|
|
138
|
+
} else if (cfg_affinity_mode == AFFINITY_MODE_DIFFERENT) {
|
|
139
|
+
if (target_cpu != -1 && target_cpu != sock_cpu)
|
|
140
|
+
new_cpu = target_cpu;
|
|
141
|
+
else
|
|
142
|
+
new_cpu = sock_cpu ^ 1;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
if (target_cpu != -1 && new_cpu != target_cpu) {
|
|
146
|
+
printf("Couldn't set affinity for multi socket setup\n");
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
CPU_ZERO(&mask);
|
|
151
|
+
CPU_SET(new_cpu, &mask);
|
|
152
|
+
if (sched_setaffinity(0, sizeof(mask), &mask))
|
|
153
|
+
t_error(1, errno, "sched_setaffinity() failed\n");
|
|
154
|
+
target_cpu = new_cpu;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
static struct zc_conn *get_connection(__u64 user_data)
|
|
158
|
+
{
|
|
159
|
+
user_data &= ~REQ_TYPE_MASK;
|
|
160
|
+
return (struct zc_conn *)(unsigned long)user_data;
|
|
161
|
+
}
|
|
162
|
+
|
|
94
163
|
static inline size_t get_refill_ring_size(unsigned int rq_entries)
|
|
95
164
|
{
|
|
96
165
|
ring_size = rq_entries * sizeof(struct io_uring_zcrx_rqe);
|
|
@@ -106,36 +175,36 @@ static void zcrx_populate_area_udmabuf(struct io_uring_zcrx_area_reg *area_reg)
|
|
|
106
175
|
|
|
107
176
|
devfd = open("/dev/udmabuf", O_RDWR);
|
|
108
177
|
if (devfd < 0)
|
|
109
|
-
t_error(1,
|
|
178
|
+
t_error(1, errno, "Failed to open udmabuf dev");
|
|
110
179
|
|
|
111
180
|
memfd = memfd_create("udmabuf-test", MFD_ALLOW_SEALING);
|
|
112
181
|
if (memfd < 0)
|
|
113
|
-
t_error(1,
|
|
182
|
+
t_error(1, errno, "Failed to open udmabuf dev");
|
|
114
183
|
|
|
115
184
|
ret = fcntl(memfd, F_ADD_SEALS, F_SEAL_SHRINK);
|
|
116
185
|
if (ret < 0)
|
|
117
|
-
t_error(1,
|
|
186
|
+
t_error(1, errno, "Failed to set seals");
|
|
118
187
|
|
|
119
|
-
ret = ftruncate(memfd,
|
|
188
|
+
ret = ftruncate(memfd, cfg_area_size);
|
|
120
189
|
if (ret == -1)
|
|
121
|
-
t_error(1,
|
|
190
|
+
t_error(1, errno, "Failed to resize udmabuf");
|
|
122
191
|
|
|
123
192
|
memset(&create, 0, sizeof(create));
|
|
124
193
|
create.memfd = memfd;
|
|
125
194
|
create.offset = 0;
|
|
126
|
-
create.size =
|
|
195
|
+
create.size = cfg_area_size;
|
|
127
196
|
dmabuf_fd = ioctl(devfd, UDMABUF_CREATE, &create);
|
|
128
197
|
if (dmabuf_fd < 0)
|
|
129
|
-
t_error(1,
|
|
198
|
+
t_error(1, errno, "Failed to create udmabuf");
|
|
130
199
|
|
|
131
|
-
area_ptr = mmap(NULL,
|
|
200
|
+
area_ptr = mmap(NULL, cfg_area_size, PROT_READ | PROT_WRITE, MAP_SHARED,
|
|
132
201
|
dmabuf_fd, 0);
|
|
133
202
|
if (area_ptr == MAP_FAILED)
|
|
134
|
-
t_error(1,
|
|
203
|
+
t_error(1, errno, "Failed to mmap udmabuf");
|
|
135
204
|
|
|
136
205
|
memset(area_reg, 0, sizeof(*area_reg));
|
|
137
206
|
area_reg->addr = 0; /* offset into dmabuf */
|
|
138
|
-
area_reg->len =
|
|
207
|
+
area_reg->len = cfg_area_size;
|
|
139
208
|
area_reg->flags |= IORING_ZCRX_AREA_DMABUF;
|
|
140
209
|
area_reg->dmabuf_fd = dmabuf_fd;
|
|
141
210
|
|
|
@@ -152,10 +221,10 @@ static void zcrx_populate_area(struct io_uring_zcrx_area_reg *area_reg)
|
|
|
152
221
|
return;
|
|
153
222
|
}
|
|
154
223
|
if (cfg_area_type == AREA_TYPE_NORMAL) {
|
|
155
|
-
area_ptr = mmap(NULL,
|
|
224
|
+
area_ptr = mmap(NULL, cfg_area_size, prot,
|
|
156
225
|
flags, 0, 0);
|
|
157
226
|
} else if (cfg_area_type == AREA_TYPE_HUGE_PAGES) {
|
|
158
|
-
area_ptr = mmap(NULL,
|
|
227
|
+
area_ptr = mmap(NULL, cfg_area_size, prot,
|
|
159
228
|
flags | MAP_HUGETLB | MAP_HUGE_2MB, -1, 0);
|
|
160
229
|
}
|
|
161
230
|
|
|
@@ -164,7 +233,7 @@ static void zcrx_populate_area(struct io_uring_zcrx_area_reg *area_reg)
|
|
|
164
233
|
|
|
165
234
|
memset(area_reg, 0, sizeof(*area_reg));
|
|
166
235
|
area_reg->addr = uring_ptr_to_u64(area_ptr);
|
|
167
|
-
area_reg->len =
|
|
236
|
+
area_reg->len = cfg_area_size;
|
|
168
237
|
area_reg->flags = 0;
|
|
169
238
|
}
|
|
170
239
|
|
|
@@ -172,7 +241,7 @@ static void setup_zcrx(struct io_uring *ring)
|
|
|
172
241
|
{
|
|
173
242
|
struct io_uring_zcrx_area_reg area_reg;
|
|
174
243
|
unsigned int ifindex;
|
|
175
|
-
unsigned int rq_entries =
|
|
244
|
+
unsigned int rq_entries = cfg_rq_entries;
|
|
176
245
|
unsigned rq_flags = 0;
|
|
177
246
|
int ret;
|
|
178
247
|
|
|
@@ -239,59 +308,160 @@ static void add_accept(struct io_uring *ring, int sockfd)
|
|
|
239
308
|
sqe->user_data = REQ_TYPE_ACCEPT;
|
|
240
309
|
}
|
|
241
310
|
|
|
242
|
-
static void add_recvzc(struct io_uring *ring,
|
|
311
|
+
static void add_recvzc(struct io_uring *ring, struct zc_conn *conn, size_t len)
|
|
243
312
|
{
|
|
244
313
|
struct io_uring_sqe *sqe = io_uring_get_sqe(ring);
|
|
314
|
+
__u64 token;
|
|
315
|
+
|
|
316
|
+
token = (__u64)(unsigned long)conn;
|
|
317
|
+
token |= REQ_TYPE_RX;
|
|
245
318
|
|
|
246
|
-
|
|
319
|
+
conn->stat_nr_reqs++;
|
|
320
|
+
io_uring_prep_rw(IORING_OP_RECV_ZC, sqe, conn->sockfd, NULL, len, 0);
|
|
247
321
|
sqe->ioprio |= IORING_RECV_MULTISHOT;
|
|
248
322
|
sqe->zcrx_ifq_idx = zcrx_id;
|
|
249
|
-
sqe->user_data =
|
|
323
|
+
sqe->user_data = token;
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
static void print_socket_info(int sockfd)
|
|
327
|
+
{
|
|
328
|
+
struct sockaddr_in6 peer_addr;
|
|
329
|
+
socklen_t addr_len = sizeof(peer_addr);
|
|
330
|
+
char ip_str[INET6_ADDRSTRLEN];
|
|
331
|
+
int port;
|
|
332
|
+
|
|
333
|
+
if (getpeername(sockfd, (struct sockaddr *)&peer_addr, &addr_len) < 0) {
|
|
334
|
+
t_error(1, errno, "getpeername failed");
|
|
335
|
+
return;
|
|
336
|
+
}
|
|
337
|
+
if (!inet_ntop(AF_INET6, &peer_addr.sin6_addr, ip_str, sizeof(ip_str))) {
|
|
338
|
+
t_error(1, errno, "inet_ntop failed");
|
|
339
|
+
return;
|
|
340
|
+
}
|
|
341
|
+
port = ntohs(peer_addr.sin6_port);
|
|
342
|
+
|
|
343
|
+
printf("socket accepted: fd %i, Peer IP %s, Peer port %d\n",
|
|
344
|
+
sockfd, ip_str, port);
|
|
250
345
|
}
|
|
251
346
|
|
|
252
347
|
static void process_accept(struct io_uring *ring, struct io_uring_cqe *cqe)
|
|
253
348
|
{
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
if (
|
|
349
|
+
struct zc_conn *conn;
|
|
350
|
+
|
|
351
|
+
if (cqe->res < 0) {
|
|
352
|
+
printf("Accept failed %i, terminate\n", cqe->res);
|
|
353
|
+
stop = false;
|
|
354
|
+
return;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
conn = aligned_alloc(64, sizeof(*conn));
|
|
358
|
+
if (!conn)
|
|
359
|
+
t_error(1, 0, "can't allocate conn structure");
|
|
360
|
+
if (conn->sockfd)
|
|
257
361
|
t_error(1, 0, "Unexpected second connection");
|
|
258
362
|
|
|
259
|
-
|
|
260
|
-
|
|
363
|
+
memset(conn, 0, sizeof(*conn));
|
|
364
|
+
conn->sockfd = cqe->res;
|
|
365
|
+
print_socket_info(conn->sockfd);
|
|
366
|
+
set_affinity(conn->sockfd);
|
|
367
|
+
add_recvzc(ring, conn, cfg_size);
|
|
368
|
+
|
|
369
|
+
add_accept(ring, listen_fd);
|
|
261
370
|
}
|
|
262
371
|
|
|
263
|
-
static void verify_data(
|
|
372
|
+
static void verify_data(__u8 *data, size_t size, unsigned long seq)
|
|
264
373
|
{
|
|
265
|
-
|
|
374
|
+
size_t i;
|
|
266
375
|
|
|
267
376
|
if (!cfg_verify_data)
|
|
268
377
|
return;
|
|
269
378
|
|
|
270
379
|
for (i = 0; i < size; i++) {
|
|
271
|
-
|
|
380
|
+
__u8 expected = (__u8)'a' + (seq + i) % 26;
|
|
381
|
+
__u8 v = data[i];
|
|
272
382
|
|
|
273
|
-
if (
|
|
274
|
-
t_error(1, 0, "payload mismatch at %
|
|
275
|
-
i, expected,
|
|
383
|
+
if (v != expected)
|
|
384
|
+
t_error(1, 0, "payload mismatch at %u: expected %u vs got %u, diff %i, base seq %lu, seq %lu",
|
|
385
|
+
(unsigned)i, expected, v, (int)expected - v,
|
|
386
|
+
seq, seq + i);
|
|
276
387
|
}
|
|
277
388
|
}
|
|
278
389
|
|
|
279
|
-
static
|
|
280
|
-
|
|
390
|
+
static unsigned rq_nr_queued(struct io_uring_zcrx_rq *rq)
|
|
391
|
+
{
|
|
392
|
+
return rq->rq_tail - io_uring_smp_load_acquire(rq->khead);
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
static inline void fill_rqe(const struct io_uring_cqe *cqe,
|
|
396
|
+
struct io_uring_zcrx_rqe *rqe)
|
|
397
|
+
{
|
|
398
|
+
const struct io_uring_zcrx_cqe *rcqe = (void *)(cqe + 1);
|
|
399
|
+
|
|
400
|
+
rqe->off = (rcqe->off & ~IORING_ZCRX_AREA_MASK) | area_token;
|
|
401
|
+
rqe->len = cqe->res;
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
static void return_buffer(struct io_uring_zcrx_rq *rq_ring,
|
|
405
|
+
const struct io_uring_cqe *cqe)
|
|
281
406
|
{
|
|
282
|
-
unsigned rq_mask = rq_ring.ring_entries - 1;
|
|
283
|
-
struct io_uring_zcrx_cqe *rcqe;
|
|
284
407
|
struct io_uring_zcrx_rqe *rqe;
|
|
408
|
+
unsigned rq_mask;
|
|
409
|
+
|
|
410
|
+
if (rq_nr_queued(rq_ring) == rq_ring->ring_entries) {
|
|
411
|
+
printf("refill queue is full, drop the buffer\n");
|
|
412
|
+
return;
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
rq_mask = rq_ring->ring_entries - 1;
|
|
416
|
+
/* processed, return back to the kernel */
|
|
417
|
+
rqe = &rq_ring->rqes[rq_ring->rq_tail & rq_mask];
|
|
418
|
+
fill_rqe(cqe, rqe);
|
|
419
|
+
io_uring_smp_store_release(rq_ring->ktail, ++rq_ring->rq_tail);
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
static void process_recvzc_error(struct io_uring *ring,
|
|
423
|
+
struct zc_conn *conn, int ret)
|
|
424
|
+
{
|
|
425
|
+
if (ret == -ENOSPC) {
|
|
426
|
+
size_t left = 0;
|
|
427
|
+
|
|
428
|
+
if (cfg_size) {
|
|
429
|
+
left = cfg_size - conn->received;
|
|
430
|
+
if (left == 0)
|
|
431
|
+
t_error(1, 0, "ENOSPC for a finished request");
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
add_recvzc(ring, conn, left);
|
|
435
|
+
return;
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
if (ret != 0)
|
|
439
|
+
t_error(1, 0, "invalid final recvzc ret %i", ret);
|
|
440
|
+
if (cfg_size && conn->received != cfg_size)
|
|
441
|
+
t_error(1, 0, "total receive size mismatch %lu / %lu",
|
|
442
|
+
conn->received, cfg_size);
|
|
443
|
+
|
|
444
|
+
printf("Connection terminated: received %lu, cqes %i, nr requeues %i\n",
|
|
445
|
+
conn->received,
|
|
446
|
+
conn->stat_nr_cqes,
|
|
447
|
+
conn->stat_nr_reqs - 1);
|
|
448
|
+
|
|
449
|
+
close(conn->sockfd);
|
|
450
|
+
free(conn);
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
static void process_recvzc(struct io_uring *ring,
|
|
454
|
+
struct io_uring_cqe *cqe)
|
|
455
|
+
{
|
|
456
|
+
struct zc_conn *conn = get_connection(cqe->user_data);
|
|
457
|
+
const struct io_uring_zcrx_cqe *rcqe;
|
|
285
458
|
uint64_t mask;
|
|
286
|
-
|
|
459
|
+
__u8 *data;
|
|
460
|
+
|
|
461
|
+
conn->stat_nr_cqes++;
|
|
287
462
|
|
|
288
463
|
if (!(cqe->flags & IORING_CQE_F_MORE)) {
|
|
289
|
-
|
|
290
|
-
t_error(1, 0, "invalid final recvzc ret %i", cqe->res);
|
|
291
|
-
if (received != cfg_size)
|
|
292
|
-
t_error(1, 0, "total receive size mismatch %lu / %lu",
|
|
293
|
-
received, cfg_size);
|
|
294
|
-
stop = true;
|
|
464
|
+
process_recvzc_error(ring, conn, cqe->res);
|
|
295
465
|
return;
|
|
296
466
|
}
|
|
297
467
|
if (cqe->res < 0)
|
|
@@ -299,24 +469,22 @@ static void process_recvzc(struct io_uring __attribute__((unused)) *ring,
|
|
|
299
469
|
|
|
300
470
|
rcqe = (struct io_uring_zcrx_cqe *)(cqe + 1);
|
|
301
471
|
mask = (1ULL << IORING_ZCRX_AREA_SHIFT) - 1;
|
|
302
|
-
data = (
|
|
472
|
+
data = (__u8 *)area_ptr + (rcqe->off & mask);
|
|
303
473
|
|
|
304
|
-
verify_data(data, cqe->res, received);
|
|
305
|
-
received += cqe->res;
|
|
306
|
-
|
|
307
|
-
/* processed, return back to the kernel */
|
|
308
|
-
rqe = &rq_ring.rqes[rq_ring.rq_tail & rq_mask];
|
|
309
|
-
rqe->off = (rcqe->off & ~IORING_ZCRX_AREA_MASK) | area_token;
|
|
310
|
-
rqe->len = cqe->res;
|
|
311
|
-
io_uring_smp_store_release(rq_ring.ktail, ++rq_ring.rq_tail);
|
|
474
|
+
verify_data(data, cqe->res, conn->received);
|
|
475
|
+
conn->received += cqe->res;
|
|
476
|
+
return_buffer(&rq_ring, cqe);
|
|
312
477
|
}
|
|
313
478
|
|
|
314
479
|
static void server_loop(struct io_uring *ring)
|
|
315
480
|
{
|
|
316
481
|
struct io_uring_cqe *cqe;
|
|
317
482
|
unsigned int head, count = 0;
|
|
483
|
+
int ret;
|
|
318
484
|
|
|
319
|
-
io_uring_submit_and_wait(ring, 1);
|
|
485
|
+
ret = io_uring_submit_and_wait(ring, 1);
|
|
486
|
+
if (ret < 0 && ret != -ETIME)
|
|
487
|
+
t_error(1, ret, "io_uring_submit_and_wait failed\n");
|
|
320
488
|
|
|
321
489
|
io_uring_for_each_cqe(ring, head, cqe) {
|
|
322
490
|
switch (cqe->user_data & REQ_TYPE_MASK) {
|
|
@@ -336,41 +504,46 @@ static void server_loop(struct io_uring *ring)
|
|
|
336
504
|
|
|
337
505
|
static void run_server(void)
|
|
338
506
|
{
|
|
339
|
-
|
|
507
|
+
struct io_uring_params p;
|
|
340
508
|
struct io_uring ring;
|
|
341
|
-
int
|
|
509
|
+
int enable, ret;
|
|
342
510
|
|
|
343
|
-
|
|
344
|
-
if (
|
|
511
|
+
listen_fd = socket(AF_INET6, SOCK_STREAM, 0);
|
|
512
|
+
if (listen_fd == -1)
|
|
345
513
|
t_error(1, 0, "socket()");
|
|
346
514
|
|
|
347
515
|
enable = 1;
|
|
348
|
-
ret = setsockopt(
|
|
516
|
+
ret = setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int));
|
|
349
517
|
if (ret < 0)
|
|
350
518
|
t_error(1, 0, "setsockopt(SO_REUSEADDR)");
|
|
351
519
|
|
|
352
|
-
ret = bind(
|
|
520
|
+
ret = bind(listen_fd, (struct sockaddr *)&cfg_addr, sizeof(cfg_addr));
|
|
353
521
|
if (ret < 0)
|
|
354
522
|
t_error(1, 0, "bind()");
|
|
355
523
|
|
|
356
|
-
if (listen(
|
|
524
|
+
if (listen(listen_fd, 1024) < 0)
|
|
357
525
|
t_error(1, 0, "listen()");
|
|
358
526
|
|
|
359
|
-
|
|
360
|
-
flags |=
|
|
361
|
-
flags |=
|
|
362
|
-
flags |=
|
|
363
|
-
flags |=
|
|
527
|
+
memset(&p, 0, sizeof(p));
|
|
528
|
+
p.flags |= IORING_SETUP_COOP_TASKRUN;
|
|
529
|
+
p.flags |= IORING_SETUP_SINGLE_ISSUER;
|
|
530
|
+
p.flags |= IORING_SETUP_DEFER_TASKRUN;
|
|
531
|
+
p.flags |= IORING_SETUP_SUBMIT_ALL;
|
|
532
|
+
p.flags |= IORING_SETUP_CQE32;
|
|
533
|
+
p.flags |= IORING_SETUP_CQSIZE;
|
|
534
|
+
p.cq_entries = cfg_cq_entries;
|
|
364
535
|
|
|
365
|
-
ret =
|
|
536
|
+
ret = io_uring_queue_init_params(8, &ring, &p);
|
|
366
537
|
if (ret)
|
|
367
538
|
t_error(1, ret, "ring init failed");
|
|
368
539
|
|
|
369
540
|
setup_zcrx(&ring);
|
|
370
|
-
add_accept(&ring,
|
|
541
|
+
add_accept(&ring, listen_fd);
|
|
371
542
|
|
|
372
543
|
while (!stop)
|
|
373
544
|
server_loop(&ring);
|
|
545
|
+
|
|
546
|
+
close(listen_fd);
|
|
374
547
|
}
|
|
375
548
|
|
|
376
549
|
static void usage(const char *filepath)
|
|
@@ -386,7 +559,7 @@ static void parse_opts(int argc, char **argv)
|
|
|
386
559
|
if (argc <= 1)
|
|
387
560
|
usage(argv[0]);
|
|
388
561
|
|
|
389
|
-
while ((c = getopt(argc, argv, "vp:i:q:s:r:A:")) != -1) {
|
|
562
|
+
while ((c = getopt(argc, argv, "vp:i:q:s:r:A:S:C:R:c:")) != -1) {
|
|
390
563
|
switch (c) {
|
|
391
564
|
case 'p':
|
|
392
565
|
cfg_port = strtoul(optarg, NULL, 0);
|
|
@@ -408,14 +581,32 @@ static void parse_opts(int argc, char **argv)
|
|
|
408
581
|
if (cfg_rq_alloc_mode >= __RQ_ALLOC_MAX)
|
|
409
582
|
t_error(1, 0, "invalid RQ allocation mode");
|
|
410
583
|
break;
|
|
584
|
+
case 'S':
|
|
585
|
+
cfg_area_size = strtoul(optarg, NULL, 0);
|
|
586
|
+
break;
|
|
411
587
|
case 'A':
|
|
412
588
|
cfg_area_type = strtoul(optarg, NULL, 0);
|
|
413
589
|
if (cfg_area_type >= __AREA_TYPE_MAX)
|
|
414
590
|
t_error(1, 0, "Invalid area type");
|
|
415
591
|
break;
|
|
592
|
+
case 'C':
|
|
593
|
+
cfg_cq_entries = strtoul(optarg, NULL, 0);
|
|
594
|
+
break;
|
|
595
|
+
case 'R':
|
|
596
|
+
cfg_rq_entries = strtoul(optarg, NULL, 0);
|
|
597
|
+
break;
|
|
598
|
+
case 'c':
|
|
599
|
+
cfg_affinity_mode = strtoul(optarg, NULL, 0);
|
|
600
|
+
if (cfg_affinity_mode >= __AFFINITY_MODE_MAX)
|
|
601
|
+
t_error(1, 0, "Invalid affinity mode");
|
|
416
602
|
}
|
|
417
603
|
}
|
|
418
604
|
|
|
605
|
+
if (!cfg_ifname)
|
|
606
|
+
t_error(1, -EINVAL, "Interface is not specified");
|
|
607
|
+
if (cfg_queue_id == -1)
|
|
608
|
+
t_error(1, -EINVAL, "Queue idx is not specified");
|
|
609
|
+
|
|
419
610
|
memset(addr6, 0, sizeof(*addr6));
|
|
420
611
|
addr6->sin6_family = AF_INET6;
|
|
421
612
|
addr6->sin6_port = htons(cfg_port);
|
|
@@ -233,6 +233,18 @@ enum io_uring_sqe_flags_bit {
|
|
|
233
233
|
*/
|
|
234
234
|
#define IORING_SETUP_SQE_MIXED (1U << 19)
|
|
235
235
|
|
|
236
|
+
/*
|
|
237
|
+
* When set, io_uring ignores SQ head and tail and fetches SQEs to submit
|
|
238
|
+
* starting from index 0 instead from the index stored in the head pointer.
|
|
239
|
+
* IOW, the user should place all SQE at the beginning of the SQ memory
|
|
240
|
+
* before issuing a submission syscall.
|
|
241
|
+
*
|
|
242
|
+
* It requires IORING_SETUP_NO_SQARRAY and is incompatible with
|
|
243
|
+
* IORING_SETUP_SQPOLL. The user must also never change the SQ head and tail
|
|
244
|
+
* values and keep it set to 0. Any other value is undefined behaviour.
|
|
245
|
+
*/
|
|
246
|
+
#define IORING_SETUP_SQ_REWIND (1U << 20)
|
|
247
|
+
|
|
236
248
|
enum io_uring_op {
|
|
237
249
|
IORING_OP_NOP,
|
|
238
250
|
IORING_OP_READV,
|