uringmachine 0.1

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 (307) hide show
  1. checksums.yaml +7 -0
  2. data/.github/dependabot.yml +12 -0
  3. data/.github/workflows/test.yml +35 -0
  4. data/.gitignore +59 -0
  5. data/.gitmodules +3 -0
  6. data/CHANGELOG.md +7 -0
  7. data/Gemfile +3 -0
  8. data/LICENSE +21 -0
  9. data/README.md +11 -0
  10. data/Rakefile +39 -0
  11. data/TODO.md +0 -0
  12. data/examples/echo_server.rb +52 -0
  13. data/examples/event_loop.rb +69 -0
  14. data/examples/fibers.rb +105 -0
  15. data/examples/http_server.rb +56 -0
  16. data/examples/http_server_multishot.rb +57 -0
  17. data/examples/http_server_simpler.rb +34 -0
  18. data/ext/um/extconf.rb +71 -0
  19. data/ext/um/iou.h +101 -0
  20. data/ext/um/op_ctx.c +138 -0
  21. data/ext/um/ring.c +755 -0
  22. data/ext/um/um.c +267 -0
  23. data/ext/um/um.h +97 -0
  24. data/ext/um/um_class.c +175 -0
  25. data/ext/um/um_ext.c +11 -0
  26. data/ext/um/um_op.c +87 -0
  27. data/ext/um/um_utils.c +23 -0
  28. data/lib/uringmachine/version.rb +3 -0
  29. data/lib/uringmachine.rb +8 -0
  30. data/test/helper.rb +70 -0
  31. data/test/test_iou.rb +876 -0
  32. data/test/test_um.rb +168 -0
  33. data/uringmachine.gemspec +27 -0
  34. data/vendor/liburing/.github/actions/codespell/stopwords +7 -0
  35. data/vendor/liburing/.github/pull_request_template.md +86 -0
  36. data/vendor/liburing/.github/workflows/build.yml +137 -0
  37. data/vendor/liburing/.github/workflows/codespell.yml +25 -0
  38. data/vendor/liburing/.github/workflows/shellcheck.yml +20 -0
  39. data/vendor/liburing/.gitignore +41 -0
  40. data/vendor/liburing/CHANGELOG +111 -0
  41. data/vendor/liburing/CITATION.cff +11 -0
  42. data/vendor/liburing/COPYING +502 -0
  43. data/vendor/liburing/COPYING.GPL +339 -0
  44. data/vendor/liburing/LICENSE +20 -0
  45. data/vendor/liburing/Makefile +96 -0
  46. data/vendor/liburing/Makefile.common +7 -0
  47. data/vendor/liburing/Makefile.quiet +11 -0
  48. data/vendor/liburing/README +106 -0
  49. data/vendor/liburing/SECURITY.md +6 -0
  50. data/vendor/liburing/configure +624 -0
  51. data/vendor/liburing/debian/README.Debian +7 -0
  52. data/vendor/liburing/debian/changelog +38 -0
  53. data/vendor/liburing/debian/control +39 -0
  54. data/vendor/liburing/debian/copyright +49 -0
  55. data/vendor/liburing/debian/liburing-dev.install +4 -0
  56. data/vendor/liburing/debian/liburing-dev.manpages +5 -0
  57. data/vendor/liburing/debian/liburing2.install +1 -0
  58. data/vendor/liburing/debian/liburing2.symbols +56 -0
  59. data/vendor/liburing/debian/patches/series +1 -0
  60. data/vendor/liburing/debian/rules +29 -0
  61. data/vendor/liburing/debian/source/format +1 -0
  62. data/vendor/liburing/debian/source/local-options +2 -0
  63. data/vendor/liburing/debian/source/options +1 -0
  64. data/vendor/liburing/debian/watch +3 -0
  65. data/vendor/liburing/examples/Makefile +53 -0
  66. data/vendor/liburing/examples/helpers.c +62 -0
  67. data/vendor/liburing/examples/helpers.h +7 -0
  68. data/vendor/liburing/examples/io_uring-close-test.c +123 -0
  69. data/vendor/liburing/examples/io_uring-cp.c +282 -0
  70. data/vendor/liburing/examples/io_uring-test.c +112 -0
  71. data/vendor/liburing/examples/io_uring-udp.c +403 -0
  72. data/vendor/liburing/examples/link-cp.c +193 -0
  73. data/vendor/liburing/examples/napi-busy-poll-client.c +509 -0
  74. data/vendor/liburing/examples/napi-busy-poll-server.c +450 -0
  75. data/vendor/liburing/examples/poll-bench.c +101 -0
  76. data/vendor/liburing/examples/proxy.c +2461 -0
  77. data/vendor/liburing/examples/proxy.h +102 -0
  78. data/vendor/liburing/examples/rsrc-update-bench.c +100 -0
  79. data/vendor/liburing/examples/send-zerocopy.c +658 -0
  80. data/vendor/liburing/examples/ucontext-cp.c +258 -0
  81. data/vendor/liburing/liburing-ffi.pc.in +12 -0
  82. data/vendor/liburing/liburing.pc.in +12 -0
  83. data/vendor/liburing/liburing.spec +66 -0
  84. data/vendor/liburing/make-debs.sh +55 -0
  85. data/vendor/liburing/src/Makefile +129 -0
  86. data/vendor/liburing/src/arch/aarch64/lib.h +47 -0
  87. data/vendor/liburing/src/arch/aarch64/syscall.h +91 -0
  88. data/vendor/liburing/src/arch/generic/lib.h +17 -0
  89. data/vendor/liburing/src/arch/generic/syscall.h +100 -0
  90. data/vendor/liburing/src/arch/riscv64/lib.h +48 -0
  91. data/vendor/liburing/src/arch/riscv64/syscall.h +100 -0
  92. data/vendor/liburing/src/arch/syscall-defs.h +94 -0
  93. data/vendor/liburing/src/arch/x86/lib.h +11 -0
  94. data/vendor/liburing/src/arch/x86/syscall.h +296 -0
  95. data/vendor/liburing/src/ffi.c +15 -0
  96. data/vendor/liburing/src/include/liburing/barrier.h +81 -0
  97. data/vendor/liburing/src/include/liburing/io_uring.h +818 -0
  98. data/vendor/liburing/src/include/liburing.h +1602 -0
  99. data/vendor/liburing/src/int_flags.h +11 -0
  100. data/vendor/liburing/src/lib.h +52 -0
  101. data/vendor/liburing/src/liburing-ffi.map +211 -0
  102. data/vendor/liburing/src/liburing.map +104 -0
  103. data/vendor/liburing/src/nolibc.c +55 -0
  104. data/vendor/liburing/src/queue.c +468 -0
  105. data/vendor/liburing/src/register.c +374 -0
  106. data/vendor/liburing/src/setup.c +689 -0
  107. data/vendor/liburing/src/setup.h +9 -0
  108. data/vendor/liburing/src/syscall.c +29 -0
  109. data/vendor/liburing/src/syscall.h +53 -0
  110. data/vendor/liburing/src/version.c +21 -0
  111. data/vendor/liburing/test/232c93d07b74.c +305 -0
  112. data/vendor/liburing/test/35fa71a030ca.c +329 -0
  113. data/vendor/liburing/test/500f9fbadef8.c +91 -0
  114. data/vendor/liburing/test/7ad0e4b2f83c.c +94 -0
  115. data/vendor/liburing/test/8a9973408177.c +107 -0
  116. data/vendor/liburing/test/917257daa0fe.c +54 -0
  117. data/vendor/liburing/test/Makefile +297 -0
  118. data/vendor/liburing/test/a0908ae19763.c +59 -0
  119. data/vendor/liburing/test/a4c0b3decb33.c +181 -0
  120. data/vendor/liburing/test/accept-link.c +255 -0
  121. data/vendor/liburing/test/accept-non-empty.c +256 -0
  122. data/vendor/liburing/test/accept-reuse.c +163 -0
  123. data/vendor/liburing/test/accept-test.c +83 -0
  124. data/vendor/liburing/test/accept.c +919 -0
  125. data/vendor/liburing/test/across-fork.c +284 -0
  126. data/vendor/liburing/test/b19062a56726.c +54 -0
  127. data/vendor/liburing/test/b5837bd5311d.c +78 -0
  128. data/vendor/liburing/test/bind-listen.c +408 -0
  129. data/vendor/liburing/test/buf-ring-nommap.c +123 -0
  130. data/vendor/liburing/test/buf-ring-put.c +83 -0
  131. data/vendor/liburing/test/buf-ring.c +473 -0
  132. data/vendor/liburing/test/ce593a6c480a.c +139 -0
  133. data/vendor/liburing/test/close-opath.c +123 -0
  134. data/vendor/liburing/test/config +14 -0
  135. data/vendor/liburing/test/connect-rep.c +204 -0
  136. data/vendor/liburing/test/connect.c +442 -0
  137. data/vendor/liburing/test/coredump.c +60 -0
  138. data/vendor/liburing/test/cq-full.c +97 -0
  139. data/vendor/liburing/test/cq-overflow.c +530 -0
  140. data/vendor/liburing/test/cq-peek-batch.c +103 -0
  141. data/vendor/liburing/test/cq-ready.c +95 -0
  142. data/vendor/liburing/test/cq-size.c +65 -0
  143. data/vendor/liburing/test/d4ae271dfaae.c +96 -0
  144. data/vendor/liburing/test/d77a67ed5f27.c +65 -0
  145. data/vendor/liburing/test/defer-taskrun.c +391 -0
  146. data/vendor/liburing/test/defer-tw-timeout.c +173 -0
  147. data/vendor/liburing/test/defer.c +319 -0
  148. data/vendor/liburing/test/double-poll-crash.c +195 -0
  149. data/vendor/liburing/test/drop-submit.c +94 -0
  150. data/vendor/liburing/test/eeed8b54e0df.c +120 -0
  151. data/vendor/liburing/test/empty-eownerdead.c +45 -0
  152. data/vendor/liburing/test/eploop.c +74 -0
  153. data/vendor/liburing/test/eventfd-disable.c +179 -0
  154. data/vendor/liburing/test/eventfd-reg.c +77 -0
  155. data/vendor/liburing/test/eventfd-ring.c +98 -0
  156. data/vendor/liburing/test/eventfd.c +113 -0
  157. data/vendor/liburing/test/evloop.c +73 -0
  158. data/vendor/liburing/test/exec-target.c +6 -0
  159. data/vendor/liburing/test/exit-no-cleanup.c +117 -0
  160. data/vendor/liburing/test/fadvise.c +202 -0
  161. data/vendor/liburing/test/fallocate.c +265 -0
  162. data/vendor/liburing/test/fc2a85cb02ef.c +132 -0
  163. data/vendor/liburing/test/fd-install.c +500 -0
  164. data/vendor/liburing/test/fd-pass.c +237 -0
  165. data/vendor/liburing/test/fdinfo.c +419 -0
  166. data/vendor/liburing/test/file-register.c +1189 -0
  167. data/vendor/liburing/test/file-update.c +231 -0
  168. data/vendor/liburing/test/file-verify.c +654 -0
  169. data/vendor/liburing/test/files-exit-hang-poll.c +114 -0
  170. data/vendor/liburing/test/files-exit-hang-timeout.c +137 -0
  171. data/vendor/liburing/test/fixed-buf-iter.c +115 -0
  172. data/vendor/liburing/test/fixed-buf-merge.c +101 -0
  173. data/vendor/liburing/test/fixed-hugepage.c +411 -0
  174. data/vendor/liburing/test/fixed-link.c +90 -0
  175. data/vendor/liburing/test/fixed-reuse.c +160 -0
  176. data/vendor/liburing/test/fpos.c +255 -0
  177. data/vendor/liburing/test/fsnotify.c +118 -0
  178. data/vendor/liburing/test/fsync.c +224 -0
  179. data/vendor/liburing/test/futex.c +571 -0
  180. data/vendor/liburing/test/hardlink.c +170 -0
  181. data/vendor/liburing/test/helpers.c +318 -0
  182. data/vendor/liburing/test/helpers.h +108 -0
  183. data/vendor/liburing/test/ignore-single-mmap.c +48 -0
  184. data/vendor/liburing/test/init-mem.c +164 -0
  185. data/vendor/liburing/test/io-cancel.c +561 -0
  186. data/vendor/liburing/test/io_uring_enter.c +264 -0
  187. data/vendor/liburing/test/io_uring_passthrough.c +482 -0
  188. data/vendor/liburing/test/io_uring_register.c +503 -0
  189. data/vendor/liburing/test/io_uring_setup.c +110 -0
  190. data/vendor/liburing/test/iopoll-leak.c +85 -0
  191. data/vendor/liburing/test/iopoll-overflow.c +118 -0
  192. data/vendor/liburing/test/iopoll.c +465 -0
  193. data/vendor/liburing/test/lfs-openat-write.c +119 -0
  194. data/vendor/liburing/test/lfs-openat.c +273 -0
  195. data/vendor/liburing/test/link-timeout.c +1108 -0
  196. data/vendor/liburing/test/link.c +497 -0
  197. data/vendor/liburing/test/link_drain.c +255 -0
  198. data/vendor/liburing/test/madvise.c +195 -0
  199. data/vendor/liburing/test/min-timeout-wait.c +354 -0
  200. data/vendor/liburing/test/min-timeout.c +233 -0
  201. data/vendor/liburing/test/mkdir.c +112 -0
  202. data/vendor/liburing/test/msg-ring-fd.c +331 -0
  203. data/vendor/liburing/test/msg-ring-flags.c +212 -0
  204. data/vendor/liburing/test/msg-ring-overflow.c +159 -0
  205. data/vendor/liburing/test/msg-ring.c +467 -0
  206. data/vendor/liburing/test/multicqes_drain.c +429 -0
  207. data/vendor/liburing/test/napi-test.c +215 -0
  208. data/vendor/liburing/test/napi-test.sh +48 -0
  209. data/vendor/liburing/test/no-mmap-inval.c +42 -0
  210. data/vendor/liburing/test/nolibc.c +62 -0
  211. data/vendor/liburing/test/nop-all-sizes.c +99 -0
  212. data/vendor/liburing/test/nop.c +177 -0
  213. data/vendor/liburing/test/nvme.h +169 -0
  214. data/vendor/liburing/test/ooo-file-unreg.c +82 -0
  215. data/vendor/liburing/test/open-close.c +261 -0
  216. data/vendor/liburing/test/open-direct-link.c +188 -0
  217. data/vendor/liburing/test/open-direct-pick.c +180 -0
  218. data/vendor/liburing/test/openat2.c +312 -0
  219. data/vendor/liburing/test/personality.c +204 -0
  220. data/vendor/liburing/test/pipe-bug.c +95 -0
  221. data/vendor/liburing/test/pipe-eof.c +83 -0
  222. data/vendor/liburing/test/pipe-reuse.c +105 -0
  223. data/vendor/liburing/test/poll-cancel-all.c +496 -0
  224. data/vendor/liburing/test/poll-cancel-ton.c +135 -0
  225. data/vendor/liburing/test/poll-cancel.c +228 -0
  226. data/vendor/liburing/test/poll-link.c +221 -0
  227. data/vendor/liburing/test/poll-many.c +230 -0
  228. data/vendor/liburing/test/poll-mshot-overflow.c +265 -0
  229. data/vendor/liburing/test/poll-mshot-update.c +323 -0
  230. data/vendor/liburing/test/poll-race-mshot.c +276 -0
  231. data/vendor/liburing/test/poll-race.c +105 -0
  232. data/vendor/liburing/test/poll-ring.c +48 -0
  233. data/vendor/liburing/test/poll-v-poll.c +353 -0
  234. data/vendor/liburing/test/poll.c +327 -0
  235. data/vendor/liburing/test/probe.c +135 -0
  236. data/vendor/liburing/test/read-before-exit.c +129 -0
  237. data/vendor/liburing/test/read-mshot-empty.c +153 -0
  238. data/vendor/liburing/test/read-mshot.c +404 -0
  239. data/vendor/liburing/test/read-write.c +1013 -0
  240. data/vendor/liburing/test/recv-msgall-stream.c +398 -0
  241. data/vendor/liburing/test/recv-msgall.c +263 -0
  242. data/vendor/liburing/test/recv-multishot.c +602 -0
  243. data/vendor/liburing/test/recvsend_bundle.c +691 -0
  244. data/vendor/liburing/test/reg-fd-only.c +131 -0
  245. data/vendor/liburing/test/reg-hint.c +56 -0
  246. data/vendor/liburing/test/reg-reg-ring.c +90 -0
  247. data/vendor/liburing/test/regbuf-merge.c +91 -0
  248. data/vendor/liburing/test/register-restrictions.c +633 -0
  249. data/vendor/liburing/test/rename.c +132 -0
  250. data/vendor/liburing/test/ring-leak.c +283 -0
  251. data/vendor/liburing/test/ring-leak2.c +249 -0
  252. data/vendor/liburing/test/ringbuf-read.c +196 -0
  253. data/vendor/liburing/test/ringbuf-status.c +242 -0
  254. data/vendor/liburing/test/rsrc_tags.c +461 -0
  255. data/vendor/liburing/test/runtests-loop.sh +16 -0
  256. data/vendor/liburing/test/runtests-quiet.sh +11 -0
  257. data/vendor/liburing/test/runtests.sh +168 -0
  258. data/vendor/liburing/test/rw_merge_test.c +98 -0
  259. data/vendor/liburing/test/self.c +91 -0
  260. data/vendor/liburing/test/send-zerocopy.c +971 -0
  261. data/vendor/liburing/test/send_recv.c +412 -0
  262. data/vendor/liburing/test/send_recvmsg.c +444 -0
  263. data/vendor/liburing/test/shared-wq.c +84 -0
  264. data/vendor/liburing/test/short-read.c +75 -0
  265. data/vendor/liburing/test/shutdown.c +165 -0
  266. data/vendor/liburing/test/sigfd-deadlock.c +88 -0
  267. data/vendor/liburing/test/single-issuer.c +169 -0
  268. data/vendor/liburing/test/skip-cqe.c +428 -0
  269. data/vendor/liburing/test/socket-getsetsock-cmd.c +346 -0
  270. data/vendor/liburing/test/socket-io-cmd.c +237 -0
  271. data/vendor/liburing/test/socket-rw-eagain.c +149 -0
  272. data/vendor/liburing/test/socket-rw-offset.c +149 -0
  273. data/vendor/liburing/test/socket-rw.c +137 -0
  274. data/vendor/liburing/test/socket.c +408 -0
  275. data/vendor/liburing/test/splice.c +512 -0
  276. data/vendor/liburing/test/sq-full-cpp.cc +45 -0
  277. data/vendor/liburing/test/sq-full.c +45 -0
  278. data/vendor/liburing/test/sq-poll-dup.c +211 -0
  279. data/vendor/liburing/test/sq-poll-kthread.c +169 -0
  280. data/vendor/liburing/test/sq-poll-share.c +138 -0
  281. data/vendor/liburing/test/sq-space_left.c +159 -0
  282. data/vendor/liburing/test/sqpoll-disable-exit.c +196 -0
  283. data/vendor/liburing/test/sqpoll-exec.c +132 -0
  284. data/vendor/liburing/test/sqpoll-exit-hang.c +78 -0
  285. data/vendor/liburing/test/sqpoll-sleep.c +69 -0
  286. data/vendor/liburing/test/statx.c +172 -0
  287. data/vendor/liburing/test/stdout.c +232 -0
  288. data/vendor/liburing/test/submit-and-wait.c +108 -0
  289. data/vendor/liburing/test/submit-link-fail.c +156 -0
  290. data/vendor/liburing/test/submit-reuse.c +237 -0
  291. data/vendor/liburing/test/symlink.c +117 -0
  292. data/vendor/liburing/test/sync-cancel.c +235 -0
  293. data/vendor/liburing/test/teardowns.c +58 -0
  294. data/vendor/liburing/test/test.h +36 -0
  295. data/vendor/liburing/test/thread-exit.c +143 -0
  296. data/vendor/liburing/test/timeout-new.c +256 -0
  297. data/vendor/liburing/test/timeout.c +1798 -0
  298. data/vendor/liburing/test/truncate.c +186 -0
  299. data/vendor/liburing/test/tty-write-dpoll.c +60 -0
  300. data/vendor/liburing/test/unlink.c +112 -0
  301. data/vendor/liburing/test/version.c +25 -0
  302. data/vendor/liburing/test/wait-timeout.c +287 -0
  303. data/vendor/liburing/test/waitid.c +373 -0
  304. data/vendor/liburing/test/wakeup-hang.c +162 -0
  305. data/vendor/liburing/test/wq-aff.c +146 -0
  306. data/vendor/liburing/test/xattr.c +442 -0
  307. metadata +412 -0
