uringmachine 0.15 → 0.18

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.
Files changed (261) hide show
  1. checksums.yaml +4 -4
  2. data/.github/FUNDING.yml +3 -0
  3. data/.gitmodules +4 -0
  4. data/CHANGELOG.md +12 -0
  5. data/TODO.md +12 -3
  6. data/examples/bm_send.rb +86 -0
  7. data/ext/um/um.c +28 -1
  8. data/ext/um/um.h +3 -0
  9. data/ext/um/um_class.c +17 -0
  10. data/ext/um/um_stream_class.c +0 -1
  11. data/ext/um/um_utils.c +38 -15
  12. data/lib/uringmachine/version.rb +1 -1
  13. data/lib/uringmachine.rb +4 -3
  14. data/test/test_um.rb +76 -0
  15. data/vendor/libressl/.github/scripts/changelog.sh +74 -0
  16. data/vendor/libressl/.github/workflows/android.yml +35 -0
  17. data/vendor/libressl/.github/workflows/cifuzz.yml +33 -0
  18. data/vendor/libressl/.github/workflows/cmake-config.yml +98 -0
  19. data/vendor/libressl/.github/workflows/coverity.yml +69 -0
  20. data/vendor/libressl/.github/workflows/emscripten.yml +71 -0
  21. data/vendor/libressl/.github/workflows/fedora-rawhide.yml +39 -0
  22. data/vendor/libressl/.github/workflows/freebsd.yml +71 -0
  23. data/vendor/libressl/.github/workflows/linux.yml +71 -0
  24. data/vendor/libressl/.github/workflows/macos.yml +37 -0
  25. data/vendor/libressl/.github/workflows/release.yml +81 -0
  26. data/vendor/libressl/.github/workflows/rust-openssl.yml +47 -0
  27. data/vendor/libressl/.github/workflows/solaris.yml +37 -0
  28. data/vendor/libressl/.github/workflows/windows.yml +70 -0
  29. data/vendor/libressl/.gitignore +333 -0
  30. data/vendor/libressl/CMakeLists.txt +581 -0
  31. data/vendor/libressl/COPYING +133 -0
  32. data/vendor/libressl/ChangeLog +3280 -0
  33. data/vendor/libressl/FindLibreSSL.cmake +232 -0
  34. data/vendor/libressl/LibreSSLConfig.cmake.in +36 -0
  35. data/vendor/libressl/Makefile.am +60 -0
  36. data/vendor/libressl/Makefile.am.common +20 -0
  37. data/vendor/libressl/OPENBSD_BRANCH +1 -0
  38. data/vendor/libressl/README.md +238 -0
  39. data/vendor/libressl/README.mingw.md +43 -0
  40. data/vendor/libressl/apps/CMakeLists.txt +18 -0
  41. data/vendor/libressl/apps/Makefile.am +5 -0
  42. data/vendor/libressl/apps/nc/CMakeLists.txt +67 -0
  43. data/vendor/libressl/apps/nc/Makefile.am +64 -0
  44. data/vendor/libressl/apps/nc/compat/accept4.c +17 -0
  45. data/vendor/libressl/apps/nc/compat/readpassphrase.c +205 -0
  46. data/vendor/libressl/apps/nc/compat/socket.c +29 -0
  47. data/vendor/libressl/apps/nc/compat/sys/socket.h +30 -0
  48. data/vendor/libressl/apps/ocspcheck/CMakeLists.txt +44 -0
  49. data/vendor/libressl/apps/ocspcheck/Makefile.am +45 -0
  50. data/vendor/libressl/apps/ocspcheck/compat/.gitignore +0 -0
  51. data/vendor/libressl/apps/openssl/CMakeLists.txt +97 -0
  52. data/vendor/libressl/apps/openssl/Makefile.am +108 -0
  53. data/vendor/libressl/apps/openssl/apps_win.c +138 -0
  54. data/vendor/libressl/apps/openssl/certhash_win.c +13 -0
  55. data/vendor/libressl/apps/openssl/compat/clock_gettime_osx.c +26 -0
  56. data/vendor/libressl/apps/openssl/compat/poll_win.c +329 -0
  57. data/vendor/libressl/appveyor.yml +53 -0
  58. data/vendor/libressl/autogen.sh +15 -0
  59. data/vendor/libressl/check-release.sh +86 -0
  60. data/vendor/libressl/cmake_export_symbol.cmake +71 -0
  61. data/vendor/libressl/cmake_uninstall.cmake.in +36 -0
  62. data/vendor/libressl/config +17 -0
  63. data/vendor/libressl/configure.ac +165 -0
  64. data/vendor/libressl/crypto/CMakeLists.txt +863 -0
  65. data/vendor/libressl/crypto/Makefile.am +962 -0
  66. data/vendor/libressl/crypto/Makefile.am.arc4random +46 -0
  67. data/vendor/libressl/crypto/Makefile.am.elf-mips +14 -0
  68. data/vendor/libressl/crypto/Makefile.am.elf-mips64 +14 -0
  69. data/vendor/libressl/crypto/Makefile.am.elf-x86_64 +35 -0
  70. data/vendor/libressl/crypto/Makefile.am.macosx-x86_64 +35 -0
  71. data/vendor/libressl/crypto/Makefile.am.masm-x86_64 +22 -0
  72. data/vendor/libressl/crypto/Makefile.am.mingw64-x86_64 +23 -0
  73. data/vendor/libressl/crypto/arch/aarch64/crypto_cpu_caps_darwin.c +60 -0
  74. data/vendor/libressl/crypto/arch/aarch64/crypto_cpu_caps_linux.c +62 -0
  75. data/vendor/libressl/crypto/arch/aarch64/crypto_cpu_caps_none.c +26 -0
  76. data/vendor/libressl/crypto/arch/aarch64/crypto_cpu_caps_windows.c +36 -0
  77. data/vendor/libressl/crypto/arch/loongarch64/crypto_arch.h +21 -0
  78. data/vendor/libressl/crypto/arch/mips/crypto_arch.h +21 -0
  79. data/vendor/libressl/crypto/bn/arch/loongarch64/bn_arch.h +23 -0
  80. data/vendor/libressl/crypto/bn/arch/mips/bn_arch.h +24 -0
  81. data/vendor/libressl/crypto/compat/.gitignore +31 -0
  82. data/vendor/libressl/crypto/compat/arc4random.h +41 -0
  83. data/vendor/libressl/crypto/compat/b_win.c +55 -0
  84. data/vendor/libressl/crypto/compat/bsd-asprintf.c +96 -0
  85. data/vendor/libressl/crypto/compat/crypto_lock_win.c +56 -0
  86. data/vendor/libressl/crypto/compat/explicit_bzero_win.c +13 -0
  87. data/vendor/libressl/crypto/compat/freezero.c +32 -0
  88. data/vendor/libressl/crypto/compat/getdelim.c +78 -0
  89. data/vendor/libressl/crypto/compat/getline.c +40 -0
  90. data/vendor/libressl/crypto/compat/getopt_long.c +528 -0
  91. data/vendor/libressl/crypto/compat/getpagesize.c +18 -0
  92. data/vendor/libressl/crypto/compat/getprogname_linux.c +23 -0
  93. data/vendor/libressl/crypto/compat/getprogname_unimpl.c +7 -0
  94. data/vendor/libressl/crypto/compat/getprogname_windows.c +13 -0
  95. data/vendor/libressl/crypto/compat/posix_win.c +296 -0
  96. data/vendor/libressl/crypto/compat/syslog_r.c +19 -0
  97. data/vendor/libressl/crypto/compat/ui_openssl_win.c +334 -0
  98. data/vendor/libressl/dist.sh +22 -0
  99. data/vendor/libressl/gen-coverage-report.sh +58 -0
  100. data/vendor/libressl/gen-openbsd-tags.sh +20 -0
  101. data/vendor/libressl/include/CMakeLists.txt +61 -0
  102. data/vendor/libressl/include/Makefile.am +79 -0
  103. data/vendor/libressl/include/arch/loongarch64/opensslconf.h +150 -0
  104. data/vendor/libressl/include/arch/mips/opensslconf.h +150 -0
  105. data/vendor/libressl/include/compat/arpa/inet.h +15 -0
  106. data/vendor/libressl/include/compat/arpa/nameser.h +25 -0
  107. data/vendor/libressl/include/compat/cet.h +19 -0
  108. data/vendor/libressl/include/compat/dirent.h +17 -0
  109. data/vendor/libressl/include/compat/dirent_msvc.h +611 -0
  110. data/vendor/libressl/include/compat/endian.h +161 -0
  111. data/vendor/libressl/include/compat/err.h +95 -0
  112. data/vendor/libressl/include/compat/fcntl.h +32 -0
  113. data/vendor/libressl/include/compat/getopt.h +50 -0
  114. data/vendor/libressl/include/compat/limits.h +25 -0
  115. data/vendor/libressl/include/compat/netdb.h +10 -0
  116. data/vendor/libressl/include/compat/netinet/in.h +19 -0
  117. data/vendor/libressl/include/compat/netinet/ip.h +49 -0
  118. data/vendor/libressl/include/compat/netinet/tcp.h +10 -0
  119. data/vendor/libressl/include/compat/poll.h +63 -0
  120. data/vendor/libressl/include/compat/pthread.h +122 -0
  121. data/vendor/libressl/include/compat/readpassphrase.h +44 -0
  122. data/vendor/libressl/include/compat/resolv.h +24 -0
  123. data/vendor/libressl/include/compat/stdint.h +31 -0
  124. data/vendor/libressl/include/compat/stdio.h +65 -0
  125. data/vendor/libressl/include/compat/stdlib.h +57 -0
  126. data/vendor/libressl/include/compat/string.h +98 -0
  127. data/vendor/libressl/include/compat/sys/_null.h +18 -0
  128. data/vendor/libressl/include/compat/sys/ioctl.h +11 -0
  129. data/vendor/libressl/include/compat/sys/mman.h +19 -0
  130. data/vendor/libressl/include/compat/sys/param.h +15 -0
  131. data/vendor/libressl/include/compat/sys/queue.h +536 -0
  132. data/vendor/libressl/include/compat/sys/select.h +10 -0
  133. data/vendor/libressl/include/compat/sys/socket.h +18 -0
  134. data/vendor/libressl/include/compat/sys/stat.h +129 -0
  135. data/vendor/libressl/include/compat/sys/time.h +37 -0
  136. data/vendor/libressl/include/compat/sys/tree.h +1006 -0
  137. data/vendor/libressl/include/compat/sys/types.h +69 -0
  138. data/vendor/libressl/include/compat/sys/uio.h +17 -0
  139. data/vendor/libressl/include/compat/syslog.h +38 -0
  140. data/vendor/libressl/include/compat/time.h +59 -0
  141. data/vendor/libressl/include/compat/unistd.h +83 -0
  142. data/vendor/libressl/include/compat/win32netcompat.h +57 -0
  143. data/vendor/libressl/include/openssl/Makefile.am.tpl +45 -0
  144. data/vendor/libressl/libcrypto.pc.in +28 -0
  145. data/vendor/libressl/libressl.pub +2 -0
  146. data/vendor/libressl/libssl.pc.in +28 -0
  147. data/vendor/libressl/libtls.pc.in +28 -0
  148. data/vendor/libressl/m4/ax_add_fortify_source.m4 +80 -0
  149. data/vendor/libressl/m4/ax_check_compile_flag.m4 +53 -0
  150. data/vendor/libressl/m4/check-hardening-options.m4 +110 -0
  151. data/vendor/libressl/m4/check-libc.m4 +189 -0
  152. data/vendor/libressl/m4/check-os-options.m4 +181 -0
  153. data/vendor/libressl/m4/disable-compiler-warnings.m4 +44 -0
  154. data/vendor/libressl/man/CMakeLists.txt +26 -0
  155. data/vendor/libressl/man/links +2780 -0
  156. data/vendor/libressl/man/update_links.sh +25 -0
  157. data/vendor/libressl/openssl.pc.in +11 -0
  158. data/vendor/libressl/patches/bn_shift.patch +34 -0
  159. data/vendor/libressl/patches/crypto_arch.h.patch +34 -0
  160. data/vendor/libressl/patches/crypto_namespace.h.patch +22 -0
  161. data/vendor/libressl/patches/netcat.c.patch +178 -0
  162. data/vendor/libressl/patches/openssl.c.patch +12 -0
  163. data/vendor/libressl/patches/opensslfeatures.h.patch +49 -0
  164. data/vendor/libressl/patches/patch-amd64-crypto-cpu-caps.c.patch +20 -0
  165. data/vendor/libressl/patches/patch-i386-crypto-cpu-caps.c.patch +20 -0
  166. data/vendor/libressl/patches/speed.c.patch +114 -0
  167. data/vendor/libressl/patches/ssl_namespace.h.patch +21 -0
  168. data/vendor/libressl/patches/tls.h.patch +16 -0
  169. data/vendor/libressl/patches/tls_config.c.patch +15 -0
  170. data/vendor/libressl/patches/win32_amd64_bn_arch.h.patch +28 -0
  171. data/vendor/libressl/patches/windows_headers.patch +80 -0
  172. data/vendor/libressl/scripts/config.guess +1774 -0
  173. data/vendor/libressl/scripts/config.sub +1907 -0
  174. data/vendor/libressl/scripts/i686-w64-mingw32.cmake +9 -0
  175. data/vendor/libressl/scripts/test +210 -0
  176. data/vendor/libressl/scripts/wrap-compiler-for-flag-check +31 -0
  177. data/vendor/libressl/scripts/x86_64-w64-mingw32.cmake +9 -0
  178. data/vendor/libressl/ssl/CMakeLists.txt +183 -0
  179. data/vendor/libressl/ssl/Makefile.am +187 -0
  180. data/vendor/libressl/tests/CMakeLists.txt +970 -0
  181. data/vendor/libressl/tests/Makefile.am +944 -0
  182. data/vendor/libressl/tests/aeadtest.sh +30 -0
  183. data/vendor/libressl/tests/arc4randomforktest.sh +21 -0
  184. data/vendor/libressl/tests/asn1time_small.test +10 -0
  185. data/vendor/libressl/tests/cmake/CMakeLists.txt +52 -0
  186. data/vendor/libressl/tests/cmake/crypto.c +7 -0
  187. data/vendor/libressl/tests/cmake/ssl.c +6 -0
  188. data/vendor/libressl/tests/cmake/tls.c +6 -0
  189. data/vendor/libressl/tests/compat/pipe2.c +186 -0
  190. data/vendor/libressl/tests/dtlstest.sh +28 -0
  191. data/vendor/libressl/tests/evptest.sh +22 -0
  192. data/vendor/libressl/tests/keypairtest.sh +27 -0
  193. data/vendor/libressl/tests/mlkem_tests.sh +39 -0
  194. data/vendor/libressl/tests/ocsptest.bat +25 -0
  195. data/vendor/libressl/tests/ocsptest.sh +23 -0
  196. data/vendor/libressl/tests/openssl.cnf +29 -0
  197. data/vendor/libressl/tests/optionstest.c +381 -0
  198. data/vendor/libressl/tests/pidwraptest.c +85 -0
  199. data/vendor/libressl/tests/pidwraptest.sh +26 -0
  200. data/vendor/libressl/tests/quictest.bat +27 -0
  201. data/vendor/libressl/tests/quictest.sh +30 -0
  202. data/vendor/libressl/tests/renegotiation_test.bat +27 -0
  203. data/vendor/libressl/tests/renegotiation_test.sh +30 -0
  204. data/vendor/libressl/tests/rfc5280time_small.test +10 -0
  205. data/vendor/libressl/tests/servertest.bat +27 -0
  206. data/vendor/libressl/tests/servertest.sh +30 -0
  207. data/vendor/libressl/tests/shutdowntest.bat +27 -0
  208. data/vendor/libressl/tests/shutdowntest.sh +30 -0
  209. data/vendor/libressl/tests/ssltest.bat +32 -0
  210. data/vendor/libressl/tests/ssltest.sh +48 -0
  211. data/vendor/libressl/tests/testdsa.bat +47 -0
  212. data/vendor/libressl/tests/testdsa.sh +57 -0
  213. data/vendor/libressl/tests/testenc.bat +85 -0
  214. data/vendor/libressl/tests/testenc.sh +93 -0
  215. data/vendor/libressl/tests/testrsa.bat +47 -0
  216. data/vendor/libressl/tests/testrsa.sh +57 -0
  217. data/vendor/libressl/tests/testssl.bat +171 -0
  218. data/vendor/libressl/tests/tlstest.bat +27 -0
  219. data/vendor/libressl/tests/tlstest.sh +28 -0
  220. data/vendor/libressl/tls/CMakeLists.txt +125 -0
  221. data/vendor/libressl/tls/Makefile.am +76 -0
  222. data/vendor/libressl/tls/compat/ftruncate.c +17 -0
  223. data/vendor/libressl/tls/compat/pread.c +29 -0
  224. data/vendor/libressl/tls/compat/pwrite.c +29 -0
  225. data/vendor/libressl/update.sh +460 -0
  226. data/vendor/liburing/.github/workflows/ci.yml +8 -0
  227. data/vendor/liburing/configure +23 -2
  228. data/vendor/liburing/examples/helpers.c +1 -1
  229. data/vendor/liburing/examples/helpers.h +1 -1
  230. data/vendor/liburing/examples/reg-wait.c +3 -3
  231. data/vendor/liburing/examples/zcrx.c +5 -5
  232. data/vendor/liburing/liburing.spec +1 -1
  233. data/vendor/liburing/src/include/liburing/io_uring.h +16 -0
  234. data/vendor/liburing/src/include/liburing.h +20 -4
  235. data/vendor/liburing/src/lib.h +2 -4
  236. data/vendor/liburing/src/liburing-ffi.map +7 -0
  237. data/vendor/liburing/src/liburing.map +7 -0
  238. data/vendor/liburing/src/register.c +5 -0
  239. data/vendor/liburing/src/sanitize.c +5 -4
  240. data/vendor/liburing/src/setup.c +43 -28
  241. data/vendor/liburing/test/Makefile +7 -0
  242. data/vendor/liburing/test/cmd-discard.c +2 -2
  243. data/vendor/liburing/test/evfd-short-read.c +84 -0
  244. data/vendor/liburing/test/fdinfo-sqpoll.c +117 -0
  245. data/vendor/liburing/test/fdinfo.c +1 -1
  246. data/vendor/liburing/test/fixed-buf-merge.c +2 -2
  247. data/vendor/liburing/test/futex-kill.c +135 -0
  248. data/vendor/liburing/test/helpers.c +1 -1
  249. data/vendor/liburing/test/helpers.h +1 -1
  250. data/vendor/liburing/test/init-mem.c +50 -12
  251. data/vendor/liburing/test/io_uring_passthrough.c +25 -6
  252. data/vendor/liburing/test/msg-ring.c +123 -9
  253. data/vendor/liburing/test/recv-bundle-short-ooo.c +16 -1
  254. data/vendor/liburing/test/recv-inc-ooo.c +411 -0
  255. data/vendor/liburing/test/recv-mshot-fair.c +513 -0
  256. data/vendor/liburing/test/reg-wait.c +14 -14
  257. data/vendor/liburing/test/send-zerocopy.c +4 -4
  258. data/vendor/liburing/test/timerfd-short-read.c +81 -0
  259. data/vendor/liburing/test/timestamp.c +382 -0
  260. data/vendor/liburing/test/zcrx.c +22 -22
  261. metadata +222 -2
