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.
- checksums.yaml +7 -0
- data/.github/dependabot.yml +12 -0
- data/.github/workflows/test.yml +35 -0
- data/.gitignore +59 -0
- data/.gitmodules +3 -0
- data/CHANGELOG.md +7 -0
- data/Gemfile +3 -0
- data/LICENSE +21 -0
- data/README.md +11 -0
- data/Rakefile +39 -0
- data/TODO.md +0 -0
- data/examples/echo_server.rb +52 -0
- data/examples/event_loop.rb +69 -0
- data/examples/fibers.rb +105 -0
- data/examples/http_server.rb +56 -0
- data/examples/http_server_multishot.rb +57 -0
- data/examples/http_server_simpler.rb +34 -0
- data/ext/um/extconf.rb +71 -0
- data/ext/um/iou.h +101 -0
- data/ext/um/op_ctx.c +138 -0
- data/ext/um/ring.c +755 -0
- data/ext/um/um.c +267 -0
- data/ext/um/um.h +97 -0
- data/ext/um/um_class.c +175 -0
- data/ext/um/um_ext.c +11 -0
- data/ext/um/um_op.c +87 -0
- data/ext/um/um_utils.c +23 -0
- data/lib/uringmachine/version.rb +3 -0
- data/lib/uringmachine.rb +8 -0
- data/test/helper.rb +70 -0
- data/test/test_iou.rb +876 -0
- data/test/test_um.rb +168 -0
- data/uringmachine.gemspec +27 -0
- data/vendor/liburing/.github/actions/codespell/stopwords +7 -0
- data/vendor/liburing/.github/pull_request_template.md +86 -0
- data/vendor/liburing/.github/workflows/build.yml +137 -0
- data/vendor/liburing/.github/workflows/codespell.yml +25 -0
- data/vendor/liburing/.github/workflows/shellcheck.yml +20 -0
- data/vendor/liburing/.gitignore +41 -0
- data/vendor/liburing/CHANGELOG +111 -0
- data/vendor/liburing/CITATION.cff +11 -0
- data/vendor/liburing/COPYING +502 -0
- data/vendor/liburing/COPYING.GPL +339 -0
- data/vendor/liburing/LICENSE +20 -0
- data/vendor/liburing/Makefile +96 -0
- data/vendor/liburing/Makefile.common +7 -0
- data/vendor/liburing/Makefile.quiet +11 -0
- data/vendor/liburing/README +106 -0
- data/vendor/liburing/SECURITY.md +6 -0
- data/vendor/liburing/configure +624 -0
- data/vendor/liburing/debian/README.Debian +7 -0
- data/vendor/liburing/debian/changelog +38 -0
- data/vendor/liburing/debian/control +39 -0
- data/vendor/liburing/debian/copyright +49 -0
- data/vendor/liburing/debian/liburing-dev.install +4 -0
- data/vendor/liburing/debian/liburing-dev.manpages +5 -0
- data/vendor/liburing/debian/liburing2.install +1 -0
- data/vendor/liburing/debian/liburing2.symbols +56 -0
- data/vendor/liburing/debian/patches/series +1 -0
- data/vendor/liburing/debian/rules +29 -0
- data/vendor/liburing/debian/source/format +1 -0
- data/vendor/liburing/debian/source/local-options +2 -0
- data/vendor/liburing/debian/source/options +1 -0
- data/vendor/liburing/debian/watch +3 -0
- data/vendor/liburing/examples/Makefile +53 -0
- data/vendor/liburing/examples/helpers.c +62 -0
- data/vendor/liburing/examples/helpers.h +7 -0
- data/vendor/liburing/examples/io_uring-close-test.c +123 -0
- data/vendor/liburing/examples/io_uring-cp.c +282 -0
- data/vendor/liburing/examples/io_uring-test.c +112 -0
- data/vendor/liburing/examples/io_uring-udp.c +403 -0
- data/vendor/liburing/examples/link-cp.c +193 -0
- data/vendor/liburing/examples/napi-busy-poll-client.c +509 -0
- data/vendor/liburing/examples/napi-busy-poll-server.c +450 -0
- data/vendor/liburing/examples/poll-bench.c +101 -0
- data/vendor/liburing/examples/proxy.c +2461 -0
- data/vendor/liburing/examples/proxy.h +102 -0
- data/vendor/liburing/examples/rsrc-update-bench.c +100 -0
- data/vendor/liburing/examples/send-zerocopy.c +658 -0
- data/vendor/liburing/examples/ucontext-cp.c +258 -0
- data/vendor/liburing/liburing-ffi.pc.in +12 -0
- data/vendor/liburing/liburing.pc.in +12 -0
- data/vendor/liburing/liburing.spec +66 -0
- data/vendor/liburing/make-debs.sh +55 -0
- data/vendor/liburing/src/Makefile +129 -0
- data/vendor/liburing/src/arch/aarch64/lib.h +47 -0
- data/vendor/liburing/src/arch/aarch64/syscall.h +91 -0
- data/vendor/liburing/src/arch/generic/lib.h +17 -0
- data/vendor/liburing/src/arch/generic/syscall.h +100 -0
- data/vendor/liburing/src/arch/riscv64/lib.h +48 -0
- data/vendor/liburing/src/arch/riscv64/syscall.h +100 -0
- data/vendor/liburing/src/arch/syscall-defs.h +94 -0
- data/vendor/liburing/src/arch/x86/lib.h +11 -0
- data/vendor/liburing/src/arch/x86/syscall.h +296 -0
- data/vendor/liburing/src/ffi.c +15 -0
- data/vendor/liburing/src/include/liburing/barrier.h +81 -0
- data/vendor/liburing/src/include/liburing/io_uring.h +818 -0
- data/vendor/liburing/src/include/liburing.h +1602 -0
- data/vendor/liburing/src/int_flags.h +11 -0
- data/vendor/liburing/src/lib.h +52 -0
- data/vendor/liburing/src/liburing-ffi.map +211 -0
- data/vendor/liburing/src/liburing.map +104 -0
- data/vendor/liburing/src/nolibc.c +55 -0
- data/vendor/liburing/src/queue.c +468 -0
- data/vendor/liburing/src/register.c +374 -0
- data/vendor/liburing/src/setup.c +689 -0
- data/vendor/liburing/src/setup.h +9 -0
- data/vendor/liburing/src/syscall.c +29 -0
- data/vendor/liburing/src/syscall.h +53 -0
- data/vendor/liburing/src/version.c +21 -0
- data/vendor/liburing/test/232c93d07b74.c +305 -0
- data/vendor/liburing/test/35fa71a030ca.c +329 -0
- data/vendor/liburing/test/500f9fbadef8.c +91 -0
- data/vendor/liburing/test/7ad0e4b2f83c.c +94 -0
- data/vendor/liburing/test/8a9973408177.c +107 -0
- data/vendor/liburing/test/917257daa0fe.c +54 -0
- data/vendor/liburing/test/Makefile +297 -0
- data/vendor/liburing/test/a0908ae19763.c +59 -0
- data/vendor/liburing/test/a4c0b3decb33.c +181 -0
- data/vendor/liburing/test/accept-link.c +255 -0
- data/vendor/liburing/test/accept-non-empty.c +256 -0
- data/vendor/liburing/test/accept-reuse.c +163 -0
- data/vendor/liburing/test/accept-test.c +83 -0
- data/vendor/liburing/test/accept.c +919 -0
- data/vendor/liburing/test/across-fork.c +284 -0
- data/vendor/liburing/test/b19062a56726.c +54 -0
- data/vendor/liburing/test/b5837bd5311d.c +78 -0
- data/vendor/liburing/test/bind-listen.c +408 -0
- data/vendor/liburing/test/buf-ring-nommap.c +123 -0
- data/vendor/liburing/test/buf-ring-put.c +83 -0
- data/vendor/liburing/test/buf-ring.c +473 -0
- data/vendor/liburing/test/ce593a6c480a.c +139 -0
- data/vendor/liburing/test/close-opath.c +123 -0
- data/vendor/liburing/test/config +14 -0
- data/vendor/liburing/test/connect-rep.c +204 -0
- data/vendor/liburing/test/connect.c +442 -0
- data/vendor/liburing/test/coredump.c +60 -0
- data/vendor/liburing/test/cq-full.c +97 -0
- data/vendor/liburing/test/cq-overflow.c +530 -0
- data/vendor/liburing/test/cq-peek-batch.c +103 -0
- data/vendor/liburing/test/cq-ready.c +95 -0
- data/vendor/liburing/test/cq-size.c +65 -0
- data/vendor/liburing/test/d4ae271dfaae.c +96 -0
- data/vendor/liburing/test/d77a67ed5f27.c +65 -0
- data/vendor/liburing/test/defer-taskrun.c +391 -0
- data/vendor/liburing/test/defer-tw-timeout.c +173 -0
- data/vendor/liburing/test/defer.c +319 -0
- data/vendor/liburing/test/double-poll-crash.c +195 -0
- data/vendor/liburing/test/drop-submit.c +94 -0
- data/vendor/liburing/test/eeed8b54e0df.c +120 -0
- data/vendor/liburing/test/empty-eownerdead.c +45 -0
- data/vendor/liburing/test/eploop.c +74 -0
- data/vendor/liburing/test/eventfd-disable.c +179 -0
- data/vendor/liburing/test/eventfd-reg.c +77 -0
- data/vendor/liburing/test/eventfd-ring.c +98 -0
- data/vendor/liburing/test/eventfd.c +113 -0
- data/vendor/liburing/test/evloop.c +73 -0
- data/vendor/liburing/test/exec-target.c +6 -0
- data/vendor/liburing/test/exit-no-cleanup.c +117 -0
- data/vendor/liburing/test/fadvise.c +202 -0
- data/vendor/liburing/test/fallocate.c +265 -0
- data/vendor/liburing/test/fc2a85cb02ef.c +132 -0
- data/vendor/liburing/test/fd-install.c +500 -0
- data/vendor/liburing/test/fd-pass.c +237 -0
- data/vendor/liburing/test/fdinfo.c +419 -0
- data/vendor/liburing/test/file-register.c +1189 -0
- data/vendor/liburing/test/file-update.c +231 -0
- data/vendor/liburing/test/file-verify.c +654 -0
- data/vendor/liburing/test/files-exit-hang-poll.c +114 -0
- data/vendor/liburing/test/files-exit-hang-timeout.c +137 -0
- data/vendor/liburing/test/fixed-buf-iter.c +115 -0
- data/vendor/liburing/test/fixed-buf-merge.c +101 -0
- data/vendor/liburing/test/fixed-hugepage.c +411 -0
- data/vendor/liburing/test/fixed-link.c +90 -0
- data/vendor/liburing/test/fixed-reuse.c +160 -0
- data/vendor/liburing/test/fpos.c +255 -0
- data/vendor/liburing/test/fsnotify.c +118 -0
- data/vendor/liburing/test/fsync.c +224 -0
- data/vendor/liburing/test/futex.c +571 -0
- data/vendor/liburing/test/hardlink.c +170 -0
- data/vendor/liburing/test/helpers.c +318 -0
- data/vendor/liburing/test/helpers.h +108 -0
- data/vendor/liburing/test/ignore-single-mmap.c +48 -0
- data/vendor/liburing/test/init-mem.c +164 -0
- data/vendor/liburing/test/io-cancel.c +561 -0
- data/vendor/liburing/test/io_uring_enter.c +264 -0
- data/vendor/liburing/test/io_uring_passthrough.c +482 -0
- data/vendor/liburing/test/io_uring_register.c +503 -0
- data/vendor/liburing/test/io_uring_setup.c +110 -0
- data/vendor/liburing/test/iopoll-leak.c +85 -0
- data/vendor/liburing/test/iopoll-overflow.c +118 -0
- data/vendor/liburing/test/iopoll.c +465 -0
- data/vendor/liburing/test/lfs-openat-write.c +119 -0
- data/vendor/liburing/test/lfs-openat.c +273 -0
- data/vendor/liburing/test/link-timeout.c +1108 -0
- data/vendor/liburing/test/link.c +497 -0
- data/vendor/liburing/test/link_drain.c +255 -0
- data/vendor/liburing/test/madvise.c +195 -0
- data/vendor/liburing/test/min-timeout-wait.c +354 -0
- data/vendor/liburing/test/min-timeout.c +233 -0
- data/vendor/liburing/test/mkdir.c +112 -0
- data/vendor/liburing/test/msg-ring-fd.c +331 -0
- data/vendor/liburing/test/msg-ring-flags.c +212 -0
- data/vendor/liburing/test/msg-ring-overflow.c +159 -0
- data/vendor/liburing/test/msg-ring.c +467 -0
- data/vendor/liburing/test/multicqes_drain.c +429 -0
- data/vendor/liburing/test/napi-test.c +215 -0
- data/vendor/liburing/test/napi-test.sh +48 -0
- data/vendor/liburing/test/no-mmap-inval.c +42 -0
- data/vendor/liburing/test/nolibc.c +62 -0
- data/vendor/liburing/test/nop-all-sizes.c +99 -0
- data/vendor/liburing/test/nop.c +177 -0
- data/vendor/liburing/test/nvme.h +169 -0
- data/vendor/liburing/test/ooo-file-unreg.c +82 -0
- data/vendor/liburing/test/open-close.c +261 -0
- data/vendor/liburing/test/open-direct-link.c +188 -0
- data/vendor/liburing/test/open-direct-pick.c +180 -0
- data/vendor/liburing/test/openat2.c +312 -0
- data/vendor/liburing/test/personality.c +204 -0
- data/vendor/liburing/test/pipe-bug.c +95 -0
- data/vendor/liburing/test/pipe-eof.c +83 -0
- data/vendor/liburing/test/pipe-reuse.c +105 -0
- data/vendor/liburing/test/poll-cancel-all.c +496 -0
- data/vendor/liburing/test/poll-cancel-ton.c +135 -0
- data/vendor/liburing/test/poll-cancel.c +228 -0
- data/vendor/liburing/test/poll-link.c +221 -0
- data/vendor/liburing/test/poll-many.c +230 -0
- data/vendor/liburing/test/poll-mshot-overflow.c +265 -0
- data/vendor/liburing/test/poll-mshot-update.c +323 -0
- data/vendor/liburing/test/poll-race-mshot.c +276 -0
- data/vendor/liburing/test/poll-race.c +105 -0
- data/vendor/liburing/test/poll-ring.c +48 -0
- data/vendor/liburing/test/poll-v-poll.c +353 -0
- data/vendor/liburing/test/poll.c +327 -0
- data/vendor/liburing/test/probe.c +135 -0
- data/vendor/liburing/test/read-before-exit.c +129 -0
- data/vendor/liburing/test/read-mshot-empty.c +153 -0
- data/vendor/liburing/test/read-mshot.c +404 -0
- data/vendor/liburing/test/read-write.c +1013 -0
- data/vendor/liburing/test/recv-msgall-stream.c +398 -0
- data/vendor/liburing/test/recv-msgall.c +263 -0
- data/vendor/liburing/test/recv-multishot.c +602 -0
- data/vendor/liburing/test/recvsend_bundle.c +691 -0
- data/vendor/liburing/test/reg-fd-only.c +131 -0
- data/vendor/liburing/test/reg-hint.c +56 -0
- data/vendor/liburing/test/reg-reg-ring.c +90 -0
- data/vendor/liburing/test/regbuf-merge.c +91 -0
- data/vendor/liburing/test/register-restrictions.c +633 -0
- data/vendor/liburing/test/rename.c +132 -0
- data/vendor/liburing/test/ring-leak.c +283 -0
- data/vendor/liburing/test/ring-leak2.c +249 -0
- data/vendor/liburing/test/ringbuf-read.c +196 -0
- data/vendor/liburing/test/ringbuf-status.c +242 -0
- data/vendor/liburing/test/rsrc_tags.c +461 -0
- data/vendor/liburing/test/runtests-loop.sh +16 -0
- data/vendor/liburing/test/runtests-quiet.sh +11 -0
- data/vendor/liburing/test/runtests.sh +168 -0
- data/vendor/liburing/test/rw_merge_test.c +98 -0
- data/vendor/liburing/test/self.c +91 -0
- data/vendor/liburing/test/send-zerocopy.c +971 -0
- data/vendor/liburing/test/send_recv.c +412 -0
- data/vendor/liburing/test/send_recvmsg.c +444 -0
- data/vendor/liburing/test/shared-wq.c +84 -0
- data/vendor/liburing/test/short-read.c +75 -0
- data/vendor/liburing/test/shutdown.c +165 -0
- data/vendor/liburing/test/sigfd-deadlock.c +88 -0
- data/vendor/liburing/test/single-issuer.c +169 -0
- data/vendor/liburing/test/skip-cqe.c +428 -0
- data/vendor/liburing/test/socket-getsetsock-cmd.c +346 -0
- data/vendor/liburing/test/socket-io-cmd.c +237 -0
- data/vendor/liburing/test/socket-rw-eagain.c +149 -0
- data/vendor/liburing/test/socket-rw-offset.c +149 -0
- data/vendor/liburing/test/socket-rw.c +137 -0
- data/vendor/liburing/test/socket.c +408 -0
- data/vendor/liburing/test/splice.c +512 -0
- data/vendor/liburing/test/sq-full-cpp.cc +45 -0
- data/vendor/liburing/test/sq-full.c +45 -0
- data/vendor/liburing/test/sq-poll-dup.c +211 -0
- data/vendor/liburing/test/sq-poll-kthread.c +169 -0
- data/vendor/liburing/test/sq-poll-share.c +138 -0
- data/vendor/liburing/test/sq-space_left.c +159 -0
- data/vendor/liburing/test/sqpoll-disable-exit.c +196 -0
- data/vendor/liburing/test/sqpoll-exec.c +132 -0
- data/vendor/liburing/test/sqpoll-exit-hang.c +78 -0
- data/vendor/liburing/test/sqpoll-sleep.c +69 -0
- data/vendor/liburing/test/statx.c +172 -0
- data/vendor/liburing/test/stdout.c +232 -0
- data/vendor/liburing/test/submit-and-wait.c +108 -0
- data/vendor/liburing/test/submit-link-fail.c +156 -0
- data/vendor/liburing/test/submit-reuse.c +237 -0
- data/vendor/liburing/test/symlink.c +117 -0
- data/vendor/liburing/test/sync-cancel.c +235 -0
- data/vendor/liburing/test/teardowns.c +58 -0
- data/vendor/liburing/test/test.h +36 -0
- data/vendor/liburing/test/thread-exit.c +143 -0
- data/vendor/liburing/test/timeout-new.c +256 -0
- data/vendor/liburing/test/timeout.c +1798 -0
- data/vendor/liburing/test/truncate.c +186 -0
- data/vendor/liburing/test/tty-write-dpoll.c +60 -0
- data/vendor/liburing/test/unlink.c +112 -0
- data/vendor/liburing/test/version.c +25 -0
- data/vendor/liburing/test/wait-timeout.c +287 -0
- data/vendor/liburing/test/waitid.c +373 -0
- data/vendor/liburing/test/wakeup-hang.c +162 -0
- data/vendor/liburing/test/wq-aff.c +146 -0
- data/vendor/liburing/test/xattr.c +442 -0
- metadata +412 -0
|
@@ -0,0 +1,473 @@
|
|
|
1
|
+
/* SPDX-License-Identifier: MIT */
|
|
2
|
+
/*
|
|
3
|
+
* Description: run various shared buffer ring sanity checks
|
|
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
|
+
#include <sys/mman.h>
|
|
13
|
+
|
|
14
|
+
#include "liburing.h"
|
|
15
|
+
#include "helpers.h"
|
|
16
|
+
|
|
17
|
+
static int no_buf_ring;
|
|
18
|
+
static int pagesize;
|
|
19
|
+
|
|
20
|
+
/* test trying to register classic group when ring group exists */
|
|
21
|
+
static int test_mixed_reg2(int bgid)
|
|
22
|
+
{
|
|
23
|
+
struct io_uring_buf_ring *br;
|
|
24
|
+
struct io_uring_sqe *sqe;
|
|
25
|
+
struct io_uring_cqe *cqe;
|
|
26
|
+
struct io_uring ring;
|
|
27
|
+
void *bufs;
|
|
28
|
+
int ret;
|
|
29
|
+
|
|
30
|
+
ret = t_create_ring(1, &ring, 0);
|
|
31
|
+
if (ret == T_SETUP_SKIP)
|
|
32
|
+
return 0;
|
|
33
|
+
else if (ret != T_SETUP_OK)
|
|
34
|
+
return 1;
|
|
35
|
+
|
|
36
|
+
br = io_uring_setup_buf_ring(&ring, 32, bgid, 0, &ret);
|
|
37
|
+
if (!br) {
|
|
38
|
+
fprintf(stderr, "Buffer ring register failed %d\n", ret);
|
|
39
|
+
return 1;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/* provide classic buffers, group 1 */
|
|
43
|
+
bufs = malloc(8 * 1024);
|
|
44
|
+
sqe = io_uring_get_sqe(&ring);
|
|
45
|
+
io_uring_prep_provide_buffers(sqe, bufs, 1024, 8, bgid, 0);
|
|
46
|
+
io_uring_submit(&ring);
|
|
47
|
+
ret = io_uring_wait_cqe(&ring, &cqe);
|
|
48
|
+
if (ret) {
|
|
49
|
+
fprintf(stderr, "wait_cqe %d\n", ret);
|
|
50
|
+
return 1;
|
|
51
|
+
}
|
|
52
|
+
if (cqe->res != -EEXIST && cqe->res != -EINVAL) {
|
|
53
|
+
fprintf(stderr, "cqe res %d\n", cqe->res);
|
|
54
|
+
return 1;
|
|
55
|
+
}
|
|
56
|
+
io_uring_cqe_seen(&ring, cqe);
|
|
57
|
+
|
|
58
|
+
io_uring_free_buf_ring(&ring, br, 32, bgid);
|
|
59
|
+
io_uring_queue_exit(&ring);
|
|
60
|
+
return 0;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/* test trying to register ring group when classic group exists */
|
|
64
|
+
static int test_mixed_reg(int bgid)
|
|
65
|
+
{
|
|
66
|
+
struct io_uring_buf_ring *br;
|
|
67
|
+
struct io_uring_sqe *sqe;
|
|
68
|
+
struct io_uring_cqe *cqe;
|
|
69
|
+
struct io_uring ring;
|
|
70
|
+
void *bufs;
|
|
71
|
+
int ret;
|
|
72
|
+
|
|
73
|
+
ret = t_create_ring(1, &ring, 0);
|
|
74
|
+
if (ret == T_SETUP_SKIP)
|
|
75
|
+
return 0;
|
|
76
|
+
else if (ret != T_SETUP_OK)
|
|
77
|
+
return 1;
|
|
78
|
+
|
|
79
|
+
/* provide classic buffers, group 1 */
|
|
80
|
+
bufs = malloc(8 * 1024);
|
|
81
|
+
sqe = io_uring_get_sqe(&ring);
|
|
82
|
+
io_uring_prep_provide_buffers(sqe, bufs, 1024, 8, bgid, 0);
|
|
83
|
+
io_uring_submit(&ring);
|
|
84
|
+
ret = io_uring_wait_cqe(&ring, &cqe);
|
|
85
|
+
if (ret) {
|
|
86
|
+
fprintf(stderr, "wait_cqe %d\n", ret);
|
|
87
|
+
return 1;
|
|
88
|
+
}
|
|
89
|
+
if (cqe->res) {
|
|
90
|
+
fprintf(stderr, "cqe res %d\n", cqe->res);
|
|
91
|
+
return 1;
|
|
92
|
+
}
|
|
93
|
+
io_uring_cqe_seen(&ring, cqe);
|
|
94
|
+
|
|
95
|
+
br = io_uring_setup_buf_ring(&ring, 32, bgid, 0, &ret);
|
|
96
|
+
if (br) {
|
|
97
|
+
fprintf(stderr, "Buffer ring setup succeeded unexpectedly %d\n", ret);
|
|
98
|
+
return 1;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
io_uring_queue_exit(&ring);
|
|
102
|
+
return 0;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
static int test_double_reg_unreg(int bgid)
|
|
106
|
+
{
|
|
107
|
+
struct io_uring_buf_reg reg = { };
|
|
108
|
+
struct io_uring_buf_ring *br;
|
|
109
|
+
struct io_uring ring;
|
|
110
|
+
int ret;
|
|
111
|
+
|
|
112
|
+
ret = t_create_ring(1, &ring, 0);
|
|
113
|
+
if (ret == T_SETUP_SKIP)
|
|
114
|
+
return 0;
|
|
115
|
+
else if (ret != T_SETUP_OK)
|
|
116
|
+
return 1;
|
|
117
|
+
|
|
118
|
+
br = io_uring_setup_buf_ring(&ring, 32, bgid, 0, &ret);
|
|
119
|
+
if (!br) {
|
|
120
|
+
fprintf(stderr, "Buffer ring register failed %d\n", ret);
|
|
121
|
+
return 1;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/* check that 2nd register with same bgid fails */
|
|
125
|
+
reg.ring_addr = (unsigned long) br;
|
|
126
|
+
reg.ring_entries = 32;
|
|
127
|
+
reg.bgid = bgid;
|
|
128
|
+
|
|
129
|
+
ret = io_uring_register_buf_ring(&ring, ®, 0);
|
|
130
|
+
if (ret != -EEXIST) {
|
|
131
|
+
fprintf(stderr, "Buffer ring register failed %d\n", ret);
|
|
132
|
+
return 1;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
ret = io_uring_free_buf_ring(&ring, br, 32, bgid);
|
|
136
|
+
if (ret) {
|
|
137
|
+
fprintf(stderr, "Buffer ring register failed %d\n", ret);
|
|
138
|
+
return 1;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
ret = io_uring_unregister_buf_ring(&ring, bgid);
|
|
142
|
+
if (ret != -EINVAL && ret != -ENOENT) {
|
|
143
|
+
fprintf(stderr, "Buffer ring register failed %d\n", ret);
|
|
144
|
+
return 1;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
io_uring_queue_exit(&ring);
|
|
148
|
+
return 0;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
static int test_reg_unreg(int bgid)
|
|
152
|
+
{
|
|
153
|
+
struct io_uring_buf_ring *br;
|
|
154
|
+
struct io_uring ring;
|
|
155
|
+
int ret;
|
|
156
|
+
|
|
157
|
+
ret = t_create_ring(1, &ring, 0);
|
|
158
|
+
if (ret == T_SETUP_SKIP)
|
|
159
|
+
return 0;
|
|
160
|
+
else if (ret != T_SETUP_OK)
|
|
161
|
+
return 1;
|
|
162
|
+
|
|
163
|
+
br = io_uring_setup_buf_ring(&ring, 32, bgid, 0, &ret);
|
|
164
|
+
if (!br) {
|
|
165
|
+
if (ret == -EINVAL) {
|
|
166
|
+
no_buf_ring = 1;
|
|
167
|
+
return 0;
|
|
168
|
+
}
|
|
169
|
+
fprintf(stderr, "Buffer ring register failed %d\n", ret);
|
|
170
|
+
return 1;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
ret = io_uring_free_buf_ring(&ring, br, 32, bgid);
|
|
174
|
+
if (ret) {
|
|
175
|
+
fprintf(stderr, "Buffer ring unregister failed %d\n", ret);
|
|
176
|
+
return 1;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
io_uring_queue_exit(&ring);
|
|
180
|
+
return 0;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
static int test_bad_reg(int bgid)
|
|
184
|
+
{
|
|
185
|
+
struct io_uring ring;
|
|
186
|
+
int ret;
|
|
187
|
+
struct io_uring_buf_reg reg = { };
|
|
188
|
+
|
|
189
|
+
ret = t_create_ring(1, &ring, 0);
|
|
190
|
+
if (ret == T_SETUP_SKIP)
|
|
191
|
+
return 0;
|
|
192
|
+
else if (ret != T_SETUP_OK)
|
|
193
|
+
return 1;
|
|
194
|
+
|
|
195
|
+
reg.ring_addr = 4096;
|
|
196
|
+
reg.ring_entries = 32;
|
|
197
|
+
reg.bgid = bgid;
|
|
198
|
+
|
|
199
|
+
ret = io_uring_register_buf_ring(&ring, ®, 0);
|
|
200
|
+
if (!ret)
|
|
201
|
+
fprintf(stderr, "Buffer ring register worked unexpectedly\n");
|
|
202
|
+
|
|
203
|
+
io_uring_queue_exit(&ring);
|
|
204
|
+
return !ret;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
static int test_full_page_reg(int bgid)
|
|
208
|
+
{
|
|
209
|
+
#if defined(__hppa__)
|
|
210
|
+
return T_EXIT_SKIP;
|
|
211
|
+
#else
|
|
212
|
+
struct io_uring ring;
|
|
213
|
+
int ret;
|
|
214
|
+
void *ptr;
|
|
215
|
+
struct io_uring_buf_reg reg = { };
|
|
216
|
+
int entries = pagesize / sizeof(struct io_uring_buf);
|
|
217
|
+
|
|
218
|
+
ret = io_uring_queue_init(1, &ring, 0);
|
|
219
|
+
if (ret) {
|
|
220
|
+
fprintf(stderr, "queue init failed %d\n", ret);
|
|
221
|
+
return T_EXIT_FAIL;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
ret = posix_memalign(&ptr, pagesize, pagesize * 2);
|
|
225
|
+
if (ret) {
|
|
226
|
+
fprintf(stderr, "posix_memalign failed %d\n", ret);
|
|
227
|
+
goto err;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
ret = mprotect(ptr + pagesize, pagesize, PROT_NONE);
|
|
231
|
+
if (ret) {
|
|
232
|
+
fprintf(stderr, "mprotect failed %d\n", errno);
|
|
233
|
+
goto err1;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
reg.ring_addr = (unsigned long) ptr;
|
|
237
|
+
reg.ring_entries = entries;
|
|
238
|
+
reg.bgid = bgid;
|
|
239
|
+
|
|
240
|
+
ret = io_uring_register_buf_ring(&ring, ®, 0);
|
|
241
|
+
if (ret)
|
|
242
|
+
fprintf(stderr, "register buf ring failed %d\n", ret);
|
|
243
|
+
|
|
244
|
+
if (mprotect(ptr + pagesize, pagesize, PROT_READ | PROT_WRITE))
|
|
245
|
+
fprintf(stderr, "reverting mprotect failed %d\n", errno);
|
|
246
|
+
|
|
247
|
+
err1:
|
|
248
|
+
free(ptr);
|
|
249
|
+
err:
|
|
250
|
+
io_uring_queue_exit(&ring);
|
|
251
|
+
return ret ? T_EXIT_FAIL : T_EXIT_PASS;
|
|
252
|
+
#endif
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
static int test_one_read(int fd, int bgid, struct io_uring *ring)
|
|
256
|
+
{
|
|
257
|
+
int ret;
|
|
258
|
+
struct io_uring_cqe *cqe;
|
|
259
|
+
struct io_uring_sqe *sqe;
|
|
260
|
+
|
|
261
|
+
sqe = io_uring_get_sqe(ring);
|
|
262
|
+
if (!sqe) {
|
|
263
|
+
fprintf(stderr, "get sqe failed\n");
|
|
264
|
+
return -1;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
io_uring_prep_read(sqe, fd, NULL, 1, 0);
|
|
268
|
+
sqe->flags |= IOSQE_BUFFER_SELECT;
|
|
269
|
+
sqe->buf_group = bgid;
|
|
270
|
+
ret = io_uring_submit(ring);
|
|
271
|
+
if (ret <= 0) {
|
|
272
|
+
fprintf(stderr, "sqe submit failed: %d\n", ret);
|
|
273
|
+
return -1;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
ret = io_uring_wait_cqe(ring, &cqe);
|
|
277
|
+
if (ret < 0) {
|
|
278
|
+
fprintf(stderr, "wait completion %d\n", ret);
|
|
279
|
+
return -1;
|
|
280
|
+
}
|
|
281
|
+
ret = cqe->res;
|
|
282
|
+
io_uring_cqe_seen(ring, cqe);
|
|
283
|
+
|
|
284
|
+
if (ret == -ENOBUFS)
|
|
285
|
+
return ret;
|
|
286
|
+
|
|
287
|
+
if (ret != 1) {
|
|
288
|
+
fprintf(stderr, "read result %d\n", ret);
|
|
289
|
+
return -1;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
return cqe->flags >> 16;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
static int test_running(int bgid, int entries, int loops, int use_mmap)
|
|
296
|
+
{
|
|
297
|
+
int ring_mask = io_uring_buf_ring_mask(entries);
|
|
298
|
+
struct io_uring_buf_ring *br;
|
|
299
|
+
int ret, loop, idx, read_fd;
|
|
300
|
+
struct io_uring ring;
|
|
301
|
+
char buffer[8];
|
|
302
|
+
bool *buffers;
|
|
303
|
+
|
|
304
|
+
ret = t_create_ring(1, &ring, 0);
|
|
305
|
+
if (ret == T_SETUP_SKIP)
|
|
306
|
+
return T_EXIT_SKIP;
|
|
307
|
+
else if (ret != T_SETUP_OK)
|
|
308
|
+
return T_EXIT_FAIL;
|
|
309
|
+
|
|
310
|
+
if (!use_mmap) {
|
|
311
|
+
br = io_uring_setup_buf_ring(&ring, entries, bgid, 0, &ret);
|
|
312
|
+
if (!br) {
|
|
313
|
+
/* by now should have checked if this is supported or not */
|
|
314
|
+
fprintf(stderr, "Buffer ring register failed %d\n", ret);
|
|
315
|
+
return T_EXIT_FAIL;
|
|
316
|
+
}
|
|
317
|
+
} else {
|
|
318
|
+
struct io_uring_buf_reg reg = {
|
|
319
|
+
.ring_entries = entries,
|
|
320
|
+
.bgid = bgid,
|
|
321
|
+
.flags = IOU_PBUF_RING_MMAP,
|
|
322
|
+
};
|
|
323
|
+
size_t ring_size;
|
|
324
|
+
off_t off;
|
|
325
|
+
|
|
326
|
+
ret = io_uring_register_buf_ring(&ring, ®, 0);
|
|
327
|
+
if (ret) {
|
|
328
|
+
if (ret == -EINVAL)
|
|
329
|
+
return T_EXIT_SKIP;
|
|
330
|
+
fprintf(stderr, "mmap ring register failed %d\n", ret);
|
|
331
|
+
return T_EXIT_FAIL;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
off = IORING_OFF_PBUF_RING |
|
|
335
|
+
(unsigned long long) bgid << IORING_OFF_PBUF_SHIFT;
|
|
336
|
+
ring_size = sizeof(struct io_uring_buf) * entries;
|
|
337
|
+
br = mmap(NULL, ring_size, PROT_READ | PROT_WRITE,
|
|
338
|
+
MAP_SHARED | MAP_POPULATE, ring.ring_fd, off);
|
|
339
|
+
if (br == MAP_FAILED) {
|
|
340
|
+
perror("mmap");
|
|
341
|
+
return T_EXIT_FAIL;
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
buffers = malloc(sizeof(bool) * entries);
|
|
346
|
+
if (!buffers)
|
|
347
|
+
return T_EXIT_SKIP;
|
|
348
|
+
|
|
349
|
+
read_fd = open("/dev/zero", O_RDONLY);
|
|
350
|
+
if (read_fd < 0)
|
|
351
|
+
return T_EXIT_SKIP;
|
|
352
|
+
|
|
353
|
+
for (loop = 0; loop < loops; loop++) {
|
|
354
|
+
memset(buffers, 0, sizeof(bool) * entries);
|
|
355
|
+
for (idx = 0; idx < entries; idx++)
|
|
356
|
+
io_uring_buf_ring_add(br, buffer, sizeof(buffer), idx, ring_mask, idx);
|
|
357
|
+
io_uring_buf_ring_advance(br, entries);
|
|
358
|
+
|
|
359
|
+
for (idx = 0; idx < entries; idx++) {
|
|
360
|
+
memset(buffer, 1, sizeof(buffer));
|
|
361
|
+
ret = test_one_read(read_fd, bgid, &ring);
|
|
362
|
+
if (ret < 0) {
|
|
363
|
+
fprintf(stderr, "bad run %d/%d = %d\n", loop, idx, ret);
|
|
364
|
+
return T_EXIT_FAIL;
|
|
365
|
+
}
|
|
366
|
+
if (buffers[ret]) {
|
|
367
|
+
fprintf(stderr, "reused buffer %d/%d = %d!\n", loop, idx, ret);
|
|
368
|
+
return T_EXIT_FAIL;
|
|
369
|
+
}
|
|
370
|
+
if (buffer[0] != 0) {
|
|
371
|
+
fprintf(stderr, "unexpected read %d %d/%d = %d!\n",
|
|
372
|
+
(int)buffer[0], loop, idx, ret);
|
|
373
|
+
return T_EXIT_FAIL;
|
|
374
|
+
}
|
|
375
|
+
if (buffer[1] != 1) {
|
|
376
|
+
fprintf(stderr, "unexpected spilled read %d %d/%d = %d!\n",
|
|
377
|
+
(int)buffer[1], loop, idx, ret);
|
|
378
|
+
return T_EXIT_FAIL;
|
|
379
|
+
}
|
|
380
|
+
buffers[ret] = true;
|
|
381
|
+
}
|
|
382
|
+
ret = test_one_read(read_fd, bgid, &ring);
|
|
383
|
+
if (ret != -ENOBUFS) {
|
|
384
|
+
fprintf(stderr, "expected enobufs run %d = %d\n", loop, ret);
|
|
385
|
+
return T_EXIT_FAIL;
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
ret = io_uring_unregister_buf_ring(&ring, bgid);
|
|
391
|
+
if (ret) {
|
|
392
|
+
fprintf(stderr, "Buffer ring register failed %d\n", ret);
|
|
393
|
+
return T_EXIT_FAIL;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
close(read_fd);
|
|
397
|
+
io_uring_queue_exit(&ring);
|
|
398
|
+
free(buffers);
|
|
399
|
+
return T_EXIT_PASS;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
int main(int argc, char *argv[])
|
|
403
|
+
{
|
|
404
|
+
int bgids[] = { 1, 127, -1 };
|
|
405
|
+
int entries[] = {1, 32768, 4096, -1 };
|
|
406
|
+
int ret, i;
|
|
407
|
+
|
|
408
|
+
if (argc > 1)
|
|
409
|
+
return T_EXIT_SKIP;
|
|
410
|
+
|
|
411
|
+
pagesize = getpagesize();
|
|
412
|
+
|
|
413
|
+
for (i = 0; bgids[i] != -1; i++) {
|
|
414
|
+
ret = test_reg_unreg(bgids[i]);
|
|
415
|
+
if (ret) {
|
|
416
|
+
fprintf(stderr, "test_reg_unreg failed\n");
|
|
417
|
+
return T_EXIT_FAIL;
|
|
418
|
+
}
|
|
419
|
+
if (no_buf_ring)
|
|
420
|
+
break;
|
|
421
|
+
|
|
422
|
+
ret = test_bad_reg(bgids[i]);
|
|
423
|
+
if (ret) {
|
|
424
|
+
fprintf(stderr, "test_bad_reg failed\n");
|
|
425
|
+
return T_EXIT_FAIL;
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
ret = test_double_reg_unreg(bgids[i]);
|
|
429
|
+
if (ret) {
|
|
430
|
+
fprintf(stderr, "test_double_reg_unreg failed\n");
|
|
431
|
+
return T_EXIT_FAIL;
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
ret = test_mixed_reg(bgids[i]);
|
|
435
|
+
if (ret) {
|
|
436
|
+
fprintf(stderr, "test_mixed_reg failed\n");
|
|
437
|
+
return T_EXIT_FAIL;
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
ret = test_mixed_reg2(bgids[i]);
|
|
441
|
+
if (ret) {
|
|
442
|
+
fprintf(stderr, "test_mixed_reg2 failed\n");
|
|
443
|
+
return T_EXIT_FAIL;
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
ret = test_full_page_reg(bgids[i]);
|
|
447
|
+
if (ret == T_EXIT_FAIL) {
|
|
448
|
+
fprintf(stderr, "test_full_page_reg failed\n");
|
|
449
|
+
return T_EXIT_FAIL;
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
for (i = 0; !no_buf_ring && entries[i] != -1; i++) {
|
|
454
|
+
ret = test_running(2, entries[i], 3, 0);
|
|
455
|
+
if (ret) {
|
|
456
|
+
fprintf(stderr, "test_running(%d) failed\n", entries[i]);
|
|
457
|
+
return T_EXIT_FAIL;
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
for (i = 0; !no_buf_ring && entries[i] != -1; i++) {
|
|
462
|
+
ret = test_running(2, entries[i], 3, 1);
|
|
463
|
+
if (ret == T_EXIT_SKIP) {
|
|
464
|
+
break;
|
|
465
|
+
} else if (ret != T_EXIT_PASS) {
|
|
466
|
+
fprintf(stderr, "test_running(%d) mmap failed\n", entries[i]);
|
|
467
|
+
return T_EXIT_FAIL;
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
|
|
472
|
+
return T_EXIT_PASS;
|
|
473
|
+
}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/* SPDX-License-Identifier: MIT */
|
|
2
|
+
/*
|
|
3
|
+
* Test 5.7 regression with task_work not being run while a task is
|
|
4
|
+
* waiting on another event in the kernel.
|
|
5
|
+
*/
|
|
6
|
+
#include <errno.h>
|
|
7
|
+
#include <poll.h>
|
|
8
|
+
#include <stdio.h>
|
|
9
|
+
#include <stdlib.h>
|
|
10
|
+
#include <sys/eventfd.h>
|
|
11
|
+
#include <unistd.h>
|
|
12
|
+
#include <pthread.h>
|
|
13
|
+
#include "liburing.h"
|
|
14
|
+
#include "helpers.h"
|
|
15
|
+
|
|
16
|
+
static int use_sqpoll = 0;
|
|
17
|
+
|
|
18
|
+
static void notify_fd(int fd)
|
|
19
|
+
{
|
|
20
|
+
char buf[8] = {0, 0, 0, 0, 0, 0, 1};
|
|
21
|
+
int ret;
|
|
22
|
+
|
|
23
|
+
ret = write(fd, &buf, 8);
|
|
24
|
+
if (ret < 0)
|
|
25
|
+
perror("write");
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
static void *delay_set_fd_from_thread(void *data)
|
|
29
|
+
{
|
|
30
|
+
int fd = (intptr_t) data;
|
|
31
|
+
|
|
32
|
+
sleep(1);
|
|
33
|
+
notify_fd(fd);
|
|
34
|
+
return NULL;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
int main(int argc, char *argv[])
|
|
38
|
+
{
|
|
39
|
+
struct io_uring_params p = {};
|
|
40
|
+
struct io_uring ring;
|
|
41
|
+
int loop_fd, other_fd;
|
|
42
|
+
struct io_uring_sqe *sqe;
|
|
43
|
+
struct io_uring_cqe *cqe = NULL;
|
|
44
|
+
int ret, use_fd;
|
|
45
|
+
char buf[8] = {0, 0, 0, 0, 0, 0, 1};
|
|
46
|
+
pthread_t tid;
|
|
47
|
+
|
|
48
|
+
if (argc > 1)
|
|
49
|
+
return T_EXIT_SKIP;
|
|
50
|
+
|
|
51
|
+
/* Create an eventfd to be registered with the loop to be
|
|
52
|
+
* notified of events being ready
|
|
53
|
+
*/
|
|
54
|
+
loop_fd = eventfd(0, EFD_CLOEXEC);
|
|
55
|
+
if (loop_fd == -1) {
|
|
56
|
+
fprintf(stderr, "eventfd errno=%d\n", errno);
|
|
57
|
+
return T_EXIT_FAIL;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/* Create an eventfd that can create events */
|
|
61
|
+
use_fd = other_fd = eventfd(0, EFD_CLOEXEC);
|
|
62
|
+
if (other_fd == -1) {
|
|
63
|
+
fprintf(stderr, "eventfd errno=%d\n", errno);
|
|
64
|
+
return T_EXIT_FAIL;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (use_sqpoll)
|
|
68
|
+
p.flags = IORING_SETUP_SQPOLL;
|
|
69
|
+
|
|
70
|
+
/* Setup the ring with a registered event fd to be notified on events */
|
|
71
|
+
ret = t_create_ring_params(8, &ring, &p);
|
|
72
|
+
if (ret == T_SETUP_SKIP)
|
|
73
|
+
return T_EXIT_PASS;
|
|
74
|
+
else if (ret < 0)
|
|
75
|
+
return ret;
|
|
76
|
+
|
|
77
|
+
ret = io_uring_register_eventfd(&ring, loop_fd);
|
|
78
|
+
if (ret < 0) {
|
|
79
|
+
fprintf(stderr, "register_eventfd=%d\n", ret);
|
|
80
|
+
return T_EXIT_FAIL;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (use_sqpoll) {
|
|
84
|
+
ret = io_uring_register_files(&ring, &other_fd, 1);
|
|
85
|
+
if (ret < 0) {
|
|
86
|
+
fprintf(stderr, "register_files=%d\n", ret);
|
|
87
|
+
return T_EXIT_FAIL;
|
|
88
|
+
}
|
|
89
|
+
use_fd = 0;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/* Submit a poll operation to wait on an event in other_fd */
|
|
93
|
+
sqe = io_uring_get_sqe(&ring);
|
|
94
|
+
io_uring_prep_poll_add(sqe, use_fd, POLLIN);
|
|
95
|
+
sqe->user_data = 1;
|
|
96
|
+
if (use_sqpoll)
|
|
97
|
+
sqe->flags |= IOSQE_FIXED_FILE;
|
|
98
|
+
ret = io_uring_submit(&ring);
|
|
99
|
+
if (ret != 1) {
|
|
100
|
+
fprintf(stderr, "submit=%d\n", ret);
|
|
101
|
+
return T_EXIT_FAIL;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/*
|
|
105
|
+
* CASE 3: Hangs forever in Linux 5.7.5; Works in Linux 5.6.0 When this
|
|
106
|
+
* code is uncommented, we don't se a notification on other_fd until
|
|
107
|
+
* _after_ we have started the read on loop_fd. In that case, the read() on
|
|
108
|
+
* loop_fd seems to hang forever.
|
|
109
|
+
*/
|
|
110
|
+
pthread_create(&tid, NULL, delay_set_fd_from_thread,
|
|
111
|
+
(void*) (intptr_t) other_fd);
|
|
112
|
+
|
|
113
|
+
/* Wait on the event fd for an event to be ready */
|
|
114
|
+
do {
|
|
115
|
+
ret = read(loop_fd, buf, 8);
|
|
116
|
+
} while (ret < 0 && errno == EINTR);
|
|
117
|
+
|
|
118
|
+
if (ret < 0) {
|
|
119
|
+
perror("read");
|
|
120
|
+
return T_EXIT_FAIL;
|
|
121
|
+
} else if (ret != 8) {
|
|
122
|
+
fprintf(stderr, "Odd-sized eventfd read: %d\n", ret);
|
|
123
|
+
return T_EXIT_FAIL;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
ret = io_uring_wait_cqe(&ring, &cqe);
|
|
128
|
+
if (ret) {
|
|
129
|
+
fprintf(stderr, "wait_cqe=%d\n", ret);
|
|
130
|
+
return ret;
|
|
131
|
+
}
|
|
132
|
+
if (cqe->res < 0) {
|
|
133
|
+
fprintf(stderr, "cqe->res=%d\n", cqe->res);
|
|
134
|
+
return T_EXIT_FAIL;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
io_uring_cqe_seen(&ring, cqe);
|
|
138
|
+
return T_EXIT_PASS;
|
|
139
|
+
}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
|
|
3
|
+
#define _GNU_SOURCE 1
|
|
4
|
+
#define _FILE_OFFSET_BITS 64
|
|
5
|
+
|
|
6
|
+
// Test program for io_uring IORING_OP_CLOSE with O_PATH file.
|
|
7
|
+
// Author: Clayton Harris <bugs@claycon.org>, 2020-06-07
|
|
8
|
+
|
|
9
|
+
// linux 5.6.14-300.fc32.x86_64
|
|
10
|
+
// gcc 10.1.1-1.fc32
|
|
11
|
+
// liburing.x86_64 0.5-1.fc32
|
|
12
|
+
|
|
13
|
+
// gcc -O2 -Wall -Wextra -std=c11 -o close_opath close_opath.c -luring
|
|
14
|
+
// ./close_opath testfilepath
|
|
15
|
+
|
|
16
|
+
#include <errno.h>
|
|
17
|
+
#include <fcntl.h>
|
|
18
|
+
#include <sys/stat.h>
|
|
19
|
+
#include <stdio.h>
|
|
20
|
+
#include <string.h>
|
|
21
|
+
#include <unistd.h>
|
|
22
|
+
|
|
23
|
+
#include "liburing.h"
|
|
24
|
+
|
|
25
|
+
typedef struct
|
|
26
|
+
{
|
|
27
|
+
const char *const flnames;
|
|
28
|
+
const int oflags;
|
|
29
|
+
} oflgs_t;
|
|
30
|
+
|
|
31
|
+
static int test_io_uring_close(struct io_uring *ring, int fd)
|
|
32
|
+
{
|
|
33
|
+
struct io_uring_sqe *sqe;
|
|
34
|
+
struct io_uring_cqe *cqe;
|
|
35
|
+
int ret;
|
|
36
|
+
|
|
37
|
+
sqe = io_uring_get_sqe(ring);
|
|
38
|
+
if (!sqe) {
|
|
39
|
+
fprintf(stderr, "io_uring_get_sqe() failed\n");
|
|
40
|
+
return -ENOENT;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
io_uring_prep_close(sqe, fd);
|
|
44
|
+
|
|
45
|
+
ret = io_uring_submit(ring);
|
|
46
|
+
if (ret < 0) {
|
|
47
|
+
fprintf(stderr, "io_uring_submit() failed, errno %d: %s\n",
|
|
48
|
+
-ret, strerror(-ret));
|
|
49
|
+
return ret;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
ret = io_uring_wait_cqe(ring, &cqe);
|
|
53
|
+
if (ret < 0) {
|
|
54
|
+
fprintf(stderr, "io_uring_wait_cqe() failed, errno %d: %s\n",
|
|
55
|
+
-ret, strerror(-ret));
|
|
56
|
+
return ret;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
ret = cqe->res;
|
|
60
|
+
io_uring_cqe_seen(ring, cqe);
|
|
61
|
+
|
|
62
|
+
if (ret < 0 && ret != -EOPNOTSUPP && ret != -EINVAL && ret != -EBADF) {
|
|
63
|
+
fprintf(stderr, "io_uring close() failed, errno %d: %s\n",
|
|
64
|
+
-ret, strerror(-ret));
|
|
65
|
+
return ret;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return 0;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
static int open_file(const char *path, const oflgs_t *oflgs)
|
|
72
|
+
{
|
|
73
|
+
int fd;
|
|
74
|
+
|
|
75
|
+
fd = openat(AT_FDCWD, path, oflgs->oflags, 0);
|
|
76
|
+
if (fd < 0) {
|
|
77
|
+
int err = errno;
|
|
78
|
+
fprintf(stderr, "openat(%s, %s) failed, errno %d: %s\n",
|
|
79
|
+
path, oflgs->flnames, err, strerror(err));
|
|
80
|
+
return -err;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return fd;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
int main(int argc, char *argv[])
|
|
87
|
+
{
|
|
88
|
+
const char *fname = ".";
|
|
89
|
+
struct io_uring ring;
|
|
90
|
+
int ret, i;
|
|
91
|
+
static const oflgs_t oflgs[] = {
|
|
92
|
+
{ "O_RDONLY", O_RDONLY },
|
|
93
|
+
{ "O_PATH", O_PATH }
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
ret = io_uring_queue_init(2, &ring, 0);
|
|
97
|
+
if (ret < 0) {
|
|
98
|
+
fprintf(stderr, "io_uring_queue_init() failed, errno %d: %s\n",
|
|
99
|
+
-ret, strerror(-ret));
|
|
100
|
+
return 0x02;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
#define OFLGS_SIZE (sizeof(oflgs) / sizeof(oflgs[0]))
|
|
104
|
+
|
|
105
|
+
ret = 0;
|
|
106
|
+
for (i = 0; i < OFLGS_SIZE; i++) {
|
|
107
|
+
int fd;
|
|
108
|
+
|
|
109
|
+
fd = open_file(fname, &oflgs[i]);
|
|
110
|
+
if (fd < 0) {
|
|
111
|
+
ret |= 0x02;
|
|
112
|
+
break;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/* Should always succeed */
|
|
116
|
+
if (test_io_uring_close(&ring, fd) < 0)
|
|
117
|
+
ret |= 0x04 << i;
|
|
118
|
+
}
|
|
119
|
+
#undef OFLGS_SIZE
|
|
120
|
+
|
|
121
|
+
io_uring_queue_exit(&ring);
|
|
122
|
+
return ret;
|
|
123
|
+
}
|