@@ -0,0 +1,211 @@
1
+ /* SPDX-License-Identifier: MIT */
2
+ /*
3
+ * Description: test SQPOLL with IORING_SETUP_ATTACH_WQ and closing of
4
+ * the original ring descriptor.
5
+ */
6
+ #include <errno.h>
7
+ #include <stdio.h>
8
+ #include <unistd.h>
9
+ #include <stdlib.h>
10
+ #include <string.h>
11
+ #include <fcntl.h>
12
+ #include <sys/types.h>
13
+ #include <sys/eventfd.h>
14
+ #include <sys/resource.h>
15
+
16
+ #include "helpers.h"
17
+ #include "liburing.h"
18
+
19
+ #define FILE_SIZE (128 * 1024 * 1024)
20
+ #define BS 4096
21
+ #define BUFFERS 64
22
+
23
+ #define NR_RINGS 4
24
+
25
+ static struct iovec *vecs;
26
+ static struct io_uring rings[NR_RINGS];
27
+
28
+ static int wait_io(struct io_uring *ring, int nr_ios)
29
+ {
30
+ struct io_uring_cqe *cqe;
31
+ int ret;
32
+
33
+ while (nr_ios) {
34
+ ret = io_uring_wait_cqe(ring, &cqe);
35
+ if (ret) {
36
+ fprintf(stderr, "wait_ret=%d\n", ret);
37
+ return 1;
38
+ }
39
+ if (cqe->res != BS) {
40
+ fprintf(stderr, "Unexpected ret %d\n", cqe->res);
41
+ return 1;
42
+ }
43
+ io_uring_cqe_seen(ring, cqe);
44
+ nr_ios--;
45
+ }
46
+
47
+ return 0;
48
+ }
49
+
50
+ static int queue_io(struct io_uring *ring, int fd, int nr_ios)
51
+ {
52
+ unsigned long off;
53
+ int i;
54
+
55
+ i = 0;
56
+ off = 0;
57
+ while (nr_ios) {
58
+ struct io_uring_sqe *sqe;
59
+
60
+ sqe = io_uring_get_sqe(ring);
61
+ if (!sqe)
62
+ break;
63
+ io_uring_prep_read(sqe, fd, vecs[i].iov_base, vecs[i].iov_len, off);
64
+ nr_ios--;
65
+ i++;
66
+ off += BS;
67
+ }
68
+
69
+ io_uring_submit(ring);
70
+ return i;
71
+ }
72
+
73
+ static int do_io(int fd, int ring_start, int ring_end)
74
+ {
75
+ int i, rets[NR_RINGS];
76
+ unsigned ios = 0;
77
+
78
+ while (ios < 32) {
79
+ for (i = ring_start; i < ring_end; i++) {
80
+ int ret = queue_io(&rings[i], fd, BUFFERS);
81
+ if (ret < 0)
82
+ goto err;
83
+ rets[i] = ret;
84
+ }
85
+ for (i = ring_start; i < ring_end; i++) {
86
+ if (wait_io(&rings[i], rets[i]))
87
+ goto err;
88
+ }
89
+ ios += BUFFERS;
90
+ }
91
+
92
+ return 0;
93
+ err:
94
+ return 1;
95
+ }
96
+
97
+ static int test(int fd, int do_dup_and_close, int close_ring)
98
+ {
99
+ int i, ret, ring_fd;
100
+
101
+ for (i = 0; i < NR_RINGS; i++) {
102
+ struct io_uring_params p = { };
103
+
104
+ p.flags = IORING_SETUP_SQPOLL;
105
+ p.sq_thread_idle = 100;
106
+ if (i) {
107
+ p.wq_fd = rings[0].ring_fd;
108
+ p.flags |= IORING_SETUP_ATTACH_WQ;
109
+ }
110
+ ret = io_uring_queue_init_params(BUFFERS, &rings[i], &p);
111
+ if (ret) {
112
+ fprintf(stderr, "queue_init: %d/%d\n", ret, i);
113
+ goto err;
114
+ }
115
+ /* no sharing for non-fixed either */
116
+ if (!(p.features & IORING_FEAT_SQPOLL_NONFIXED)) {
117
+ fprintf(stdout, "No SQPOLL sharing, skipping\n");
118
+ return 0;
119
+ }
120
+ }
121
+
122
+ /* test all rings */
123
+ if (do_io(fd, 0, NR_RINGS))
124
+ goto err;
125
+
126
+ /* dup and close original ring fd */
127
+ ring_fd = dup(rings[0].ring_fd);
128
+ if (close_ring)
129
+ close(rings[0].ring_fd);
130
+ rings[0].ring_fd = rings[0].enter_ring_fd = ring_fd;
131
+ if (do_dup_and_close)
132
+ goto done;
133
+
134
+ /* test all but closed one */
135
+ if (do_io(fd, 1, NR_RINGS))
136
+ goto err;
137
+
138
+ /* test closed one */
139
+ if (do_io(fd, 0, 1))
140
+ goto err;
141
+
142
+ /* make sure thread is idle so we enter the kernel */
143
+ usleep(200000);
144
+
145
+ /* test closed one */
146
+ if (do_io(fd, 0, 1))
147
+ goto err;
148
+
149
+
150
+ done:
151
+ for (i = 0; i < NR_RINGS; i++)
152
+ io_uring_queue_exit(&rings[i]);
153
+
154
+ return 0;
155
+ err:
156
+ return 1;
157
+ }
158
+
159
+ int main(int argc, char *argv[])
160
+ {
161
+ char *fname;
162
+ int ret, fd;
163
+
164
+ if (argc > 1) {
165
+ fname = argv[1];
166
+ } else {
167
+ fname = ".basic-rw-poll-dup";
168
+ t_create_file(fname, FILE_SIZE);
169
+ }
170
+
171
+ vecs = t_create_buffers(BUFFERS, BS);
172
+
173
+ fd = open(fname, O_RDONLY | O_DIRECT);
174
+ if (fd < 0) {
175
+ int __e = errno;
176
+
177
+ if (fname != argv[1])
178
+ unlink(fname);
179
+
180
+ if (__e == EINVAL)
181
+ return T_EXIT_SKIP;
182
+ perror("open");
183
+ return -1;
184
+ }
185
+
186
+ if (fname != argv[1])
187
+ unlink(fname);
188
+
189
+ ret = test(fd, 0, 0);
190
+ if (ret) {
191
+ fprintf(stderr, "test 0 0 failed\n");
192
+ goto err;
193
+ }
194
+
195
+ ret = test(fd, 0, 1);
196
+ if (ret) {
197
+ fprintf(stderr, "test 0 1 failed\n");
198
+ goto err;
199
+ }
200
+
201
+
202
+ ret = test(fd, 1, 0);
203
+ if (ret) {
204
+ fprintf(stderr, "test 1 0 failed\n");
205
+ goto err;
206
+ }
207
+
208
+ return 0;
209
+ err:
210
+ return 1;
211
+ }
@@ -0,0 +1,169 @@
1
+ /* SPDX-License-Identifier: MIT */
2
+ /*
3
+ * Description: test if io_uring SQ poll kthread is stopped when the userspace
4
+ * process ended with or without closing the io_uring fd
5
+ *
6
+ */
7
+ #include <errno.h>
8
+ #include <fcntl.h>
9
+ #include <stdio.h>
10
+ #include <unistd.h>
11
+ #include <pthread.h>
12
+ #include <stdbool.h>
13
+ #include <stdlib.h>
14
+ #include <string.h>
15
+ #include <signal.h>
16
+ #include <poll.h>
17
+ #include <sys/wait.h>
18
+ #include <sys/epoll.h>
19
+
20
+ #include "liburing.h"
21
+ #include "helpers.h"
22
+
23
+ #define SQ_THREAD_IDLE 2000
24
+ #define BUF_SIZE 128
25
+ #define KTHREAD_NAME "io_uring-sq"
26
+
27
+ enum {
28
+ TEST_OK = 0,
29
+ TEST_SKIPPED = 1,
30
+ TEST_FAILED = 2,
31
+ };
32
+
33
+ static int do_test_sq_poll_kthread_stopped(bool do_exit)
34
+ {
35
+ int ret = 0, pipe1[2];
36
+ struct io_uring_params param;
37
+ struct io_uring ring;
38
+ struct io_uring_sqe *sqe;
39
+ struct io_uring_cqe *cqe;
40
+ uint8_t buf[BUF_SIZE];
41
+ struct iovec iov;
42
+
43
+ if (pipe(pipe1) != 0) {
44
+ perror("pipe");
45
+ return TEST_FAILED;
46
+ }
47
+
48
+ memset(&param, 0, sizeof(param));
49
+ param.flags |= IORING_SETUP_SQPOLL;
50
+ param.sq_thread_idle = SQ_THREAD_IDLE;
51
+
52
+ ret = t_create_ring_params(16, &ring, &param);
53
+ if (ret == T_SETUP_SKIP) {
54
+ ret = TEST_FAILED;
55
+ goto err_pipe;
56
+ } else if (ret != T_SETUP_OK) {
57
+ fprintf(stderr, "ring setup failed\n");
58
+ ret = TEST_FAILED;
59
+ goto err_pipe;
60
+ }
61
+
62
+ ret = io_uring_register_files(&ring, &pipe1[1], 1);
63
+ if (ret) {
64
+ fprintf(stderr, "file reg failed: %d\n", ret);
65
+ ret = TEST_FAILED;
66
+ goto err_uring;
67
+ }
68
+
69
+ iov.iov_base = buf;
70
+ iov.iov_len = BUF_SIZE;
71
+
72
+ sqe = io_uring_get_sqe(&ring);
73
+ if (!sqe) {
74
+ fprintf(stderr, "io_uring_get_sqe failed\n");
75
+ ret = TEST_FAILED;
76
+ goto err_uring;
77
+ }
78
+
79
+ io_uring_prep_writev(sqe, 0, &iov, 1, 0);
80
+ sqe->flags |= IOSQE_FIXED_FILE;
81
+
82
+ ret = io_uring_submit(&ring);
83
+ if (ret < 0) {
84
+ fprintf(stderr, "io_uring_submit failed - ret: %d\n",
85
+ ret);
86
+ ret = TEST_FAILED;
87
+ goto err_uring;
88
+ }
89
+
90
+ ret = io_uring_wait_cqe(&ring, &cqe);
91
+ if (ret < 0) {
92
+ fprintf(stderr, "io_uring_wait_cqe - ret: %d\n",
93
+ ret);
94
+ ret = TEST_FAILED;
95
+ goto err_uring;
96
+ }
97
+
98
+ if (cqe->res != BUF_SIZE) {
99
+ fprintf(stderr, "unexpected cqe->res %d [expected %d]\n",
100
+ cqe->res, BUF_SIZE);
101
+ ret = TEST_FAILED;
102
+ goto err_uring;
103
+
104
+ }
105
+
106
+ io_uring_cqe_seen(&ring, cqe);
107
+
108
+ ret = TEST_OK;
109
+
110
+ err_uring:
111
+ if (do_exit)
112
+ io_uring_queue_exit(&ring);
113
+ err_pipe:
114
+ close(pipe1[0]);
115
+ close(pipe1[1]);
116
+
117
+ return ret;
118
+ }
119
+
120
+ static int test_sq_poll_kthread_stopped(bool do_exit)
121
+ {
122
+ pid_t pid;
123
+ int status = 0;
124
+
125
+ pid = fork();
126
+
127
+ if (pid == 0) {
128
+ int ret = do_test_sq_poll_kthread_stopped(do_exit);
129
+ exit(ret);
130
+ }
131
+
132
+ pid = wait(&status);
133
+ if (status != 0)
134
+ return WEXITSTATUS(status);
135
+
136
+ sleep(1);
137
+ if (system("ps --ppid 2 | grep " KTHREAD_NAME) == 0) {
138
+ fprintf(stderr, "%s kthread still running!\n", KTHREAD_NAME);
139
+ return TEST_FAILED;
140
+ }
141
+
142
+ return 0;
143
+ }
144
+
145
+ int main(int argc, char *argv[])
146
+ {
147
+ int ret;
148
+
149
+ if (argc > 1)
150
+ return 0;
151
+
152
+ ret = test_sq_poll_kthread_stopped(true);
153
+ if (ret == TEST_SKIPPED) {
154
+ printf("test_sq_poll_kthread_stopped_exit: skipped\n");
155
+ } else if (ret == TEST_FAILED) {
156
+ fprintf(stderr, "test_sq_poll_kthread_stopped_exit failed\n");
157
+ return ret;
158
+ }
159
+
160
+ ret = test_sq_poll_kthread_stopped(false);
161
+ if (ret == TEST_SKIPPED) {
162
+ printf("test_sq_poll_kthread_stopped_noexit: skipped\n");
163
+ } else if (ret == TEST_FAILED) {
164
+ fprintf(stderr, "test_sq_poll_kthread_stopped_noexit failed\n");
165
+ return ret;
166
+ }
167
+
168
+ return 0;
169
+ }
@@ -0,0 +1,138 @@
1
+ /* SPDX-License-Identifier: MIT */
2
+ /*
3
+ * Description: test SQPOLL with IORING_SETUP_ATTACH_WQ
4
+ */
5
+ #include <errno.h>
6
+ #include <stdio.h>
7
+ #include <unistd.h>
8
+ #include <stdlib.h>
9
+ #include <string.h>
10
+ #include <fcntl.h>
11
+ #include <sys/types.h>
12
+ #include <poll.h>
13
+ #include <sys/eventfd.h>
14
+ #include <sys/resource.h>
15
+
16
+ #include "helpers.h"
17
+ #include "liburing.h"
18
+
19
+ #define FILE_SIZE (128 * 1024 * 1024)
20
+ #define BS 4096
21
+ #define BUFFERS 64
22
+
23
+ #define NR_RINGS 4
24
+
25
+ static struct iovec *vecs;
26
+
27
+ static int wait_io(struct io_uring *ring, int nr_ios)
28
+ {
29
+ struct io_uring_cqe *cqe;
30
+
31
+ while (nr_ios) {
32
+ int ret = io_uring_wait_cqe(ring, &cqe);
33
+
34
+ if (ret == -EAGAIN) {
35
+ continue;
36
+ } else if (ret) {
37
+ fprintf(stderr, "io_uring_wait_cqe failed %i\n", ret);
38
+ return 1;
39
+ }
40
+ if (cqe->res != BS) {
41
+ fprintf(stderr, "Unexpected ret %d\n", cqe->res);
42
+ return 1;
43
+ }
44
+ io_uring_cqe_seen(ring, cqe);
45
+ nr_ios--;
46
+ }
47
+
48
+ return 0;
49
+ }
50
+
51
+ static int queue_io(struct io_uring *ring, int fd, int nr_ios)
52
+ {
53
+ unsigned long off;
54
+ int i;
55
+
56
+ i = 0;
57
+ off = 0;
58
+ while (nr_ios) {
59
+ struct io_uring_sqe *sqe;
60
+
61
+ sqe = io_uring_get_sqe(ring);
62
+ if (!sqe)
63
+ break;
64
+ io_uring_prep_read(sqe, fd, vecs[i].iov_base, vecs[i].iov_len, off);
65
+ nr_ios--;
66
+ i++;
67
+ off += BS;
68
+ }
69
+
70
+ io_uring_submit(ring);
71
+ return i;
72
+ }
73
+
74
+ int main(int argc, char *argv[])
75
+ {
76
+ struct io_uring rings[NR_RINGS];
77
+ int rets[NR_RINGS];
78
+ unsigned long ios;
79
+ int i, ret, fd;
80
+ char *fname;
81
+
82
+ if (argc > 1) {
83
+ fname = argv[1];
84
+ } else {
85
+ fname = ".basic-rw-poll-share";
86
+ t_create_file(fname, FILE_SIZE);
87
+ }
88
+
89
+ vecs = t_create_buffers(BUFFERS, BS);
90
+
91
+ fd = open(fname, O_RDONLY | O_DIRECT);
92
+ if (fd < 0) {
93
+ perror("open");
94
+ return -1;
95
+ }
96
+
97
+ if (fname != argv[1])
98
+ unlink(fname);
99
+
100
+ for (i = 0; i < NR_RINGS; i++) {
101
+ struct io_uring_params p = { };
102
+
103
+ p.flags = IORING_SETUP_SQPOLL;
104
+ if (i) {
105
+ p.wq_fd = rings[0].ring_fd;
106
+ p.flags |= IORING_SETUP_ATTACH_WQ;
107
+ }
108
+ ret = io_uring_queue_init_params(BUFFERS, &rings[i], &p);
109
+ if (ret) {
110
+ fprintf(stderr, "queue_init: %d/%d\n", ret, i);
111
+ goto err;
112
+ }
113
+ /* no sharing for non-fixed either */
114
+ if (!(p.features & IORING_FEAT_SQPOLL_NONFIXED)) {
115
+ fprintf(stdout, "No SQPOLL sharing, skipping\n");
116
+ return 0;
117
+ }
118
+ }
119
+
120
+ ios = 0;
121
+ while (ios < (FILE_SIZE / BS)) {
122
+ for (i = 0; i < NR_RINGS; i++) {
123
+ ret = queue_io(&rings[i], fd, BUFFERS);
124
+ if (ret < 0)
125
+ goto err;
126
+ rets[i] = ret;
127
+ }
128
+ for (i = 0; i < NR_RINGS; i++) {
129
+ if (wait_io(&rings[i], rets[i]))
130
+ goto err;
131
+ }
132
+ ios += BUFFERS;
133
+ }
134
+
135
+ return 0;
136
+ err:
137
+ return 1;
138
+ }
@@ -0,0 +1,159 @@
1
+ /* SPDX-License-Identifier: MIT */
2
+ /*
3
+ * Description: test SQ queue space left
4
+ *
5
+ */
6
+ #include <errno.h>
7
+ #include <stdio.h>
8
+ #include <unistd.h>
9
+ #include <stdlib.h>
10
+ #include <string.h>
11
+ #include <fcntl.h>
12
+
13
+ #include "liburing.h"
14
+
15
+ static int test_left(void)
16
+ {
17
+ struct io_uring_sqe *sqe;
18
+ struct io_uring ring;
19
+ int ret, i = 0, s;
20
+
21
+ ret = io_uring_queue_init(8, &ring, 0);
22
+ if (ret) {
23
+ fprintf(stderr, "ring setup failed: %d\n", ret);
24
+ return 1;
25
+
26
+ }
27
+
28
+ if ((s = io_uring_sq_space_left(&ring)) != 8) {
29
+ fprintf(stderr, "Got %d SQEs left, expected %d\n", s, 8);
30
+ goto err;
31
+ }
32
+
33
+ i = 0;
34
+ while ((sqe = io_uring_get_sqe(&ring)) != NULL) {
35
+ i++;
36
+ if ((s = io_uring_sq_space_left(&ring)) != 8 - i) {
37
+ fprintf(stderr, "Got %d SQEs left, expected %d\n", s, 8 - i);
38
+ goto err;
39
+ }
40
+ }
41
+
42
+ if (i != 8) {
43
+ fprintf(stderr, "Got %d SQEs, expected %d\n", i, 8);
44
+ goto err;
45
+ }
46
+
47
+ io_uring_queue_exit(&ring);
48
+ return 0;
49
+ err:
50
+ io_uring_queue_exit(&ring);
51
+ return 1;
52
+ }
53
+
54
+ static int test_sync(void)
55
+ {
56
+ struct io_uring_sqe *sqe;
57
+ struct io_uring ring;
58
+ int ret, i;
59
+
60
+ ret = io_uring_queue_init(32, &ring, 0);
61
+ if (ret) {
62
+ fprintf(stderr, "ring setup failed: %d\n", ret);
63
+ return 1;
64
+
65
+ }
66
+
67
+ /* prep 8 NOPS */
68
+ for (i = 0; i < 8; i++) {
69
+ sqe = io_uring_get_sqe(&ring);
70
+ if (!sqe) {
71
+ fprintf(stderr, "get sqe failed\n");
72
+ goto err;
73
+ }
74
+ io_uring_prep_nop(sqe);
75
+ }
76
+
77
+ /* prep known bad command, this should terminate submission */
78
+ sqe = io_uring_get_sqe(&ring);
79
+ if (!sqe) {
80
+ fprintf(stderr, "get sqe failed\n");
81
+ goto err;
82
+ }
83
+ io_uring_prep_nop(sqe);
84
+ sqe->opcode = 0xfe;
85
+
86
+ /* prep 8 NOPS */
87
+ for (i = 0; i < 8; i++) {
88
+ sqe = io_uring_get_sqe(&ring);
89
+ if (!sqe) {
90
+ fprintf(stderr, "get sqe failed\n");
91
+ goto err;
92
+ }
93
+ io_uring_prep_nop(sqe);
94
+ }
95
+
96
+ /* we should have 8 + 1 + 8 pending now */
97
+ ret = io_uring_sq_ready(&ring);
98
+ if (ret != 17) {
99
+ fprintf(stderr, "%d ready, wanted 17\n", ret);
100
+ goto err;
101
+ }
102
+
103
+ ret = io_uring_submit(&ring);
104
+
105
+ /* should submit 8 successfully, then error #9 and stop */
106
+ if (ret != 9) {
107
+ fprintf(stderr, "submitted %d, wanted 9\n", ret);
108
+ goto err;
109
+ }
110
+
111
+ /* should now have 8 ready, with 9 gone */
112
+ ret = io_uring_sq_ready(&ring);
113
+ if (ret != 8) {
114
+ fprintf(stderr, "%d ready, wanted 8\n", ret);
115
+ goto err;
116
+ }
117
+
118
+ ret = io_uring_submit(&ring);
119
+
120
+ /* the last 8 should submit fine */
121
+ if (ret != 8) {
122
+ fprintf(stderr, "submitted %d, wanted 8\n", ret);
123
+ goto err;
124
+ }
125
+
126
+ ret = io_uring_sq_ready(&ring);
127
+ if (ret) {
128
+ fprintf(stderr, "%d ready, wanted 0\n", ret);
129
+ goto err;
130
+ }
131
+
132
+ io_uring_queue_exit(&ring);
133
+ return 0;
134
+ err:
135
+ io_uring_queue_exit(&ring);
136
+ return 1;
137
+ }
138
+
139
+ int main(int argc, char *argv[])
140
+ {
141
+ int ret;
142
+
143
+ if (argc > 1)
144
+ return 0;
145
+
146
+ ret = test_left();
147
+ if (ret) {
148
+ fprintf(stderr, "test_left failed\n");
149
+ return ret;
150
+ }
151
+
152
+ ret = test_sync();
153
+ if (ret) {
154
+ fprintf(stderr, "test_sync failed\n");
155
+ return ret;
156
+ }
157
+
158
+ return 0;
159
+ }