@@ -0,0 +1,513 @@
1
+ /* SPDX-License-Identifier: MIT */
2
+ /*
3
+ * Test that fairness exists between multiple streams, and that setting
4
+ * optlen is honored in terms of terminating a multishot request when
5
+ * a certain byte limit is reached.
6
+ */
7
+ #include <errno.h>
8
+ #include <stdio.h>
9
+ #include <stdlib.h>
10
+ #include <string.h>
11
+ #include <unistd.h>
12
+ #include <limits.h>
13
+ #include <arpa/inet.h>
14
+ #include <sys/types.h>
15
+ #include <sys/socket.h>
16
+ #include <pthread.h>
17
+
18
+ #include "liburing.h"
19
+ #include "helpers.h"
20
+
21
+ #define RECV_BIDS 2048
22
+ #define RECV_BID_MASK (RECV_BIDS - 1)
23
+ #define RECV_BGID 8
24
+ #define RECV_BID_SZ 32
25
+
26
+ #define PORT 10210
27
+ #define HOST "127.0.0.1"
28
+
29
+ #define NR_RDS 4
30
+
31
+ static bool no_limit_support;
32
+
33
+ static int use_port = PORT;
34
+
35
+ struct recv_data {
36
+ pthread_barrier_t connect;
37
+ pthread_barrier_t startup;
38
+ pthread_barrier_t barrier;
39
+
40
+ struct io_uring_buf_ring *br;
41
+
42
+ int recv_bytes;
43
+ int accept_fd;
44
+ unsigned int max_sends;
45
+ unsigned int queue_flags;
46
+
47
+ int bytes_since_arm;
48
+ int total_bytes;
49
+
50
+ int recv_bundle;
51
+
52
+ int use_port;
53
+ int id;
54
+
55
+ int mshot_too_big;
56
+ int unfair;
57
+ };
58
+
59
+ #define PER_ITER_LIMIT 1024
60
+ #define PER_MSHOT_LIMIT 4096
61
+
62
+ static void arm_recv(struct io_uring *ring, struct recv_data *rd)
63
+ {
64
+ struct io_uring_sqe *sqe;
65
+ int len = PER_ITER_LIMIT;
66
+
67
+ if (rd->total_bytes && rd->bytes_since_arm > PER_MSHOT_LIMIT)
68
+ rd->mshot_too_big++;
69
+
70
+ rd->bytes_since_arm = 0;
71
+ sqe = io_uring_get_sqe(ring);
72
+ io_uring_prep_recv_multishot(sqe, rd->accept_fd, NULL, len, 0);
73
+ sqe->optlen = PER_MSHOT_LIMIT;
74
+ if (rd->recv_bundle)
75
+ sqe->ioprio |= IORING_RECVSEND_BUNDLE;
76
+ sqe->buf_group = RECV_BGID;
77
+ sqe->flags |= IOSQE_BUFFER_SELECT;
78
+ io_uring_sqe_set_data(sqe, rd);
79
+ }
80
+
81
+ static int recv_prep(struct io_uring *ring, struct recv_data *rd, int *sock)
82
+ {
83
+ struct sockaddr_in saddr;
84
+ int sockfd, ret, val, use_fd;
85
+ socklen_t socklen;
86
+
87
+ memset(&saddr, 0, sizeof(saddr));
88
+ saddr.sin_family = AF_INET;
89
+ saddr.sin_addr.s_addr = htonl(INADDR_ANY);
90
+ saddr.sin_port = htons(rd->use_port);
91
+
92
+ sockfd = socket(AF_INET, SOCK_STREAM, 0);
93
+ if (sockfd < 0) {
94
+ perror("socket");
95
+ return 1;
96
+ }
97
+
98
+ val = 1;
99
+ setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
100
+
101
+ ret = bind(sockfd, (struct sockaddr *)&saddr, sizeof(saddr));
102
+ if (ret < 0) {
103
+ perror("bind");
104
+ goto err;
105
+ }
106
+
107
+ ret = listen(sockfd, 1);
108
+ if (ret < 0) {
109
+ perror("listen");
110
+ goto err;
111
+ }
112
+
113
+ pthread_barrier_wait(&rd->connect);
114
+
115
+ socklen = sizeof(saddr);
116
+ use_fd = accept(sockfd, (struct sockaddr *)&saddr, &socklen);
117
+ if (use_fd < 0) {
118
+ perror("accept");
119
+ goto err;
120
+ }
121
+
122
+ rd->accept_fd = use_fd;
123
+ pthread_barrier_wait(&rd->startup);
124
+ pthread_barrier_wait(&rd->barrier);
125
+
126
+ rd->recv_bytes = rd->max_sends * 4096;
127
+ arm_recv(ring, rd);
128
+ *sock = sockfd;
129
+ return 0;
130
+ err:
131
+ close(sockfd);
132
+ return 1;
133
+ }
134
+
135
+ struct iter {
136
+ int last_res;
137
+ int last_id;
138
+ int count;
139
+ };
140
+
141
+ static void iter_done(struct recv_data *rd, struct iter *iter)
142
+ {
143
+ if (!iter->count)
144
+ return;
145
+ iter->count = 0;
146
+ }
147
+
148
+ static struct recv_data *last_rd;
149
+ static int bytes_since_last;
150
+
151
+ static int recv_get_cqe(struct io_uring *ring,
152
+ struct io_uring_cqe **cqe, struct iter *iter)
153
+ {
154
+ struct __kernel_timespec ts = { .tv_sec = 0, .tv_nsec = 100000000LL };
155
+ int ret;
156
+
157
+ do {
158
+ ret = io_uring_submit_and_wait_timeout(ring, cqe, 1, &ts, NULL);
159
+ if (!ret) {
160
+ struct recv_data *rd = io_uring_cqe_get_data(*cqe);
161
+
162
+ if (last_rd != rd) {
163
+ if (last_rd) {
164
+ int diff = bytes_since_last - PER_ITER_LIMIT;
165
+
166
+ if (bytes_since_last > PER_ITER_LIMIT &&
167
+ diff > RECV_BID_SZ)
168
+ rd->unfair++;
169
+ }
170
+ last_rd = rd;
171
+ bytes_since_last = 0;
172
+ }
173
+ if ((*cqe)->res == iter->last_res && rd->id == iter->last_id) {
174
+ iter->count++;
175
+ } else {
176
+ iter_done(rd, iter);
177
+ }
178
+ iter->last_res = (*cqe)->res;
179
+ bytes_since_last += (*cqe)->res;
180
+ iter->last_id = rd->id;
181
+ return 0;
182
+ }
183
+ if (ret == -ETIME)
184
+ continue;
185
+ fprintf(stderr, "wait recv: %d\n", ret);
186
+ break;
187
+ } while (1);
188
+
189
+ return 1;
190
+ }
191
+
192
+ static int do_recv(struct io_uring *ring)
193
+ {
194
+ struct iter iter = { .last_res = -4096, };
195
+ struct io_uring_cqe *cqe;
196
+ struct recv_data *rd;
197
+ int ret = 1;
198
+ int done = 0;
199
+
200
+ last_rd = NULL;
201
+ bytes_since_last = 0;
202
+ do {
203
+ if (recv_get_cqe(ring, &cqe, &iter))
204
+ break;
205
+ rd = io_uring_cqe_get_data(cqe);
206
+ if (cqe->res == -EINVAL) {
207
+ fprintf(stdout, "recv not supported, skipping\n");
208
+ return 0;
209
+ }
210
+ if (cqe->res < 0) {
211
+ fprintf(stderr, "failed recv cqe: %d\n", cqe->res);
212
+ goto err;
213
+ }
214
+ if (cqe->res && !(cqe->flags & IORING_CQE_F_BUFFER)) {
215
+ fprintf(stderr, "no buffer set in recv\n");
216
+ goto err;
217
+ }
218
+ rd->recv_bytes -= cqe->res;
219
+ rd->bytes_since_arm += cqe->res;
220
+ rd->total_bytes += cqe->res;
221
+ if (!cqe->res || !rd->recv_bytes) {
222
+ io_uring_cqe_seen(ring, cqe);
223
+ done++;
224
+ continue;
225
+ }
226
+ io_uring_cqe_seen(ring, cqe);
227
+ if (!(cqe->flags & IORING_CQE_F_MORE) && rd->recv_bytes)
228
+ arm_recv(ring, rd);
229
+ } while (done < NR_RDS);
230
+
231
+ ret = 0;
232
+ iter_done(rd, &iter);
233
+ err:
234
+ return ret;
235
+ }
236
+
237
+ static void *recv_fn(void *data)
238
+ {
239
+ struct recv_data *rds = data;
240
+ struct io_uring_params p = { };
241
+ struct io_uring_buf_ring *br = NULL;
242
+ struct io_uring ring;
243
+ unsigned int buf_len;
244
+ void *buf, *ptr;
245
+ int ret, sock[NR_RDS], i;
246
+ int brflags, ring_setup = 0;
247
+
248
+ for (i = 0; i < NR_RDS; i++) {
249
+ sock[i] = -1;
250
+ rds[i].accept_fd = -1;
251
+ }
252
+
253
+ p.cq_entries = 4096;
254
+ p.flags = rds[0].queue_flags | IORING_SETUP_CQSIZE;
255
+ ret = io_uring_queue_init_params(16, &ring, &p);
256
+ if (ret) {
257
+ if (ret == -EINVAL) {
258
+ no_limit_support = true;
259
+ goto skip;
260
+ }
261
+ fprintf(stderr, "ring init: %d\n", ret);
262
+ goto err;
263
+ }
264
+
265
+ ring_setup = 1;
266
+ if (posix_memalign(&buf, 4096, NR_RDS * rds[0].max_sends * 4096))
267
+ goto err;
268
+
269
+ brflags = 0;
270
+ br = io_uring_setup_buf_ring(&ring, RECV_BIDS, RECV_BGID, brflags, &ret);
271
+ if (!br) {
272
+ if (ret == -EINVAL) {
273
+ no_limit_support = true;
274
+ goto skip;
275
+ }
276
+ fprintf(stderr, "failed setting up recv ring %d\n", ret);
277
+ goto err;
278
+ }
279
+
280
+ ptr = buf;
281
+ buf_len = RECV_BID_SZ;
282
+ for (i = 0; i < RECV_BIDS; i++) {
283
+ io_uring_buf_ring_add(br, ptr, buf_len, i, RECV_BID_MASK, i);
284
+ ptr += buf_len;
285
+ }
286
+ io_uring_buf_ring_advance(br, RECV_BIDS);
287
+
288
+ for (i = 0; i < NR_RDS; i++) {
289
+ ret = recv_prep(&ring, &rds[i], &sock[i]);
290
+ if (ret) {
291
+ fprintf(stderr, "recv_prep failed: %d\n", ret);
292
+ goto err;
293
+ }
294
+ }
295
+
296
+ ret = io_uring_submit(&ring);
297
+ if (ret != NR_RDS) {
298
+ struct io_uring_cqe *cqe;
299
+
300
+ if (!io_uring_peek_cqe(&ring, &cqe)) {
301
+ if (cqe->res == -EINVAL) {
302
+ no_limit_support = true;
303
+ goto skip;
304
+ }
305
+ }
306
+ fprintf(stderr, "submit failed: %d\n", ret);
307
+ goto err;
308
+ }
309
+
310
+ ret = do_recv(&ring);
311
+ skip:
312
+ for (i = 0; i < NR_RDS; i++) {
313
+ if (sock[i] != -1)
314
+ close(sock[i]);
315
+ if (rds[i].accept_fd != -1)
316
+ close(rds[i].accept_fd);
317
+ }
318
+ if (br)
319
+ io_uring_free_buf_ring(&ring, br, RECV_BIDS, RECV_BGID);
320
+ if (ring_setup)
321
+ io_uring_queue_exit(&ring);
322
+ err:
323
+ return (void *)(intptr_t)ret;
324
+ }
325
+
326
+ static int do_send(struct recv_data *rd)
327
+ {
328
+ struct sockaddr_in saddr = { };
329
+ int sockfd, ret, i;
330
+ void *buf;
331
+
332
+ buf = malloc(4096);
333
+ memset(buf, 0xa5, 4096);
334
+
335
+ saddr.sin_family = AF_INET;
336
+ saddr.sin_port = htons(rd->use_port);
337
+ inet_pton(AF_INET, HOST, &saddr.sin_addr);
338
+
339
+ sockfd = socket(AF_INET, SOCK_STREAM, 0);
340
+ if (sockfd < 0) {
341
+ perror("socket");
342
+ goto err2;
343
+ }
344
+
345
+ pthread_barrier_wait(&rd->connect);
346
+
347
+ ret = connect(sockfd, (struct sockaddr *)&saddr, sizeof(saddr));
348
+ if (ret < 0) {
349
+ perror("connect");
350
+ goto err;
351
+ }
352
+
353
+ pthread_barrier_wait(&rd->startup);
354
+
355
+ for (i = 0; i < rd->max_sends; i++) {
356
+ ret = send(sockfd, buf, 4096, 0);
357
+ if (ret < 0) {
358
+ perror("send");
359
+ return 1;
360
+ } else if (ret != 4096) {
361
+ printf("short send\n");
362
+ goto err;
363
+ }
364
+ }
365
+
366
+ pthread_barrier_wait(&rd->barrier);
367
+ close(sockfd);
368
+ free(buf);
369
+ return 0;
370
+ err:
371
+ close(sockfd);
372
+ err2:
373
+ free(buf);
374
+ return 1;
375
+ }
376
+
377
+ struct res {
378
+ int mshot_too_big;
379
+ int unfair;
380
+ };
381
+
382
+ static int test(int nr_send, int bundle, unsigned int queue_flags, struct res *r)
383
+ {
384
+ struct recv_data rds[NR_RDS] = { };
385
+ pthread_t recv_thread;
386
+ int ret, i;
387
+ void *retval;
388
+
389
+ memset(r, 0, sizeof(*r));
390
+
391
+ for (i = 0; i < NR_RDS; i++) {
392
+ struct recv_data *rd = &rds[i];
393
+
394
+ rd->use_port = ++use_port;
395
+
396
+ pthread_barrier_init(&rd->connect, NULL, 2);
397
+ pthread_barrier_init(&rd->startup, NULL, 2);
398
+ pthread_barrier_init(&rd->barrier, NULL, 2);
399
+
400
+ rd->queue_flags = queue_flags;
401
+ rd->max_sends = nr_send;
402
+ rd->recv_bundle = bundle;
403
+ rd->recv_bytes = nr_send * 4096;
404
+ rd->id = i + 1;
405
+ }
406
+
407
+ ret = pthread_create(&recv_thread, NULL, recv_fn, rds);
408
+ if (ret) {
409
+ fprintf(stderr, "Thread create failed: %d\n", ret);
410
+ return 1;
411
+ }
412
+
413
+ for (i = 0; i < NR_RDS; i++) {
414
+ struct recv_data *rd = &rds[i];
415
+
416
+ ret = do_send(rd);
417
+ if (ret)
418
+ return ret;
419
+ }
420
+
421
+ pthread_join(recv_thread, &retval);
422
+
423
+ for (i = 0; i < NR_RDS; i++) {
424
+ struct recv_data *rd = &rds[i];
425
+
426
+ r->mshot_too_big += rd->mshot_too_big;
427
+ r->unfair += rd->unfair;
428
+ }
429
+
430
+ return (intptr_t) retval;
431
+ }
432
+
433
+ static int run_tests(void)
434
+ {
435
+ struct res r;
436
+ int ret;
437
+
438
+ ret = test(2, 1, IORING_SETUP_DEFER_TASKRUN | IORING_SETUP_SINGLE_ISSUER, &r);
439
+ if (ret) {
440
+ if (no_limit_support)
441
+ return T_EXIT_SKIP;
442
+ fprintf(stderr, "test DEFER bundle failed\n");
443
+ return T_EXIT_FAIL;
444
+ }
445
+
446
+ /* DEFER_TASKRUN should be fully fair and not have overshoots */
447
+ if (r.unfair || r.mshot_too_big) {
448
+ fprintf(stderr, "DEFER bundle unfair=%d, too_big=%d\n", r.unfair, r.mshot_too_big);
449
+ return T_EXIT_FAIL;
450
+ }
451
+
452
+ ret = test(2, 0, IORING_SETUP_DEFER_TASKRUN | IORING_SETUP_SINGLE_ISSUER, &r);
453
+ if (ret) {
454
+ fprintf(stderr, "test DEFER failed\n");
455
+ return T_EXIT_FAIL;
456
+ }
457
+
458
+ /* DEFER_TASKRUN should be fully fair and not have overshoots */
459
+ if (r.unfair || r.mshot_too_big) {
460
+ fprintf(stderr, "DEFER unfair=%d, too_big=%d\n", r.unfair, r.mshot_too_big);
461
+ return T_EXIT_FAIL;
462
+ }
463
+
464
+ ret = test(2, 1, IORING_SETUP_COOP_TASKRUN, &r);
465
+ if (ret) {
466
+ fprintf(stderr, "test COOP bundle failed\n");
467
+ return T_EXIT_FAIL;
468
+ }
469
+
470
+ /*
471
+ * normal task_work should not have overshoots, but may not be fair
472
+ * because of the re-arming.
473
+ */
474
+ if (r.unfair)
475
+ fprintf(stdout, "!DEFER bundle unfair, expected\n");
476
+ if (r.mshot_too_big) {
477
+ fprintf(stderr, "!DEFER bundle too_big=%d\n", r.mshot_too_big);
478
+ return T_EXIT_FAIL;
479
+ }
480
+
481
+ ret = test(2, 0, IORING_SETUP_COOP_TASKRUN, &r);
482
+ if (ret) {
483
+ fprintf(stderr, "test COOP failed\n");
484
+ return T_EXIT_FAIL;
485
+ }
486
+
487
+ /*
488
+ * normal task_work should not have overshoots, but may not be fair
489
+ * because of the re-arming.
490
+ */
491
+ if (r.unfair)
492
+ fprintf(stdout, "!DEFER unfair, expected\n");
493
+ if (r.mshot_too_big) {
494
+ fprintf(stderr, "!DEFER too_big=%d\n", r.mshot_too_big);
495
+ return T_EXIT_FAIL;
496
+ }
497
+
498
+ return T_EXIT_PASS;
499
+ }
500
+
501
+ int main(int argc, char *argv[])
502
+ {
503
+ int ret;
504
+
505
+ if (argc > 1)
506
+ return T_EXIT_SKIP;
507
+
508
+ ret = run_tests();
509
+ if (ret != T_EXIT_PASS)
510
+ return ret;
511
+
512
+ return T_EXIT_PASS;
513
+ }
@@ -213,16 +213,16 @@ static int test_wait_arg(void)
213
213
  return T_EXIT_FAIL;
