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,173 @@
1
+ /* SPDX-License-Identifier: MIT */
2
+ /*
3
+ * Description: test waiting for more events than what will be posted with
4
+ * a timeout with DEFER_TASKRUN. All kernels should time out,
5
+ * but a non-buggy kernel will end up with one CQE available
6
+ * for reaping. Buggy kernels will not have processed the
7
+ * task_work and will have 0 events.
8
+ *
9
+ */
10
+ #include <errno.h>
11
+ #include <stdio.h>
12
+ #include <unistd.h>
13
+ #include <stdlib.h>
14
+ #include <string.h>
15
+ #include <pthread.h>
16
+
17
+ #include "liburing.h"
18
+ #include "helpers.h"
19
+
20
+ struct d {
21
+ int fd;
22
+ };
23
+
24
+ static void *thread_fn(void *data)
25
+ {
26
+ struct d *d = data;
27
+ int ret;
28
+
29
+ usleep(100000);
30
+ ret = write(d->fd, "Hello", 5);
31
+ if (ret < 0)
32
+ perror("write");
33
+ return NULL;
34
+ }
35
+
36
+ static int test_poll(struct io_uring *ring)
37
+ {
38
+ struct io_uring_cqe *cqe;
39
+ struct io_uring_sqe *sqe;
40
+ struct __kernel_timespec ts;
41
+ int ret, fds[2], i;
42
+ pthread_t thread;
43
+ char buf[32];
44
+ struct d d;
45
+ void *tret;
46
+
47
+ if (pipe(fds) < 0) {
48
+ perror("pipe");
49
+ return 1;
50
+ }
51
+ d.fd = fds[1];
52
+
53
+ sqe = io_uring_get_sqe(ring);
54
+ io_uring_prep_read(sqe, fds[0], buf, sizeof(buf), 0);
55
+
56
+ pthread_create(&thread, NULL, thread_fn, &d);
57
+
58
+ ts.tv_sec = 1;
59
+ ts.tv_nsec = 0;
60
+
61
+ ret = io_uring_submit_and_wait_timeout(ring, &cqe, 2, &ts, NULL);
62
+ if (ret != 1) {
63
+ fprintf(stderr, "unexpected wait ret %d\n", ret);
64
+ return T_EXIT_FAIL;
65
+ }
66
+
67
+ for (i = 0; i < 2; i++) {
68
+ ret = io_uring_peek_cqe(ring, &cqe);
69
+ if (ret)
70
+ break;
71
+ io_uring_cqe_seen(ring, cqe);
72
+ }
73
+
74
+ if (i != 1) {
75
+ fprintf(stderr, "Got %d request, expected 1\n", i);
76
+ return T_EXIT_FAIL;
77
+ }
78
+
79
+ pthread_join(thread, &tret);
80
+ return T_EXIT_PASS;
81
+ }
82
+
83
+ static int test_file(struct io_uring *ring, char *__fname)
84
+ {
85
+ struct io_uring_cqe *cqe;
86
+ struct io_uring_sqe *sqe;
87
+ struct __kernel_timespec ts;
88
+ char filename[64], *fname;
89
+ int fd, ret, i;
90
+ void *buf;
91
+
92
+ if (!__fname) {
93
+ fname = filename;
94
+ sprintf(fname, ".defer-tw-timeout.%d", getpid());
95
+ t_create_file(fname, 128*1024);
96
+ } else {
97
+ fname = __fname;
98
+ }
99
+
100
+ fd = open(fname, O_RDONLY | O_DIRECT);
101
+ if (fd < 0) {
102
+ if (errno == EINVAL) {
103
+ if (!__fname)
104
+ unlink(fname);
105
+ return T_EXIT_SKIP;
106
+ }
107
+ perror("open");
108
+ if (!__fname)
109
+ unlink(fname);
110
+ return T_EXIT_FAIL;
111
+ }
112
+
113
+ if (!__fname)
114
+ unlink(fname);
115
+
116
+ if (posix_memalign(&buf, 4096, 4096)) {
117
+ close(fd);
118
+ return T_EXIT_FAIL;
119
+ }
120
+
121
+ sqe = io_uring_get_sqe(ring);
122
+ io_uring_prep_read(sqe, fd, buf, 4096, 0);
123
+
124
+ ts.tv_sec = 1;
125
+ ts.tv_nsec = 0;
126
+
127
+ ret = io_uring_submit_and_wait_timeout(ring, &cqe, 2, &ts, NULL);
128
+ if (ret != 1) {
129
+ fprintf(stderr, "unexpected wait ret %d\n", ret);
130
+ close(fd);
131
+ return T_EXIT_FAIL;
132
+ }
133
+
134
+ for (i = 0; i < 2; i++) {
135
+ ret = io_uring_peek_cqe(ring, &cqe);
136
+ if (ret)
137
+ break;
138
+ io_uring_cqe_seen(ring, cqe);
139
+ }
140
+
141
+ if (i != 1) {
142
+ fprintf(stderr, "Got %d request, expected 1\n", i);
143
+ close(fd);
144
+ return T_EXIT_FAIL;
145
+ }
146
+
147
+ close(fd);
148
+ return T_EXIT_PASS;
149
+ }
150
+
151
+ int main(int argc, char *argv[])
152
+ {
153
+ struct io_uring ring;
154
+ char *fname = NULL;
155
+ int ret;
156
+
157
+ ret = io_uring_queue_init(8, &ring, IORING_SETUP_SINGLE_ISSUER | IORING_SETUP_DEFER_TASKRUN);
158
+ if (ret == -EINVAL)
159
+ return T_EXIT_SKIP;
160
+
161
+ if (argc > 1)
162
+ fname = argv[1];
163
+
164
+ ret = test_file(&ring, fname);
165
+ if (ret != T_EXIT_PASS)
166
+ return ret;
167
+
168
+ ret = test_poll(&ring);
169
+ if (ret != T_EXIT_PASS)
170
+ return ret;
171
+
172
+ return T_EXIT_PASS;
173
+ }
@@ -0,0 +1,319 @@
1
+ /* SPDX-License-Identifier: MIT */
2
+ #include <errno.h>
3
+ #include <stdio.h>
4
+ #include <unistd.h>
5
+ #include <stdlib.h>
6
+ #include <string.h>
7
+ #include <fcntl.h>
8
+ #include <sys/uio.h>
9
+ #include <stdbool.h>
10
+
11
+ #include "helpers.h"
12
+ #include "liburing.h"
13
+
14
+ #define RING_SIZE 128
15
+ enum {
16
+ OP_NOP,
17
+ OP_REMOVE_BUFFERS
18
+ };
19
+
20
+ struct test_context {
21
+ struct io_uring *ring;
22
+ struct io_uring_sqe **sqes;
23
+ struct io_uring_cqe *cqes;
24
+ int nr;
25
+ };
26
+
27
+ static void free_context(struct test_context *ctx)
28
+ {
29
+ free(ctx->sqes);
30
+ free(ctx->cqes);
31
+ memset(ctx, 0, sizeof(*ctx));
32
+ }
33
+
34
+ static int init_context(struct test_context *ctx, struct io_uring *ring, int nr,
35
+ int op)
36
+ {
37
+ struct io_uring_sqe *sqe;
38
+ int i;
39
+
40
+ memset(ctx, 0, sizeof(*ctx));
41
+ ctx->nr = nr;
42
+ ctx->ring = ring;
43
+ ctx->sqes = t_malloc(nr * sizeof(*ctx->sqes));
44
+ ctx->cqes = t_malloc(nr * sizeof(*ctx->cqes));
45
+
46
+ if (!ctx->sqes || !ctx->cqes)
47
+ goto err;
48
+
49
+ for (i = 0; i < nr; i++) {
50
+ sqe = io_uring_get_sqe(ring);
51
+ if (!sqe)
52
+ goto err;
53
+ switch (op) {
54
+ case OP_NOP:
55
+ io_uring_prep_nop(sqe);
56
+ break;
57
+ case OP_REMOVE_BUFFERS:
58
+ io_uring_prep_remove_buffers(sqe, 10, 1);
59
+ break;
60
+ }
61
+ sqe->user_data = i;
62
+ ctx->sqes[i] = sqe;
63
+ }
64
+
65
+ return 0;
66
+ err:
67
+ free_context(ctx);
68
+ printf("init context failed\n");
69
+ return 1;
70
+ }
71
+
72
+ static int wait_cqes(struct test_context *ctx)
73
+ {
74
+ int ret, i;
75
+ struct io_uring_cqe *cqe;
76
+
77
+ for (i = 0; i < ctx->nr; i++) {
78
+ ret = io_uring_wait_cqe(ctx->ring, &cqe);
79
+
80
+ if (ret < 0) {
81
+ printf("wait_cqes: wait completion %d\n", ret);
82
+ return 1;
83
+ }
84
+ memcpy(&ctx->cqes[i], cqe, sizeof(*cqe));
85
+ io_uring_cqe_seen(ctx->ring, cqe);
86
+ }
87
+
88
+ return 0;
89
+ }
90
+
91
+ static int test_canceled_userdata(struct io_uring *ring)
92
+ {
93
+ struct test_context ctx;
94
+ int ret, i, nr = 100;
95
+
96
+ if (init_context(&ctx, ring, nr, OP_NOP))
97
+ return 1;
98
+
99
+ for (i = 0; i < nr; i++)
100
+ ctx.sqes[i]->flags |= IOSQE_IO_LINK;
101
+
102
+ ret = io_uring_submit(ring);
103
+ if (ret <= 0) {
104
+ printf("sqe submit failed: %d\n", ret);
105
+ goto err;
106
+ }
107
+
108
+ if (wait_cqes(&ctx))
109
+ goto err;
110
+
111
+ for (i = 0; i < nr; i++) {
112
+ if (i != ctx.cqes[i].user_data) {
113
+ printf("invalid user data\n");
114
+ goto err;
115
+ }
116
+ }
117
+
118
+ free_context(&ctx);
119
+ return 0;
120
+ err:
121
+ free_context(&ctx);
122
+ return 1;
123
+ }
124
+
125
+ static int test_thread_link_cancel(struct io_uring *ring)
126
+ {
127
+ struct test_context ctx;
128
+ int ret, i, nr = 100;
129
+
130
+ if (init_context(&ctx, ring, nr, OP_REMOVE_BUFFERS))
131
+ return 1;
132
+
133
+ for (i = 0; i < nr; i++)
134
+ ctx.sqes[i]->flags |= IOSQE_IO_LINK;
135
+
136
+ ret = io_uring_submit(ring);
137
+ if (ret <= 0) {
138
+ printf("sqe submit failed: %d\n", ret);
139
+ goto err;
140
+ }
141
+
142
+ if (wait_cqes(&ctx))
143
+ goto err;
144
+
145
+ for (i = 0; i < nr; i++) {
146
+ bool fail = false;
147
+
148
+ if (i == 0)
149
+ fail = (ctx.cqes[i].res != -ENOENT);
150
+ else
151
+ fail = (ctx.cqes[i].res != -ECANCELED);
152
+
153
+ if (fail) {
154
+ printf("invalid status %d\n", ctx.cqes[i].res);
155
+ goto err;
156
+ }
157
+ }
158
+
159
+ free_context(&ctx);
160
+ return 0;
161
+ err:
162
+ free_context(&ctx);
163
+ return 1;
164
+ }
165
+
166
+ static int test_drain_with_linked_timeout(struct io_uring *ring)
167
+ {
168
+ const int nr = 3;
169
+ struct __kernel_timespec ts = { .tv_sec = 1, .tv_nsec = 0, };
170
+ struct test_context ctx;
171
+ int ret, i;
172
+
173
+ if (init_context(&ctx, ring, nr * 2, OP_NOP))
174
+ return 1;
175
+
176
+ for (i = 0; i < nr; i++) {
177
+ io_uring_prep_timeout(ctx.sqes[2 * i], &ts, 0, 0);
178
+ ctx.sqes[2 * i]->flags |= IOSQE_IO_LINK | IOSQE_IO_DRAIN;
179
+ io_uring_prep_link_timeout(ctx.sqes[2 * i + 1], &ts, 0);
180
+ }
181
+
182
+ ret = io_uring_submit(ring);
183
+ if (ret <= 0) {
184
+ printf("sqe submit failed: %d\n", ret);
185
+ goto err;
186
+ }
187
+
188
+ if (wait_cqes(&ctx))
189
+ goto err;
190
+
191
+ free_context(&ctx);
192
+ return 0;
193
+ err:
194
+ free_context(&ctx);
195
+ return 1;
196
+ }
197
+
198
+ static int run_drained(struct io_uring *ring, int nr)
199
+ {
200
+ struct test_context ctx;
201
+ int ret, i;
202
+
203
+ if (init_context(&ctx, ring, nr, OP_NOP))
204
+ return 1;
205
+
206
+ for (i = 0; i < nr; i++)
207
+ ctx.sqes[i]->flags |= IOSQE_IO_DRAIN;
208
+
209
+ ret = io_uring_submit(ring);
210
+ if (ret <= 0) {
211
+ printf("sqe submit failed: %d\n", ret);
212
+ goto err;
213
+ }
214
+
215
+ if (wait_cqes(&ctx))
216
+ goto err;
217
+
218
+ free_context(&ctx);
219
+ return 0;
220
+ err:
221
+ free_context(&ctx);
222
+ return 1;
223
+ }
224
+
225
+ static int test_overflow_hung(struct io_uring *ring)
226
+ {
227
+ struct io_uring_sqe *sqe;
228
+ int ret, nr = 10;
229
+
230
+ while (*ring->cq.koverflow != 1000) {
231
+ sqe = io_uring_get_sqe(ring);
232
+ if (!sqe) {
233
+ printf("get sqe failed\n");
234
+ return 1;
235
+ }
236
+
237
+ io_uring_prep_nop(sqe);
238
+ ret = io_uring_submit(ring);
239
+ if (ret <= 0) {
240
+ printf("sqe submit failed: %d\n", ret);
241
+ return 1;
242
+ }
243
+ }
244
+
245
+ return run_drained(ring, nr);
246
+ }
247
+
248
+ static int test_dropped_hung(struct io_uring *ring)
249
+ {
250
+ int nr = 10;
251
+
252
+ *ring->sq.kdropped = 1000;
253
+ return run_drained(ring, nr);
254
+ }
255
+
256
+ int main(int argc, char *argv[])
257
+ {
258
+ struct io_uring ring, poll_ring, sqthread_ring;
259
+ struct io_uring_params p;
260
+ int ret;
261
+
262
+ if (argc > 1)
263
+ return T_EXIT_SKIP;
264
+
265
+ memset(&p, 0, sizeof(p));
266
+ ret = io_uring_queue_init_params(RING_SIZE, &ring, &p);
267
+ if (ret) {
268
+ printf("ring setup failed %i\n", ret);
269
+ return T_EXIT_FAIL;
270
+ }
271
+
272
+ ret = io_uring_queue_init(RING_SIZE, &poll_ring, IORING_SETUP_IOPOLL);
273
+ if (ret) {
274
+ printf("poll_ring setup failed\n");
275
+ return T_EXIT_FAIL;
276
+ }
277
+
278
+
279
+ ret = test_canceled_userdata(&poll_ring);
280
+ if (ret) {
281
+ printf("test_canceled_userdata failed\n");
282
+ return ret;
283
+ }
284
+
285
+ if (!(p.features & IORING_FEAT_NODROP)) {
286
+ ret = test_overflow_hung(&ring);
287
+ if (ret) {
288
+ printf("test_overflow_hung failed\n");
289
+ return ret;
290
+ }
291
+ }
292
+
293
+ ret = test_dropped_hung(&ring);
294
+ if (ret) {
295
+ printf("test_dropped_hung failed\n");
296
+ return ret;
297
+ }
298
+
299
+ ret = test_drain_with_linked_timeout(&ring);
300
+ if (ret) {
301
+ printf("test_drain_with_linked_timeout failed\n");
302
+ return ret;
303
+ }
304
+
305
+ ret = t_create_ring(RING_SIZE, &sqthread_ring,
306
+ IORING_SETUP_SQPOLL | IORING_SETUP_IOPOLL);
307
+ if (ret == T_SETUP_SKIP)
308
+ return T_EXIT_SKIP;
309
+ else if (ret < 0)
310
+ return T_EXIT_FAIL;
311
+
312
+ ret = test_thread_link_cancel(&sqthread_ring);
313
+ if (ret) {
314
+ printf("test_thread_link_cancel failed\n");
315
+ return ret;
316
+ }
317
+
318
+ return T_EXIT_PASS;
319
+ }
@@ -0,0 +1,195 @@
1
+ /* SPDX-License-Identifier: MIT */
2
+ // https://syzkaller.appspot.com/bug?id=5c9918d20f771265ad0ffae3c8f3859d24850692
3
+ // autogenerated by syzkaller (https://github.com/google/syzkaller)
4
+
5
+ #include <endian.h>
6
+ #include <fcntl.h>
7
+ #include <stdint.h>
8
+ #include <stdio.h>
9
+ #include <stdlib.h>
10
+ #include <string.h>
11
+ #include <sys/mman.h>
12
+ #include <sys/stat.h>
13
+ #include <sys/types.h>
14
+ #include <sys/ioctl.h>
15
+ #include <unistd.h>
16
+
17
+ #include "liburing.h"
18
+ #include "helpers.h"
19
+ #include "../src/syscall.h"
20
+
21
+ #define SIZEOF_IO_URING_SQE 64
22
+ #define SIZEOF_IO_URING_CQE 16
23
+ #define SQ_HEAD_OFFSET 0
24
+ #define SQ_TAIL_OFFSET 64
25
+ #define SQ_RING_MASK_OFFSET 256
26
+ #define SQ_RING_ENTRIES_OFFSET 264
27
+ #define SQ_FLAGS_OFFSET 276
28
+ #define SQ_DROPPED_OFFSET 272
29
+ #define CQ_HEAD_OFFSET 128
30
+ #define CQ_TAIL_OFFSET 192
31
+ #define CQ_RING_MASK_OFFSET 260
32
+ #define CQ_RING_ENTRIES_OFFSET 268
33
+ #define CQ_RING_OVERFLOW_OFFSET 284
34
+ #define CQ_FLAGS_OFFSET 280
35
+ #define CQ_CQES_OFFSET 320
36
+
37
+ static long syz_io_uring_setup(volatile long a0, volatile long a1,
38
+ volatile long a2, volatile long a3,
39
+ volatile long a4, volatile long a5)
40
+ {
41
+ uint32_t entries = (uint32_t)a0;
42
+ struct io_uring_params* setup_params = (struct io_uring_params*)a1;
43
+ void* vma1 = (void*)a2;
44
+ void* vma2 = (void*)a3;
45
+ void** ring_ptr_out = (void**)a4;
46
+ void** sqes_ptr_out = (void**)a5;
47
+ uint32_t fd_io_uring = __sys_io_uring_setup(entries, setup_params);
48
+ uint32_t sq_ring_sz =
49
+ setup_params->sq_off.array + setup_params->sq_entries * sizeof(uint32_t);
50
+ uint32_t cq_ring_sz = setup_params->cq_off.cqes +
51
+ setup_params->cq_entries * SIZEOF_IO_URING_CQE;
52
+ uint32_t ring_sz = sq_ring_sz > cq_ring_sz ? sq_ring_sz : cq_ring_sz;
53
+ *ring_ptr_out = mmap(vma1, ring_sz, PROT_READ | PROT_WRITE,
54
+ MAP_SHARED | MAP_POPULATE | MAP_FIXED, fd_io_uring,
55
+ IORING_OFF_SQ_RING);
56
+ if (*ring_ptr_out == MAP_FAILED)
57
+ exit(0);
58
+ uint32_t sqes_sz = setup_params->sq_entries * SIZEOF_IO_URING_SQE;
59
+ *sqes_ptr_out =
60
+ mmap(vma2, sqes_sz, PROT_READ | PROT_WRITE,
61
+ MAP_SHARED | MAP_POPULATE | MAP_FIXED, fd_io_uring, IORING_OFF_SQES);
62
+ if (*sqes_ptr_out == MAP_FAILED)
63
+ exit(0);
64
+ return fd_io_uring;
65
+ }
66
+
67
+ static long syz_io_uring_submit(volatile long a0, volatile long a1,
68
+ volatile long a2, volatile long a3)
69
+ {
70
+ char* ring_ptr = (char*)a0;
71
+ char* sqes_ptr = (char*)a1;
72
+ char* sqe = (char*)a2;
73
+ uint32_t sqes_index = (uint32_t)a3;
74
+ uint32_t sq_ring_entries = *(uint32_t*)(ring_ptr + SQ_RING_ENTRIES_OFFSET);
75
+ uint32_t cq_ring_entries = *(uint32_t*)(ring_ptr + CQ_RING_ENTRIES_OFFSET);
76
+ uint32_t sq_array_off =
77
+ (CQ_CQES_OFFSET + cq_ring_entries * SIZEOF_IO_URING_CQE + 63) & ~63;
78
+ if (sq_ring_entries)
79
+ sqes_index %= sq_ring_entries;
80
+ char* sqe_dest = sqes_ptr + sqes_index * SIZEOF_IO_URING_SQE;
81
+ memcpy(sqe_dest, sqe, SIZEOF_IO_URING_SQE);
82
+ uint32_t sq_ring_mask = *(uint32_t*)(ring_ptr + SQ_RING_MASK_OFFSET);
83
+ uint32_t* sq_tail_ptr = (uint32_t*)(ring_ptr + SQ_TAIL_OFFSET);
84
+ uint32_t sq_tail = *sq_tail_ptr & sq_ring_mask;
85
+ uint32_t sq_tail_next = *sq_tail_ptr + 1;
86
+ uint32_t* sq_array = (uint32_t*)(ring_ptr + sq_array_off);
87
+ *(sq_array + sq_tail) = sqes_index;
88
+ __atomic_store_n(sq_tail_ptr, sq_tail_next, __ATOMIC_RELEASE);
89
+ return 0;
90
+ }
91
+
92
+ static long syz_open_dev(volatile long a0, volatile long a1, volatile long a2)
93
+ {
94
+ if (a0 == 0xc || a0 == 0xb) {
95
+ char buf[128];
96
+ sprintf(buf, "/dev/%s/%d:%d", a0 == 0xc ? "char" : "block", (uint8_t)a1,
97
+ (uint8_t)a2);
98
+ return open(buf, O_RDWR, 0);
99
+ } else {
100
+ char buf[1024];
101
+ char* hash;
102
+ strncpy(buf, (char*)a0, sizeof(buf) - 1);
103
+ buf[sizeof(buf) - 1] = 0;
104
+ while ((hash = strchr(buf, '#'))) {
105
+ *hash = '0' + (char)(a1 % 10);
106
+ a1 /= 10;
107
+ }
108
+ return open(buf, a2, 0);
109
+ }
110
+ }
111
+
112
+ static uint64_t r[4] = {0xffffffffffffffff, 0x0, 0x0, 0xffffffffffffffff};
113
+
114
+ int main(int argc, char *argv[])
115
+ {
116
+ void *mmap_ret;
117
+ #if !defined(__i386) && !defined(__x86_64__)
118
+ return T_EXIT_SKIP;
119
+ #endif
120
+
121
+ if (argc > 1)
122
+ return T_EXIT_SKIP;
123
+
124
+ mmap_ret = mmap((void *)0x20000000ul, 0x1000000ul, 7ul, MAP_ANON|MAP_PRIVATE, -1, 0ul);
125
+ if (mmap_ret == MAP_FAILED)
126
+ return T_EXIT_SKIP;
127
+ mmap_ret = mmap((void *)0x21000000ul, 0x1000ul, 0ul, MAP_ANON|MAP_PRIVATE, -1, 0ul);
128
+ if (mmap_ret == MAP_FAILED)
129
+ return T_EXIT_SKIP;
130
+ intptr_t res = 0;
131
+ *(uint32_t*)0x20000484 = 0;
132
+ *(uint32_t*)0x20000488 = 0;
133
+ *(uint32_t*)0x2000048c = 0;
134
+ *(uint32_t*)0x20000490 = 0;
135
+ *(uint32_t*)0x20000498 = -1;
136
+ *(uint32_t*)0x2000049c = 0;
137
+ *(uint32_t*)0x200004a0 = 0;
138
+ *(uint32_t*)0x200004a4 = 0;
139
+ res = -1;
140
+ res = syz_io_uring_setup(0x6ad4, 0x20000480, 0x20ee7000, 0x20ffb000,
141
+ 0x20000180, 0x20000040);
142
+ if (res != -1) {
143
+ r[0] = res;
144
+ r[1] = *(uint64_t*)0x20000180;
145
+ r[2] = *(uint64_t*)0x20000040;
146
+ }
147
+ res = -1;
148
+ res = syz_open_dev(0xc, 4, 0x15);
149
+ if (res != -1)
150
+ r[3] = res;
151
+ *(uint8_t*)0x20000000 = 6;
152
+ *(uint8_t*)0x20000001 = 0;
153
+ *(uint16_t*)0x20000002 = 0;
154
+ *(uint32_t*)0x20000004 = r[3];
155
+ *(uint64_t*)0x20000008 = 0;
156
+ *(uint64_t*)0x20000010 = 0;
157
+ *(uint32_t*)0x20000018 = 0;
158
+ *(uint16_t*)0x2000001c = 0;
159
+ *(uint16_t*)0x2000001e = 0;
160
+ *(uint64_t*)0x20000020 = 0;
161
+ *(uint16_t*)0x20000028 = 0;
162
+ *(uint16_t*)0x2000002a = 0;
163
+ *(uint8_t*)0x2000002c = 0;
164
+ *(uint8_t*)0x2000002d = 0;
165
+ *(uint8_t*)0x2000002e = 0;
166
+ *(uint8_t*)0x2000002f = 0;
167
+ *(uint8_t*)0x20000030 = 0;
168
+ *(uint8_t*)0x20000031 = 0;
169
+ *(uint8_t*)0x20000032 = 0;
170
+ *(uint8_t*)0x20000033 = 0;
171
+ *(uint8_t*)0x20000034 = 0;
172
+ *(uint8_t*)0x20000035 = 0;
173
+ *(uint8_t*)0x20000036 = 0;
174
+ *(uint8_t*)0x20000037 = 0;
175
+ *(uint8_t*)0x20000038 = 0;
176
+ *(uint8_t*)0x20000039 = 0;
177
+ *(uint8_t*)0x2000003a = 0;
178
+ *(uint8_t*)0x2000003b = 0;
179
+ *(uint8_t*)0x2000003c = 0;
180
+ *(uint8_t*)0x2000003d = 0;
181
+ *(uint8_t*)0x2000003e = 0;
182
+ *(uint8_t*)0x2000003f = 0;
183
+ syz_io_uring_submit(r[1], r[2], 0x20000000, 0);
184
+ __sys_io_uring_enter(r[0], 0x20450c, 0, 0ul, 0ul);
185
+ *(uint32_t*)0x20000080 = 0x7ff;
186
+ *(uint32_t*)0x20000084 = 0x8b7;
187
+ *(uint32_t*)0x20000088 = 3;
188
+ *(uint32_t*)0x2000008c = 0x101;
189
+ *(uint8_t*)0x20000090 = 9;
190
+ memcpy((void*)0x20000091, "\xaf\x09\x01\xbc\xf9\xc6\xe4\x92\x86\x51\x7d\x7f"
191
+ "\xbd\x43\x7d\x16\x69\x3e\x05",
192
+ 19);
193
+ ioctl(r[3], 0x5404, 0x20000080ul);
194
+ return T_EXIT_PASS;
195
+ }