polyphony 0.98 → 0.99.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 +4 -4
- data/.github/FUNDING.yml +1 -1
- data/.rubocop.yml +3 -3
- data/.yardopts +30 -0
- data/CHANGELOG.md +11 -0
- data/LICENSE +1 -1
- data/README.md +63 -29
- data/Rakefile +1 -5
- data/TODO.md +0 -4
- data/docs/{main-concepts/concurrency.md → concurrency.md} +2 -9
- data/docs/{main-concepts/design-principles.md → design-principles.md} +3 -9
- data/docs/{main-concepts/exception-handling.md → exception-handling.md} +2 -9
- data/docs/{main-concepts/extending.md → extending.md} +2 -9
- data/docs/faq.md +3 -16
- data/docs/{main-concepts/fiber-scheduling.md → fiber-scheduling.md} +1 -9
- data/docs/link_rewriter.rb +16 -0
- data/docs/{getting-started/overview.md → overview.md} +1 -30
- data/docs/{getting-started/tutorial.md → tutorial.md} +3 -28
- data/docs/{_posts/2020-07-26-polyphony-0.44.md → whats-new.md} +3 -1
- data/examples/adapters/redis_client.rb +3 -2
- data/examples/io/echo_server.rb +1 -1
- data/examples/io/echo_server_plain_ruby.rb +26 -0
- data/examples/io/https_server_sni_2.rb +14 -8
- data/ext/polyphony/backend_io_uring.c +154 -9
- data/ext/polyphony/backend_io_uring_context.c +21 -12
- data/ext/polyphony/backend_io_uring_context.h +12 -7
- data/ext/polyphony/backend_libev.c +1 -1
- data/ext/polyphony/extconf.rb +25 -8
- data/ext/polyphony/fiber.c +79 -2
- data/ext/polyphony/io_extensions.c +53 -0
- data/ext/polyphony/libev.h +0 -2
- data/ext/polyphony/pipe.c +42 -2
- data/ext/polyphony/polyphony.c +345 -31
- data/ext/polyphony/polyphony.h +9 -2
- data/ext/polyphony/queue.c +181 -0
- data/ext/polyphony/ring_buffer.c +0 -1
- data/ext/polyphony/runqueue.c +8 -1
- data/ext/polyphony/runqueue_ring_buffer.c +13 -0
- data/ext/polyphony/runqueue_ring_buffer.h +2 -1
- data/ext/polyphony/socket_extensions.c +6 -0
- data/ext/polyphony/thread.c +34 -2
- data/lib/polyphony/adapters/process.rb +11 -1
- data/lib/polyphony/adapters/sequel.rb +1 -1
- data/lib/polyphony/core/channel.rb +2 -0
- data/lib/polyphony/core/debug.rb +1 -1
- data/lib/polyphony/core/global_api.rb +25 -24
- data/lib/polyphony/core/resource_pool.rb +7 -6
- data/lib/polyphony/core/sync.rb +55 -2
- data/lib/polyphony/core/thread_pool.rb +3 -3
- data/lib/polyphony/core/timer.rb +8 -8
- data/lib/polyphony/extensions/exception.rb +2 -0
- data/lib/polyphony/extensions/fiber.rb +15 -13
- data/lib/polyphony/extensions/io.rb +161 -16
- data/lib/polyphony/extensions/kernel.rb +20 -2
- data/lib/polyphony/extensions/openssl.rb +101 -12
- data/lib/polyphony/extensions/pipe.rb +103 -7
- data/lib/polyphony/extensions/process.rb +13 -1
- data/lib/polyphony/extensions/socket.rb +93 -27
- data/lib/polyphony/extensions/thread.rb +9 -1
- data/lib/polyphony/extensions/timeout.rb +1 -1
- data/lib/polyphony/version.rb +2 -1
- data/lib/polyphony.rb +27 -7
- data/polyphony.gemspec +1 -8
- data/test/stress.rb +1 -1
- data/test/test_global_api.rb +45 -7
- data/test/test_io.rb +6 -7
- data/test/test_socket.rb +157 -0
- data/test/test_sync.rb +42 -1
- data/test/test_timer.rb +5 -5
- data/vendor/liburing/.github/workflows/build.yml +7 -16
- data/vendor/liburing/.gitignore +5 -0
- data/vendor/liburing/CHANGELOG +23 -1
- data/vendor/liburing/Makefile +4 -3
- data/vendor/liburing/Makefile.common +1 -0
- data/vendor/liburing/README +48 -0
- data/vendor/liburing/configure +76 -6
- data/vendor/liburing/debian/changelog +11 -0
- data/vendor/liburing/debian/control +7 -16
- data/vendor/liburing/debian/liburing-dev.manpages +3 -6
- data/vendor/liburing/debian/liburing2.install +1 -0
- data/vendor/liburing/debian/liburing2.symbols +56 -0
- data/vendor/liburing/debian/rules +15 -68
- data/vendor/liburing/examples/Makefile +4 -0
- data/vendor/liburing/examples/io_uring-close-test.c +123 -0
- data/vendor/liburing/examples/io_uring-udp.c +1 -1
- data/vendor/liburing/examples/send-zerocopy.c +315 -56
- data/vendor/liburing/examples/ucontext-cp.c +2 -17
- data/vendor/liburing/liburing-ffi.pc.in +12 -0
- data/vendor/liburing/liburing.pc.in +1 -1
- data/vendor/liburing/liburing.spec +1 -1
- data/vendor/liburing/make-debs.sh +3 -3
- data/vendor/liburing/man/IO_URING_CHECK_VERSION.3 +1 -0
- data/vendor/liburing/man/IO_URING_VERSION_MAJOR.3 +1 -0
- data/vendor/liburing/man/IO_URING_VERSION_MINOR.3 +1 -0
- data/vendor/liburing/man/io_uring_buf_ring_add.3 +6 -6
- data/vendor/liburing/man/io_uring_check_version.3 +72 -0
- data/vendor/liburing/man/io_uring_close_ring_fd.3 +43 -0
- data/vendor/liburing/man/io_uring_major_version.3 +1 -0
- data/vendor/liburing/man/io_uring_minor_version.3 +1 -0
- data/vendor/liburing/man/io_uring_prep_accept.3 +1 -1
- data/vendor/liburing/man/io_uring_prep_fgetxattr.3 +1 -0
- data/vendor/liburing/man/io_uring_prep_fsetxattr.3 +1 -0
- data/vendor/liburing/man/io_uring_prep_getxattr.3 +61 -0
- data/vendor/liburing/man/io_uring_prep_link_timeout.3 +94 -0
- data/vendor/liburing/man/io_uring_prep_msg_ring.3 +22 -2
- data/vendor/liburing/man/io_uring_prep_msg_ring_cqe_flags.3 +1 -0
- data/vendor/liburing/man/io_uring_prep_poll_add.3 +1 -1
- data/vendor/liburing/man/io_uring_prep_provide_buffers.3 +18 -9
- data/vendor/liburing/man/io_uring_prep_readv.3 +3 -3
- data/vendor/liburing/man/io_uring_prep_readv2.3 +3 -3
- data/vendor/liburing/man/io_uring_prep_recv.3 +5 -5
- data/vendor/liburing/man/io_uring_prep_recvmsg.3 +4 -4
- data/vendor/liburing/man/io_uring_prep_send.3 +9 -0
- data/vendor/liburing/man/io_uring_prep_send_set_addr.3 +38 -0
- data/vendor/liburing/man/io_uring_prep_send_zc.3 +39 -7
- data/vendor/liburing/man/io_uring_prep_send_zc_fixed.3 +1 -0
- data/vendor/liburing/man/io_uring_prep_sendmsg.3 +20 -0
- data/vendor/liburing/man/io_uring_prep_sendmsg_zc.3 +1 -0
- data/vendor/liburing/man/io_uring_prep_setxattr.3 +64 -0
- data/vendor/liburing/man/io_uring_prep_splice.3 +40 -0
- data/vendor/liburing/man/io_uring_prep_writev.3 +2 -2
- data/vendor/liburing/man/io_uring_prep_writev2.3 +2 -2
- data/vendor/liburing/man/io_uring_recvmsg_out.3 +13 -9
- data/vendor/liburing/man/io_uring_register.2 +15 -9
- data/vendor/liburing/man/io_uring_register_buf_ring.3 +4 -4
- data/vendor/liburing/man/io_uring_register_buffers.3 +49 -6
- data/vendor/liburing/man/io_uring_register_buffers_sparse.3 +1 -0
- data/vendor/liburing/man/io_uring_register_buffers_tags.3 +1 -0
- data/vendor/liburing/man/io_uring_register_buffers_update_tag.3 +1 -0
- data/vendor/liburing/man/io_uring_register_files.3 +60 -5
- data/vendor/liburing/man/io_uring_register_files_tags.3 +1 -0
- data/vendor/liburing/man/io_uring_register_files_update.3 +1 -0
- data/vendor/liburing/man/io_uring_register_files_update_tag.3 +1 -0
- data/vendor/liburing/man/io_uring_setup.2 +31 -2
- data/vendor/liburing/man/io_uring_wait_cqe_timeout.3 +1 -1
- data/vendor/liburing/src/Makefile +25 -3
- data/vendor/liburing/src/ffi.c +15 -0
- data/vendor/liburing/src/include/liburing/io_uring.h +30 -7
- data/vendor/liburing/src/include/liburing.h +190 -148
- data/vendor/liburing/src/int_flags.h +1 -0
- data/vendor/liburing/src/lib.h +5 -16
- data/vendor/liburing/src/liburing-ffi.map +172 -0
- data/vendor/liburing/src/liburing.map +11 -0
- data/vendor/liburing/src/nolibc.c +9 -2
- data/vendor/liburing/src/queue.c +2 -2
- data/vendor/liburing/src/register.c +66 -96
- data/vendor/liburing/src/setup.c +5 -4
- data/vendor/liburing/src/version.c +21 -0
- data/vendor/liburing/test/232c93d07b74.c +3 -3
- data/vendor/liburing/test/35fa71a030ca.c +3 -3
- data/vendor/liburing/test/500f9fbadef8.c +2 -0
- data/vendor/liburing/test/917257daa0fe.c +1 -1
- data/vendor/liburing/test/Makefile +27 -7
- data/vendor/liburing/test/a0908ae19763.c +2 -2
- data/vendor/liburing/test/a4c0b3decb33.c +2 -2
- data/vendor/liburing/test/accept-link.c +4 -4
- data/vendor/liburing/test/accept-reuse.c +5 -7
- data/vendor/liburing/test/accept.c +34 -31
- data/vendor/liburing/test/b19062a56726.c +1 -1
- data/vendor/liburing/test/buf-ring.c +58 -4
- data/vendor/liburing/test/ce593a6c480a.c +2 -2
- data/vendor/liburing/test/close-opath.c +2 -1
- data/vendor/liburing/test/connect.c +8 -0
- data/vendor/liburing/test/cq-overflow.c +14 -8
- data/vendor/liburing/test/d4ae271dfaae.c +1 -1
- data/vendor/liburing/test/defer-taskrun.c +64 -9
- data/vendor/liburing/test/defer.c +1 -1
- data/vendor/liburing/test/double-poll-crash.c +3 -3
- data/vendor/liburing/test/eeed8b54e0df.c +8 -3
- data/vendor/liburing/test/eploop.c +74 -0
- data/vendor/liburing/test/eventfd-ring.c +1 -1
- data/vendor/liburing/test/eventfd.c +1 -1
- data/vendor/liburing/test/evloop.c +73 -0
- data/vendor/liburing/test/exit-no-cleanup.c +1 -1
- data/vendor/liburing/test/fadvise.c +1 -1
- data/vendor/liburing/test/fc2a85cb02ef.c +3 -3
- data/vendor/liburing/test/fd-pass.c +35 -16
- data/vendor/liburing/test/file-register.c +61 -0
- data/vendor/liburing/test/file-verify.c +2 -2
- data/vendor/liburing/test/files-exit-hang-timeout.c +2 -2
- data/vendor/liburing/test/fixed-link.c +1 -1
- data/vendor/liburing/test/fsnotify.c +118 -0
- data/vendor/liburing/test/hardlink.c +1 -1
- data/vendor/liburing/test/helpers.c +54 -2
- data/vendor/liburing/test/helpers.h +4 -0
- data/vendor/liburing/test/io-cancel.c +3 -1
- data/vendor/liburing/test/io_uring_passthrough.c +39 -8
- data/vendor/liburing/test/io_uring_setup.c +3 -80
- data/vendor/liburing/test/iopoll-overflow.c +118 -0
- data/vendor/liburing/test/iopoll.c +90 -4
- data/vendor/liburing/test/lfs-openat-write.c +7 -9
- data/vendor/liburing/test/lfs-openat.c +6 -8
- data/vendor/liburing/test/link_drain.c +31 -5
- data/vendor/liburing/test/madvise.c +1 -1
- data/vendor/liburing/test/msg-ring-flags.c +192 -0
- data/vendor/liburing/test/msg-ring-overflow.c +159 -0
- data/vendor/liburing/test/msg-ring.c +173 -13
- data/vendor/liburing/test/multicqes_drain.c +22 -19
- data/vendor/liburing/test/nvme.h +4 -3
- data/vendor/liburing/test/pipe-bug.c +95 -0
- data/vendor/liburing/test/poll-link.c +3 -3
- data/vendor/liburing/test/poll-many.c +41 -19
- data/vendor/liburing/test/poll-mshot-overflow.c +105 -2
- data/vendor/liburing/test/poll-race-mshot.c +292 -0
- data/vendor/liburing/test/poll-race.c +105 -0
- data/vendor/liburing/test/poll.c +244 -26
- data/vendor/liburing/test/pollfree.c +5 -5
- data/vendor/liburing/test/read-before-exit.c +20 -3
- data/vendor/liburing/test/read-write.c +2 -0
- data/vendor/liburing/test/recv-multishot.c +96 -3
- data/vendor/liburing/test/reg-reg-ring.c +90 -0
- data/vendor/liburing/test/rename.c +1 -1
- data/vendor/liburing/test/ring-leak.c +0 -1
- data/vendor/liburing/test/ring-leak2.c +1 -1
- data/vendor/liburing/test/ringbuf-read.c +10 -6
- data/vendor/liburing/test/send-zerocopy.c +273 -103
- data/vendor/liburing/test/send_recv.c +7 -4
- data/vendor/liburing/test/sendmsg_fs_cve.c +2 -2
- data/vendor/liburing/test/single-issuer.c +7 -9
- data/vendor/liburing/test/skip-cqe.c +3 -4
- data/vendor/liburing/test/socket.c +0 -1
- data/vendor/liburing/test/sq-poll-dup.c +10 -3
- data/vendor/liburing/test/sq-poll-kthread.c +1 -1
- data/vendor/liburing/test/sq-poll-share.c +3 -2
- data/vendor/liburing/test/sqpoll-cancel-hang.c +17 -6
- data/vendor/liburing/test/sqpoll-disable-exit.c +4 -4
- data/vendor/liburing/test/symlink.c +2 -1
- data/vendor/liburing/test/test.h +2 -1
- data/vendor/liburing/test/timeout-new.c +11 -7
- data/vendor/liburing/test/timeout.c +1 -2
- data/vendor/liburing/test/unlink.c +1 -1
- data/vendor/liburing/test/version.c +25 -0
- data/vendor/liburing/test/wakeup-hang.c +1 -1
- data/vendor/liburing/test/xattr.c +8 -4
- metadata +57 -44
- data/docs/_config.yml +0 -64
- data/docs/_includes/head.html +0 -40
- data/docs/_includes/title.html +0 -1
- data/docs/_sass/custom/custom.scss +0 -10
- data/docs/_sass/overrides.scss +0 -0
- data/docs/api-reference/exception.md +0 -31
- data/docs/api-reference/fiber.md +0 -425
- data/docs/api-reference/index.md +0 -9
- data/docs/api-reference/io.md +0 -36
- data/docs/api-reference/object.md +0 -99
- data/docs/api-reference/polyphony-baseexception.md +0 -33
- data/docs/api-reference/polyphony-cancel.md +0 -26
- data/docs/api-reference/polyphony-moveon.md +0 -24
- data/docs/api-reference/polyphony-net.md +0 -20
- data/docs/api-reference/polyphony-process.md +0 -28
- data/docs/api-reference/polyphony-resourcepool.md +0 -59
- data/docs/api-reference/polyphony-restart.md +0 -18
- data/docs/api-reference/polyphony-terminate.md +0 -18
- data/docs/api-reference/polyphony-threadpool.md +0 -67
- data/docs/api-reference/polyphony-throttler.md +0 -77
- data/docs/api-reference/polyphony.md +0 -36
- data/docs/api-reference/thread.md +0 -88
- data/docs/favicon.ico +0 -0
- data/docs/getting-started/index.md +0 -10
- data/docs/getting-started/installing.md +0 -34
- data/vendor/liburing/debian/compat +0 -1
- data/vendor/liburing/debian/liburing1-udeb.install +0 -1
- data/vendor/liburing/debian/liburing1.install +0 -1
- data/vendor/liburing/debian/liburing1.symbols +0 -32
- /data/{docs/assets/img → assets}/echo-fibers.svg +0 -0
- /data/{docs → assets}/polyphony-logo.png +0 -0
- /data/{docs/assets/img → assets}/sleeping-fiber.svg +0 -0
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/* SPDX-License-Identifier: MIT */
|
|
2
|
+
/*
|
|
3
|
+
* Description: test fsnotify access off O_DIRECT read
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
#include "helpers.h"
|
|
7
|
+
|
|
8
|
+
#ifdef CONFIG_HAVE_FANOTIFY
|
|
9
|
+
#include <stdio.h>
|
|
10
|
+
#include <stdlib.h>
|
|
11
|
+
#include <unistd.h>
|
|
12
|
+
#include <fcntl.h>
|
|
13
|
+
#include <sys/fanotify.h>
|
|
14
|
+
#include <sys/stat.h>
|
|
15
|
+
#include <sys/wait.h>
|
|
16
|
+
|
|
17
|
+
#include "liburing.h"
|
|
18
|
+
|
|
19
|
+
int main(int argc, char *argv[])
|
|
20
|
+
{
|
|
21
|
+
struct io_uring_sqe *sqe;
|
|
22
|
+
struct io_uring_cqe *cqe;
|
|
23
|
+
struct io_uring ring;
|
|
24
|
+
int fan, ret, fd, err;
|
|
25
|
+
char fname[64], *f;
|
|
26
|
+
struct stat sb;
|
|
27
|
+
void *buf;
|
|
28
|
+
|
|
29
|
+
fan = fanotify_init(FAN_CLASS_NOTIF|FAN_CLASS_CONTENT, 0);
|
|
30
|
+
if (fan < 0) {
|
|
31
|
+
if (errno == ENOSYS)
|
|
32
|
+
return T_EXIT_SKIP;
|
|
33
|
+
if (geteuid())
|
|
34
|
+
return T_EXIT_SKIP;
|
|
35
|
+
perror("fanotify_init");
|
|
36
|
+
return T_EXIT_FAIL;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
err = T_EXIT_FAIL;
|
|
40
|
+
if (argc > 1) {
|
|
41
|
+
f = argv[1];
|
|
42
|
+
fd = open(argv[1], O_RDONLY | O_DIRECT);
|
|
43
|
+
if (fd < 0 && errno == EINVAL)
|
|
44
|
+
return T_EXIT_SKIP;
|
|
45
|
+
} else {
|
|
46
|
+
sprintf(fname, ".fsnotify.%d", getpid());
|
|
47
|
+
f = fname;
|
|
48
|
+
t_create_file(fname, 8192);
|
|
49
|
+
fd = open(fname, O_RDONLY | O_DIRECT);
|
|
50
|
+
if (fd < 0 && errno == EINVAL) {
|
|
51
|
+
unlink(fname);
|
|
52
|
+
return T_EXIT_SKIP;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
if (fd < 0) {
|
|
56
|
+
perror("open");
|
|
57
|
+
goto out;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (fstat(fd, &sb) < 0) {
|
|
61
|
+
perror("fstat");
|
|
62
|
+
goto out;
|
|
63
|
+
}
|
|
64
|
+
if ((sb.st_mode & S_IFMT) != S_IFREG) {
|
|
65
|
+
err = T_EXIT_SKIP;
|
|
66
|
+
close(fd);
|
|
67
|
+
goto out;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
ret = fanotify_mark(fan, FAN_MARK_ADD, FAN_ACCESS|FAN_MODIFY, fd, NULL);
|
|
71
|
+
if (ret < 0) {
|
|
72
|
+
perror("fanotify_mark");
|
|
73
|
+
goto out;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (fork()) {
|
|
77
|
+
int wstat;
|
|
78
|
+
|
|
79
|
+
io_uring_queue_init(1, &ring, 0);
|
|
80
|
+
if (posix_memalign(&buf, 4096, 4096))
|
|
81
|
+
goto out;
|
|
82
|
+
sqe = io_uring_get_sqe(&ring);
|
|
83
|
+
io_uring_prep_read(sqe, fd, buf, 4096, 0);
|
|
84
|
+
io_uring_submit(&ring);
|
|
85
|
+
ret = io_uring_wait_cqe(&ring, &cqe);
|
|
86
|
+
if (ret) {
|
|
87
|
+
fprintf(stderr, "wait_ret=%d\n", ret);
|
|
88
|
+
goto out;
|
|
89
|
+
}
|
|
90
|
+
wait(&wstat);
|
|
91
|
+
if (!WEXITSTATUS(wstat))
|
|
92
|
+
err = T_EXIT_PASS;
|
|
93
|
+
} else {
|
|
94
|
+
struct fanotify_event_metadata m;
|
|
95
|
+
int fret;
|
|
96
|
+
|
|
97
|
+
fret = read(fan, &m, sizeof(m));
|
|
98
|
+
if (fret < 0)
|
|
99
|
+
perror("fanotify read");
|
|
100
|
+
/* fail if mask isn't right or pid indicates non-task context */
|
|
101
|
+
else if (!(m.mask & 1) || !m.pid)
|
|
102
|
+
exit(1);
|
|
103
|
+
exit(0);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
out:
|
|
107
|
+
if (f == fname)
|
|
108
|
+
unlink(fname);
|
|
109
|
+
return err;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
#else /* #ifdef CONFIG_HAVE_FANOTIFY */
|
|
113
|
+
|
|
114
|
+
int main(void)
|
|
115
|
+
{
|
|
116
|
+
return T_EXIT_SKIP;
|
|
117
|
+
}
|
|
118
|
+
#endif /* #ifdef CONFIG_HAVE_FANOTIFY */
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
#include <stdio.h>
|
|
9
9
|
#include <fcntl.h>
|
|
10
10
|
#include <unistd.h>
|
|
11
|
+
#include <stdarg.h>
|
|
11
12
|
#include <sys/types.h>
|
|
12
13
|
|
|
13
14
|
#include <arpa/inet.h>
|
|
@@ -134,7 +135,8 @@ enum t_setup_ret t_create_ring_params(int depth, struct io_uring *ring,
|
|
|
134
135
|
return T_SETUP_SKIP;
|
|
135
136
|
}
|
|
136
137
|
|
|
137
|
-
|
|
138
|
+
if (ret != -EINVAL)
|
|
139
|
+
fprintf(stderr, "queue_init: %s\n", strerror(-ret));
|
|
138
140
|
return ret;
|
|
139
141
|
}
|
|
140
142
|
|
|
@@ -173,7 +175,7 @@ int t_create_socket_pair(int fd[2], bool stream)
|
|
|
173
175
|
int val;
|
|
174
176
|
struct sockaddr_in serv_addr;
|
|
175
177
|
struct sockaddr *paddr;
|
|
176
|
-
|
|
178
|
+
socklen_t paddrlen;
|
|
177
179
|
|
|
178
180
|
type |= SOCK_CLOEXEC;
|
|
179
181
|
fd[0] = socket(AF_INET, type, 0);
|
|
@@ -266,3 +268,53 @@ bool t_probe_defer_taskrun(void)
|
|
|
266
268
|
io_uring_queue_exit(&ring);
|
|
267
269
|
return true;
|
|
268
270
|
}
|
|
271
|
+
|
|
272
|
+
/*
|
|
273
|
+
* Sync internal state with kernel ring state on the SQ side. Returns the
|
|
274
|
+
* number of pending items in the SQ ring, for the shared ring.
|
|
275
|
+
*/
|
|
276
|
+
unsigned __io_uring_flush_sq(struct io_uring *ring)
|
|
277
|
+
{
|
|
278
|
+
struct io_uring_sq *sq = &ring->sq;
|
|
279
|
+
unsigned tail = sq->sqe_tail;
|
|
280
|
+
|
|
281
|
+
if (sq->sqe_head != tail) {
|
|
282
|
+
sq->sqe_head = tail;
|
|
283
|
+
/*
|
|
284
|
+
* Ensure kernel sees the SQE updates before the tail update.
|
|
285
|
+
*/
|
|
286
|
+
if (!(ring->flags & IORING_SETUP_SQPOLL))
|
|
287
|
+
IO_URING_WRITE_ONCE(*sq->ktail, tail);
|
|
288
|
+
else
|
|
289
|
+
io_uring_smp_store_release(sq->ktail, tail);
|
|
290
|
+
}
|
|
291
|
+
/*
|
|
292
|
+
* This _may_ look problematic, as we're not supposed to be reading
|
|
293
|
+
* SQ->head without acquire semantics. When we're in SQPOLL mode, the
|
|
294
|
+
* kernel submitter could be updating this right now. For non-SQPOLL,
|
|
295
|
+
* task itself does it, and there's no potential race. But even for
|
|
296
|
+
* SQPOLL, the load is going to be potentially out-of-date the very
|
|
297
|
+
* instant it's done, regardless or whether or not it's done
|
|
298
|
+
* atomically. Worst case, we're going to be over-estimating what
|
|
299
|
+
* we can submit. The point is, we need to be able to deal with this
|
|
300
|
+
* situation regardless of any perceived atomicity.
|
|
301
|
+
*/
|
|
302
|
+
return tail - *sq->khead;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
/*
|
|
306
|
+
* Implementation of error(3), prints an error message and exits.
|
|
307
|
+
*/
|
|
308
|
+
void t_error(int status, int errnum, const char *format, ...)
|
|
309
|
+
{
|
|
310
|
+
va_list args;
|
|
311
|
+
va_start(args, format);
|
|
312
|
+
|
|
313
|
+
vfprintf(stderr, format, args);
|
|
314
|
+
if (errnum)
|
|
315
|
+
fprintf(stderr, ": %s", strerror(errnum));
|
|
316
|
+
|
|
317
|
+
fprintf(stderr, "\n");
|
|
318
|
+
va_end(args);
|
|
319
|
+
exit(status);
|
|
320
|
+
}
|
|
@@ -85,8 +85,12 @@ enum t_setup_ret t_register_buffers(struct io_uring *ring,
|
|
|
85
85
|
|
|
86
86
|
bool t_probe_defer_taskrun(void);
|
|
87
87
|
|
|
88
|
+
unsigned __io_uring_flush_sq(struct io_uring *ring);
|
|
89
|
+
|
|
88
90
|
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
|
|
89
91
|
|
|
92
|
+
void t_error(int status, int errnum, const char *format, ...);
|
|
93
|
+
|
|
90
94
|
#ifdef __cplusplus
|
|
91
95
|
}
|
|
92
96
|
#endif
|
|
@@ -161,6 +161,8 @@ static int test_io_cancel(const char *file, int do_write, int do_partial,
|
|
|
161
161
|
|
|
162
162
|
fd = open(file, O_RDWR | O_DIRECT);
|
|
163
163
|
if (fd < 0) {
|
|
164
|
+
if (errno == EINVAL)
|
|
165
|
+
return T_EXIT_SKIP;
|
|
164
166
|
perror("file open");
|
|
165
167
|
goto err;
|
|
166
168
|
}
|
|
@@ -540,7 +542,7 @@ int main(int argc, char *argv[])
|
|
|
540
542
|
int async = (i & 4) != 0;
|
|
541
543
|
|
|
542
544
|
ret = test_io_cancel(fname, write, partial, async);
|
|
543
|
-
if (ret) {
|
|
545
|
+
if (ret == T_EXIT_FAIL) {
|
|
544
546
|
fprintf(stderr, "test_io_cancel %d %d %d failed\n",
|
|
545
547
|
write, partial, async);
|
|
546
548
|
goto err;
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
#define BUFFERS (FILE_SIZE / BS)
|
|
19
19
|
|
|
20
20
|
static struct iovec *vecs;
|
|
21
|
+
static int no_pt;
|
|
21
22
|
|
|
22
23
|
/*
|
|
23
24
|
* Each offset in the file has the ((test_case / 2) * FILE_SIZE)
|
|
@@ -34,7 +35,8 @@ static int verify_buf(int tc, void *buf, off_t off)
|
|
|
34
35
|
ptr = buf;
|
|
35
36
|
for (i = 0; i < u_in_buf; i++) {
|
|
36
37
|
if (off != *ptr) {
|
|
37
|
-
fprintf(stderr, "Found %u, wanted %
|
|
38
|
+
fprintf(stderr, "Found %u, wanted %llu\n", *ptr,
|
|
39
|
+
(unsigned long long) off);
|
|
38
40
|
return 1;
|
|
39
41
|
}
|
|
40
42
|
ptr++;
|
|
@@ -205,6 +207,10 @@ static int __test_io(const char *file, struct io_uring *ring, int tc, int read,
|
|
|
205
207
|
goto err;
|
|
206
208
|
}
|
|
207
209
|
if (cqe->res != 0) {
|
|
210
|
+
if (!no_pt) {
|
|
211
|
+
no_pt = 1;
|
|
212
|
+
goto skip;
|
|
213
|
+
}
|
|
208
214
|
fprintf(stderr, "cqe res %d, wanted 0\n", cqe->res);
|
|
209
215
|
goto err;
|
|
210
216
|
}
|
|
@@ -234,6 +240,7 @@ static int __test_io(const char *file, struct io_uring *ring, int tc, int read,
|
|
|
234
240
|
}
|
|
235
241
|
}
|
|
236
242
|
|
|
243
|
+
skip:
|
|
237
244
|
close(fd);
|
|
238
245
|
return 0;
|
|
239
246
|
err:
|
|
@@ -258,6 +265,10 @@ static int test_io(const char *file, int tc, int read, int sqthread,
|
|
|
258
265
|
if (ret == T_SETUP_SKIP)
|
|
259
266
|
return 0;
|
|
260
267
|
if (ret != T_SETUP_OK) {
|
|
268
|
+
if (ret == -EINVAL) {
|
|
269
|
+
no_pt = 1;
|
|
270
|
+
return T_SETUP_SKIP;
|
|
271
|
+
}
|
|
261
272
|
fprintf(stderr, "ring create failed: %d\n", ret);
|
|
262
273
|
return 1;
|
|
263
274
|
}
|
|
@@ -268,8 +279,6 @@ static int test_io(const char *file, int tc, int read, int sqthread,
|
|
|
268
279
|
return ret;
|
|
269
280
|
}
|
|
270
281
|
|
|
271
|
-
extern unsigned __io_uring_flush_sq(struct io_uring *ring);
|
|
272
|
-
|
|
273
282
|
/*
|
|
274
283
|
* Send a passthrough command that nvme will fail during submission.
|
|
275
284
|
* This comes handy for testing error handling.
|
|
@@ -282,8 +291,7 @@ static int test_invalid_passthru_submit(const char *file)
|
|
|
282
291
|
struct io_uring_sqe *sqe;
|
|
283
292
|
struct nvme_uring_cmd *cmd;
|
|
284
293
|
|
|
285
|
-
ring_flags =
|
|
286
|
-
ring_flags |= IORING_SETUP_CQE32;
|
|
294
|
+
ring_flags = IORING_SETUP_CQE32 | IORING_SETUP_SQE128;
|
|
287
295
|
|
|
288
296
|
ret = t_create_ring(1, &ring, ring_flags);
|
|
289
297
|
if (ret != T_SETUP_OK) {
|
|
@@ -346,6 +354,8 @@ static int test_io_uring_submit_enters(const char *file)
|
|
|
346
354
|
int fd, i, ret, ring_flags, open_flags;
|
|
347
355
|
unsigned head;
|
|
348
356
|
struct io_uring_cqe *cqe;
|
|
357
|
+
struct nvme_uring_cmd *cmd;
|
|
358
|
+
struct io_uring_sqe *sqe;
|
|
349
359
|
|
|
350
360
|
ring_flags = IORING_SETUP_IOPOLL;
|
|
351
361
|
ring_flags |= IORING_SETUP_SQE128;
|
|
@@ -365,12 +375,28 @@ static int test_io_uring_submit_enters(const char *file)
|
|
|
365
375
|
}
|
|
366
376
|
|
|
367
377
|
for (i = 0; i < BUFFERS; i++) {
|
|
368
|
-
struct io_uring_sqe *sqe;
|
|
369
378
|
off_t offset = BS * (rand() % BUFFERS);
|
|
379
|
+
__u64 slba;
|
|
380
|
+
__u32 nlb;
|
|
370
381
|
|
|
371
382
|
sqe = io_uring_get_sqe(&ring);
|
|
372
|
-
|
|
373
|
-
sqe->user_data =
|
|
383
|
+
io_uring_prep_readv(sqe, fd, &vecs[i], 1, offset);
|
|
384
|
+
sqe->user_data = i;
|
|
385
|
+
sqe->opcode = IORING_OP_URING_CMD;
|
|
386
|
+
sqe->cmd_op = NVME_URING_CMD_IO;
|
|
387
|
+
cmd = (struct nvme_uring_cmd *)sqe->cmd;
|
|
388
|
+
memset(cmd, 0, sizeof(struct nvme_uring_cmd));
|
|
389
|
+
|
|
390
|
+
slba = offset >> lba_shift;
|
|
391
|
+
nlb = (BS >> lba_shift) - 1;
|
|
392
|
+
|
|
393
|
+
cmd->opcode = nvme_cmd_read;
|
|
394
|
+
cmd->cdw10 = slba & 0xffffffff;
|
|
395
|
+
cmd->cdw11 = slba >> 32;
|
|
396
|
+
cmd->cdw12 = nlb;
|
|
397
|
+
cmd->addr = (__u64)(uintptr_t)&vecs[i];
|
|
398
|
+
cmd->data_len = 1;
|
|
399
|
+
cmd->nsid = nsid;
|
|
374
400
|
}
|
|
375
401
|
|
|
376
402
|
/* submit manually to avoid adding IORING_ENTER_GETEVENTS */
|
|
@@ -426,6 +452,8 @@ int main(int argc, char *argv[])
|
|
|
426
452
|
int nonvec = (i & 8) != 0;
|
|
427
453
|
|
|
428
454
|
ret = test_io(fname, i, read, sqthread, fixed, nonvec);
|
|
455
|
+
if (no_pt)
|
|
456
|
+
break;
|
|
429
457
|
if (ret) {
|
|
430
458
|
fprintf(stderr, "test_io failed %d/%d/%d/%d\n",
|
|
431
459
|
read, sqthread, fixed, nonvec);
|
|
@@ -433,6 +461,9 @@ int main(int argc, char *argv[])
|
|
|
433
461
|
}
|
|
434
462
|
}
|
|
435
463
|
|
|
464
|
+
if (no_pt)
|
|
465
|
+
return T_EXIT_SKIP;
|
|
466
|
+
|
|
436
467
|
ret = test_io_uring_submit_enters(fname);
|
|
437
468
|
if (ret) {
|
|
438
469
|
fprintf(stderr, "test_io_uring_submit_enters failed\n");
|
|
@@ -19,86 +19,10 @@
|
|
|
19
19
|
|
|
20
20
|
#include "../syscall.h"
|
|
21
21
|
|
|
22
|
-
char *features_string(struct io_uring_params *p)
|
|
23
|
-
{
|
|
24
|
-
static char flagstr[64];
|
|
25
|
-
|
|
26
|
-
if (!p || !p->features)
|
|
27
|
-
return "none";
|
|
28
|
-
|
|
29
|
-
if (p->features & ~IORING_FEAT_SINGLE_MMAP) {
|
|
30
|
-
snprintf(flagstr, 64, "0x%.8x", p->features);
|
|
31
|
-
return flagstr;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
if (p->features & IORING_FEAT_SINGLE_MMAP)
|
|
35
|
-
strncat(flagstr, "IORING_FEAT_SINGLE_MMAP", 64 - strlen(flagstr));
|
|
36
|
-
|
|
37
|
-
return flagstr;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/*
|
|
41
|
-
* Attempt the call with the given args. Return 0 when expect matches
|
|
42
|
-
* the return value of the system call, 1 otherwise.
|
|
43
|
-
*/
|
|
44
|
-
char *
|
|
45
|
-
flags_string(struct io_uring_params *p)
|
|
46
|
-
{
|
|
47
|
-
static char flagstr[64];
|
|
48
|
-
int add_pipe = 0;
|
|
49
|
-
|
|
50
|
-
memset(flagstr, 0, sizeof(flagstr));
|
|
51
|
-
|
|
52
|
-
if (!p || p->flags == 0)
|
|
53
|
-
return "none";
|
|
54
|
-
|
|
55
|
-
/*
|
|
56
|
-
* If unsupported flags are present, just print the bitmask.
|
|
57
|
-
*/
|
|
58
|
-
if (p->flags & ~(IORING_SETUP_IOPOLL | IORING_SETUP_SQPOLL |
|
|
59
|
-
IORING_SETUP_SQ_AFF)) {
|
|
60
|
-
snprintf(flagstr, 64, "0x%.8x", p->flags);
|
|
61
|
-
return flagstr;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
if (p->flags & IORING_SETUP_IOPOLL) {
|
|
65
|
-
strncat(flagstr, "IORING_SETUP_IOPOLL", 64 - strlen(flagstr));
|
|
66
|
-
add_pipe = 1;
|
|
67
|
-
}
|
|
68
|
-
if (p->flags & IORING_SETUP_SQPOLL) {
|
|
69
|
-
if (add_pipe)
|
|
70
|
-
strncat(flagstr, "|", 64 - strlen(flagstr));
|
|
71
|
-
else
|
|
72
|
-
add_pipe = 1;
|
|
73
|
-
strncat(flagstr, "IORING_SETUP_SQPOLL", 64 - strlen(flagstr));
|
|
74
|
-
}
|
|
75
|
-
if (p->flags & IORING_SETUP_SQ_AFF) {
|
|
76
|
-
if (add_pipe)
|
|
77
|
-
strncat(flagstr, "|", 64 - strlen(flagstr));
|
|
78
|
-
strncat(flagstr, "IORING_SETUP_SQ_AFF", 64 - strlen(flagstr));
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
return flagstr;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
char *
|
|
85
|
-
dump_resv(struct io_uring_params *p)
|
|
86
|
-
{
|
|
87
|
-
static char resvstr[4096];
|
|
88
|
-
|
|
89
|
-
if (!p)
|
|
90
|
-
return "";
|
|
91
|
-
|
|
92
|
-
sprintf(resvstr, "0x%.8x 0x%.8x 0x%.8x", p->resv[0],
|
|
93
|
-
p->resv[1], p->resv[2]);
|
|
94
|
-
|
|
95
|
-
return resvstr;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
22
|
/* bogus: setup returns a valid fd on success... expect can't predict the
|
|
99
23
|
fd we'll get, so this really only takes 1 parameter: error */
|
|
100
|
-
int
|
|
101
|
-
|
|
24
|
+
static int try_io_uring_setup(unsigned entries, struct io_uring_params *p,
|
|
25
|
+
int expect)
|
|
102
26
|
{
|
|
103
27
|
int ret;
|
|
104
28
|
|
|
@@ -123,8 +47,7 @@ try_io_uring_setup(unsigned entries, struct io_uring_params *p, int expect)
|
|
|
123
47
|
return 0;
|
|
124
48
|
}
|
|
125
49
|
|
|
126
|
-
int
|
|
127
|
-
main(int argc, char **argv)
|
|
50
|
+
int main(int argc, char **argv)
|
|
128
51
|
{
|
|
129
52
|
int fd;
|
|
130
53
|
unsigned int status = 0;
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/* SPDX-License-Identifier: MIT */
|
|
2
|
+
/*
|
|
3
|
+
* Description: IOPOLL with overflow test case
|
|
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
|
+
#include "helpers.h"
|
|
16
|
+
#include "liburing.h"
|
|
17
|
+
#include "../src/syscall.h"
|
|
18
|
+
|
|
19
|
+
#define FILE_SIZE (128 * 1024)
|
|
20
|
+
#define BS 4096
|
|
21
|
+
#define BUFFERS (FILE_SIZE / BS)
|
|
22
|
+
|
|
23
|
+
static struct iovec *vecs;
|
|
24
|
+
|
|
25
|
+
static int test(struct io_uring *ring, int fd)
|
|
26
|
+
{
|
|
27
|
+
struct io_uring_sqe *sqe;
|
|
28
|
+
int i, j, ret;
|
|
29
|
+
loff_t off;
|
|
30
|
+
|
|
31
|
+
off = FILE_SIZE - BS;
|
|
32
|
+
for (j = 0; j < 8; j++) {
|
|
33
|
+
for (i = 0; i < BUFFERS; i++) {
|
|
34
|
+
sqe = io_uring_get_sqe(ring);
|
|
35
|
+
io_uring_prep_read(sqe, fd, vecs[i].iov_base,
|
|
36
|
+
vecs[i].iov_len, off);
|
|
37
|
+
if (!off)
|
|
38
|
+
off = FILE_SIZE - BS;
|
|
39
|
+
else
|
|
40
|
+
off -= BS;
|
|
41
|
+
}
|
|
42
|
+
ret = io_uring_submit(ring);
|
|
43
|
+
if (ret != BUFFERS) {
|
|
44
|
+
fprintf(stderr, "submitted %d\n", ret);
|
|
45
|
+
return T_EXIT_FAIL;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
sleep(1);
|
|
50
|
+
|
|
51
|
+
ret = __sys_io_uring_enter(ring->ring_fd, 0, BUFFERS * 8,
|
|
52
|
+
IORING_ENTER_GETEVENTS, NULL);
|
|
53
|
+
|
|
54
|
+
for (i = 0; i < BUFFERS * 8; i++) {
|
|
55
|
+
struct io_uring_cqe *cqe;
|
|
56
|
+
|
|
57
|
+
ret = io_uring_wait_cqe(ring, &cqe);
|
|
58
|
+
if (ret) {
|
|
59
|
+
fprintf(stderr, "wait=%d\n", ret);
|
|
60
|
+
return T_EXIT_FAIL;
|
|
61
|
+
}
|
|
62
|
+
io_uring_cqe_seen(ring, cqe);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return T_EXIT_PASS;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
int main(int argc, char *argv[])
|
|
69
|
+
{
|
|
70
|
+
struct io_uring_params p = { };
|
|
71
|
+
struct io_uring ring;
|
|
72
|
+
char buf[256];
|
|
73
|
+
char *fname;
|
|
74
|
+
int ret, fd;
|
|
75
|
+
|
|
76
|
+
p.flags = IORING_SETUP_IOPOLL | IORING_SETUP_CQSIZE;
|
|
77
|
+
p.cq_entries = 64;
|
|
78
|
+
ret = t_create_ring_params(64, &ring, &p);
|
|
79
|
+
if (ret == T_SETUP_SKIP)
|
|
80
|
+
return 0;
|
|
81
|
+
if (ret != T_SETUP_OK) {
|
|
82
|
+
fprintf(stderr, "ring create failed: %d\n", ret);
|
|
83
|
+
return 1;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (argc > 1) {
|
|
87
|
+
fname = argv[1];
|
|
88
|
+
} else {
|
|
89
|
+
srand((unsigned)time(NULL));
|
|
90
|
+
snprintf(buf, sizeof(buf), ".basic-rw-%u-%u",
|
|
91
|
+
(unsigned)rand(), (unsigned)getpid());
|
|
92
|
+
fname = buf;
|
|
93
|
+
t_create_file(fname, FILE_SIZE);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
fd = open(fname, O_RDONLY | O_DIRECT);
|
|
97
|
+
if (fd < 0) {
|
|
98
|
+
if (errno == EINVAL) {
|
|
99
|
+
if (fname != argv[1])
|
|
100
|
+
unlink(fname);
|
|
101
|
+
return T_EXIT_SKIP;
|
|
102
|
+
}
|
|
103
|
+
perror("open");
|
|
104
|
+
goto err;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
vecs = t_create_buffers(BUFFERS, BS);
|
|
108
|
+
|
|
109
|
+
ret = test(&ring, fd);
|
|
110
|
+
|
|
111
|
+
if (fname != argv[1])
|
|
112
|
+
unlink(fname);
|
|
113
|
+
return ret;
|
|
114
|
+
err:
|
|
115
|
+
if (fname != argv[1])
|
|
116
|
+
unlink(fname);
|
|
117
|
+
return T_EXIT_FAIL;
|
|
118
|
+
}
|