214
214
  }
215
215
 
216
- buffer = aligned_alloc(page_size, page_size * 4);
216
+ buffer = t_aligned_alloc(page_size, page_size * 4);
217
217
  if (!buffer) {
218
218
  fprintf(stderr, "allocation failed\n");
219
219
  return T_EXIT_FAIL;
220
220
  }
221
221
 
222
- rd.user_addr = (__u64)(unsigned long)buffer;
222
+ rd.user_addr = uring_ptr_to_u64(buffer);
223
223
  rd.size = page_size;
224
224
  rd.flags = IORING_MEM_REGION_TYPE_USER;
225
- mr.region_uptr = (__u64)(unsigned long)&rd;
225
+ mr.region_uptr = uring_ptr_to_u64(&rd);
226
226
  mr.flags = IORING_MEM_REGION_REG_WAIT_ARG;
227
227
 
228
228
  ret = io_uring_register_region(&ring, &mr);
@@ -281,17 +281,17 @@ static int test_regions(void)
281
281
  void *buffer;
282
282
  int ret;
283
283
 
284
- buffer = aligned_alloc(page_size, page_size * 4);
284
+ buffer = t_aligned_alloc(page_size, page_size * 4);
285
285
  if (!buffer) {
286
286
  fprintf(stderr, "allocation failed\n");
287
287
  return T_EXIT_FAIL;
288
288
  }
289
289
 
290
- rd.user_addr = (__u64)(unsigned long)buffer;
290
+ rd.user_addr = uring_ptr_to_u64(buffer);
291
291
  rd.size = page_size;
292
292
  rd.flags = IORING_MEM_REGION_TYPE_USER;
293
293
 
294
- mr.region_uptr = (__u64)(unsigned long)&rd;
294
+ mr.region_uptr = uring_ptr_to_u64(&rd);
295
295
  mr.flags = IORING_MEM_REGION_REG_WAIT_ARG;
296
296
 
297
297
  ret = test_try_register_region(&mr, true);
@@ -324,7 +324,7 @@ static int test_regions(void)
324
324
  fprintf(stderr, "test_try_register_region() null uptr fail %i\n", ret);
325
325
  return T_EXIT_FAIL;
326
326
  }
327
- rd.user_addr = (__u64)(unsigned long)buffer;
327
+ rd.user_addr = uring_ptr_to_u64(buffer);
328
328
 
329
329
  rd.flags = 0;
330
330
  ret = test_try_register_region(&mr, true);
@@ -348,7 +348,7 @@ static int test_regions(void)
348
348
  fprintf(stderr, "test_try_register_region() NULL region %i\n", ret);
349
349
  return T_EXIT_FAIL;
350
350
  }
351
- mr.region_uptr = (__u64)(unsigned long)&rd;
351
+ mr.region_uptr = uring_ptr_to_u64(&rd);
352
352
 
353
353
  rd.user_addr += 16;
354
354
  ret = test_try_register_region(&mr, true);
@@ -363,7 +363,7 @@ static int test_regions(void)
363
363
  fprintf(stderr, "test_try_register_region() bogus uptr %i\n", ret);
364
364
  return T_EXIT_FAIL;
365
365
  }
366
- rd.user_addr = (__u64)(unsigned long)buffer;
366
+ rd.user_addr = uring_ptr_to_u64(buffer);
367
367
  free(buffer);
368
368
 
369
369
  buffer = mmap(NULL, page_size, PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
@@ -372,7 +372,7 @@ static int test_regions(void)
372
372
  return 1;
373
373
  }
374
374
 
375
- rd.user_addr = (__u64)(unsigned long)buffer;
375
+ rd.user_addr = uring_ptr_to_u64(buffer);
376
376
  ret = test_try_register_region(&mr, true);
377
377
  if (ret != -EFAULT) {
378
378
  fprintf(stderr, "test_try_register_region() RO uptr %i\n", ret);
@@ -393,7 +393,7 @@ static int test_regions(void)
393
393
 
394
394
  has_kernel_regions = true;
395
395
  rd.flags = 0;
396
- rd.user_addr = (__u64)(unsigned long)buffer;
396
+ rd.user_addr = uring_ptr_to_u64(buffer);
397
397
  ret = test_try_register_region(&mr, true);
398
398
  if (!ret) {
399
399
  fprintf(stderr, "test_try_register_region() failed uptr w kernel alloc %i\n", ret);
@@ -421,7 +421,7 @@ static int t_region_create_kernel(struct t_region *r,
421
421
  {
422
422
  struct io_uring_region_desc rd = { .size = r->size, };
423
423
  struct io_uring_mem_region_reg mr = {
424
- .region_uptr = (__u64)(unsigned long)&rd,
424
+ .region_uptr = uring_ptr_to_u64(&rd),
425
425
  .flags = IORING_MEM_REGION_REG_WAIT_ARG,
426
426
  };
427
427
  void *p;
@@ -458,9 +458,9 @@ static int t_region_create_user(struct t_region *r,
458
458
  if (p == MAP_FAILED)
459
459
  return -ENOMEM;
460
460
 
461
- mr.region_uptr = (__u64)(unsigned long)&rd;
461
+ mr.region_uptr = uring_ptr_to_u64(&rd);
462
462
  mr.flags = IORING_MEM_REGION_REG_WAIT_ARG;
463
- rd.user_addr = (__u64)(unsigned long)p;
463
+ rd.user_addr = uring_ptr_to_u64(p);
464
464
  rd.flags = IORING_MEM_REGION_TYPE_USER;
465
465
  rd.size = r->size;
466
466
 
@@ -842,8 +842,8 @@ int main(int argc, char *argv[])
842
842
 
843
843
  if (try_hugepages) {
844
844
  len = LARGE_BUF_SIZE;
845
- tx_buffer = aligned_alloc(page_sz, len);
846
- rx_buffer = aligned_alloc(page_sz, len);
845
+ tx_buffer = t_aligned_alloc(page_sz, len);
846
+ rx_buffer = t_aligned_alloc(page_sz, len);
847
847
 
848
848
  if (tx_buffer && rx_buffer) {
849
849
  buffers_iov[BUF_T_LARGE].iov_base = tx_buffer;
@@ -856,8 +856,8 @@ int main(int argc, char *argv[])
856
856
 
857
857
  if (!tx_buffer) {
858
858
  len = 2 * page_sz;
859
- tx_buffer = aligned_alloc(page_sz, len);
860
- rx_buffer = aligned_alloc(page_sz, len);
859
+ tx_buffer = t_aligned_alloc(page_sz, len);
860
+ rx_buffer = t_aligned_alloc(page_sz, len);
861
861
 
862
862
  if (!tx_buffer || !rx_buffer) {
863
863
  fprintf(stderr, "can't allocate buffers\n");
@@ -0,0 +1,81 @@
1
+ /* SPDX-License-Identifier: MIT */
2
+ /*
3
+ * Description: Check that trying to read two eventfd events will still
4
+ * return one when generated. There was a kernel commit that
5
+ * all of a sudden pretended that anonymous inodes were
6
+ * regular files, which broke the io_uring short read/write
7
+ * handling logic. See:
8
+ *
9
+ * https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=cfd86ef7e8e7
10
+ */
11
+ #include <errno.h>
12
+ #include <stdio.h>
13
+ #include <unistd.h>
14
+ #include <stdlib.h>
15
+ #include <string.h>
16
+ #include <fcntl.h>
17
+ #include <sys/timerfd.h>
18
+
19
+ #include "liburing.h"
20
+ #include "helpers.h"
21
+
22
+ static void sig_alrm(int sig)
23
+ {
24
+ fprintf(stderr, "Test failed due to timeout\n");
25
+ exit(T_EXIT_FAIL);
26
+ }
27
+
28
+ int main(int argc, char *argv[])
29
+ {
30
+ struct io_uring_params p = {};
31
+ struct sigaction act = { };
32
+ struct io_uring_sqe *sqe;
33
+ struct io_uring_cqe *cqe;
34
+ struct io_uring ring;
35
+ struct itimerspec is = { };
36
+ unsigned long tmp[2];
37
+ int ret, fd;
38
+
39
+ if (argc > 1)
40
+ return T_EXIT_SKIP;
41
+
42
+ ret = io_uring_queue_init_params(8, &ring, &p);
43
+ if (ret) {
44
+ fprintf(stderr, "ring setup failed: %d\n", ret);
45
+ return T_EXIT_FAIL;
46
+ }
47
+
48
+ fd = timerfd_create(CLOCK_MONOTONIC, TFD_CLOEXEC);
49
+ if (fd < 0) {
50
+ perror("timerfd_create");
51
+ return T_EXIT_FAIL;
52
+ }
53
+
54
+ sqe = io_uring_get_sqe(&ring);
55
+ io_uring_prep_read(sqe, fd, tmp, sizeof(tmp), 0);
56
+ sqe->user_data = 1;
57
+
58
+ io_uring_submit(&ring);
59
+
60
+ is.it_value.tv_sec = 0;
61
+ is.it_value.tv_nsec = 10000000;
62
+ ret = timerfd_settime(fd, 0, &is, NULL);
63
+ if (ret < 0) {
64
+ perror("timerfd_settime");
65
+ return T_EXIT_FAIL;
66
+ }
67
+
68
+ act.sa_handler = sig_alrm;
69
+ sigaction(SIGALRM, &act, NULL);
70
+ alarm(1);
71
+
72
+ ret = io_uring_wait_cqe(&ring, &cqe);
73
+ if (ret) {
74
+ fprintf(stderr, "wait: %d\n", ret);
75
+ return T_EXIT_FAIL;
76
+ }
77
+
78
+ close(fd);
79
+ io_uring_cqe_seen(&ring, cqe);
80
+ return T_EXIT_PASS;
81
+ }