uringmachine 0.3 → 0.5
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/workflows/test.yml +2 -1
- data/CHANGELOG.md +23 -0
- data/README.md +128 -0
- data/TODO.md +14 -0
- data/examples/bm_snooze.rb +89 -0
- data/examples/bm_write.rb +56 -0
- data/examples/dns_client.rb +12 -0
- data/examples/echo_server.rb +18 -40
- data/examples/http_server.rb +42 -43
- data/examples/inout.rb +19 -0
- data/examples/nc.rb +36 -0
- data/examples/server_client.rb +64 -0
- data/examples/snooze.rb +44 -0
- data/examples/write_dev_null.rb +16 -0
- data/ext/um/extconf.rb +24 -23
- data/ext/um/um.c +524 -278
- data/ext/um/um.h +146 -44
- data/ext/um/um_buffer.c +49 -0
- data/ext/um/um_class.c +217 -106
- data/ext/um/um_const.c +213 -0
- data/ext/um/um_ext.c +4 -0
- data/ext/um/um_mutex_class.c +47 -0
- data/ext/um/um_op.c +86 -114
- data/ext/um/um_queue_class.c +58 -0
- data/ext/um/um_sync.c +273 -0
- data/ext/um/um_utils.c +49 -4
- data/lib/uringmachine/dns_resolver.rb +84 -0
- data/lib/uringmachine/version.rb +1 -1
- data/lib/uringmachine.rb +28 -0
- data/supressions/ruby.supp +71 -0
- data/test/helper.rb +8 -0
- data/test/test_um.rb +685 -46
- data/vendor/liburing/.github/workflows/build.yml +29 -1
- data/vendor/liburing/.gitignore +6 -0
- data/vendor/liburing/CHANGELOG +16 -0
- data/vendor/liburing/CONTRIBUTING.md +165 -0
- data/vendor/liburing/configure +64 -0
- data/vendor/liburing/examples/Makefile +9 -1
- data/vendor/liburing/examples/kdigest.c +405 -0
- data/vendor/liburing/examples/proxy.c +75 -8
- data/vendor/liburing/examples/reg-wait.c +159 -0
- data/vendor/liburing/liburing.pc.in +1 -1
- data/vendor/liburing/liburing.spec +1 -1
- data/vendor/liburing/src/Makefile +16 -2
- data/vendor/liburing/src/include/liburing/io_uring.h +77 -0
- data/vendor/liburing/src/include/liburing/sanitize.h +39 -0
- data/vendor/liburing/src/include/liburing.h +59 -6
- data/vendor/liburing/src/int_flags.h +10 -3
- data/vendor/liburing/src/liburing-ffi.map +16 -0
- data/vendor/liburing/src/liburing.map +10 -0
- data/vendor/liburing/src/queue.c +28 -16
- data/vendor/liburing/src/register.c +106 -1
- data/vendor/liburing/src/sanitize.c +176 -0
- data/vendor/liburing/src/setup.c +47 -19
- data/vendor/liburing/src/setup.h +6 -0
- data/vendor/liburing/test/35fa71a030ca.c +7 -0
- data/vendor/liburing/test/500f9fbadef8.c +2 -0
- data/vendor/liburing/test/7ad0e4b2f83c.c +0 -25
- data/vendor/liburing/test/917257daa0fe.c +7 -0
- data/vendor/liburing/test/Makefile +38 -4
- data/vendor/liburing/test/a0908ae19763.c +7 -0
- data/vendor/liburing/test/a4c0b3decb33.c +7 -0
- data/vendor/liburing/test/accept.c +14 -4
- data/vendor/liburing/test/b19062a56726.c +7 -0
- data/vendor/liburing/test/bind-listen.c +2 -2
- data/vendor/liburing/test/buf-ring-nommap.c +10 -3
- data/vendor/liburing/test/buf-ring.c +2 -0
- data/vendor/liburing/test/cmd-discard.c +427 -0
- data/vendor/liburing/test/coredump.c +7 -0
- data/vendor/liburing/test/cq-overflow.c +13 -1
- data/vendor/liburing/test/d4ae271dfaae.c +11 -3
- data/vendor/liburing/test/defer-taskrun.c +2 -2
- data/vendor/liburing/test/defer-tw-timeout.c +4 -1
- data/vendor/liburing/test/defer.c +2 -2
- data/vendor/liburing/test/double-poll-crash.c +1 -1
- data/vendor/liburing/test/eeed8b54e0df.c +2 -0
- data/vendor/liburing/test/eventfd.c +0 -1
- data/vendor/liburing/test/exit-no-cleanup.c +11 -0
- data/vendor/liburing/test/fadvise.c +9 -26
- data/vendor/liburing/test/fdinfo.c +9 -1
- data/vendor/liburing/test/fifo-nonblock-read.c +69 -0
- data/vendor/liburing/test/file-exit-unreg.c +48 -0
- data/vendor/liburing/test/file-register.c +14 -2
- data/vendor/liburing/test/file-update.c +1 -1
- data/vendor/liburing/test/file-verify.c +27 -16
- data/vendor/liburing/test/files-exit-hang-timeout.c +1 -2
- data/vendor/liburing/test/fixed-buf-iter.c +3 -1
- data/vendor/liburing/test/fixed-hugepage.c +12 -1
- data/vendor/liburing/test/fsnotify.c +1 -0
- data/vendor/liburing/test/futex.c +16 -4
- data/vendor/liburing/test/helpers.c +47 -0
- data/vendor/liburing/test/helpers.h +6 -0
- data/vendor/liburing/test/init-mem.c +5 -3
- data/vendor/liburing/test/io-cancel.c +0 -24
- data/vendor/liburing/test/io_uring_passthrough.c +4 -0
- data/vendor/liburing/test/io_uring_register.c +38 -8
- data/vendor/liburing/test/iopoll-leak.c +4 -0
- data/vendor/liburing/test/iopoll-overflow.c +1 -1
- data/vendor/liburing/test/iopoll.c +3 -3
- data/vendor/liburing/test/kallsyms.c +203 -0
- data/vendor/liburing/test/link-timeout.c +159 -0
- data/vendor/liburing/test/linked-defer-close.c +224 -0
- data/vendor/liburing/test/madvise.c +12 -25
- data/vendor/liburing/test/min-timeout-wait.c +0 -25
- data/vendor/liburing/test/min-timeout.c +0 -25
- data/vendor/liburing/test/mkdir.c +6 -0
- data/vendor/liburing/test/msg-ring.c +8 -2
- data/vendor/liburing/test/napi-test.c +16 -3
- data/vendor/liburing/test/no-mmap-inval.c +3 -1
- data/vendor/liburing/test/nop.c +44 -0
- data/vendor/liburing/test/ooo-file-unreg.c +1 -1
- data/vendor/liburing/test/open-close.c +40 -0
- data/vendor/liburing/test/openat2.c +37 -14
- data/vendor/liburing/test/poll-many.c +13 -7
- data/vendor/liburing/test/poll-mshot-update.c +17 -10
- data/vendor/liburing/test/poll-v-poll.c +6 -3
- data/vendor/liburing/test/pollfree.c +148 -0
- data/vendor/liburing/test/read-mshot-empty.c +158 -153
- data/vendor/liburing/test/read-mshot-stdin.c +121 -0
- data/vendor/liburing/test/read-mshot.c +282 -27
- data/vendor/liburing/test/read-write.c +78 -13
- data/vendor/liburing/test/recv-msgall-stream.c +3 -0
- data/vendor/liburing/test/recv-msgall.c +5 -0
- data/vendor/liburing/test/recvsend_bundle-inc.c +680 -0
- data/vendor/liburing/test/recvsend_bundle.c +94 -31
- data/vendor/liburing/test/reg-fd-only.c +15 -5
- data/vendor/liburing/test/reg-wait.c +251 -0
- data/vendor/liburing/test/regbuf-clone.c +645 -0
- data/vendor/liburing/test/regbuf-merge.c +7 -0
- data/vendor/liburing/test/register-restrictions.c +86 -85
- data/vendor/liburing/test/rename.c +59 -1
- data/vendor/liburing/test/resize-rings.c +643 -0
- data/vendor/liburing/test/ringbuf-read.c +5 -0
- data/vendor/liburing/test/ringbuf-status.c +5 -1
- data/vendor/liburing/test/rsrc_tags.c +1 -1
- data/vendor/liburing/test/runtests.sh +16 -1
- data/vendor/liburing/test/send-zerocopy.c +59 -0
- data/vendor/liburing/test/short-read.c +1 -0
- data/vendor/liburing/test/socket.c +43 -0
- data/vendor/liburing/test/splice.c +3 -1
- data/vendor/liburing/test/sq-poll-dup.c +1 -1
- data/vendor/liburing/test/sq-poll-share.c +2 -0
- data/vendor/liburing/test/sqpoll-disable-exit.c +8 -0
- data/vendor/liburing/test/sqpoll-exit-hang.c +1 -25
- data/vendor/liburing/test/sqpoll-sleep.c +40 -33
- data/vendor/liburing/test/sqwait.c +136 -0
- data/vendor/liburing/test/statx.c +89 -0
- data/vendor/liburing/test/stdout.c +2 -0
- data/vendor/liburing/test/submit-and-wait.c +1 -25
- data/vendor/liburing/test/submit-reuse.c +4 -26
- data/vendor/liburing/test/symlink.c +12 -1
- data/vendor/liburing/test/sync-cancel.c +56 -22
- data/vendor/liburing/test/thread-exit.c +5 -0
- data/vendor/liburing/test/timeout-new.c +1 -26
- data/vendor/liburing/test/timeout.c +25 -34
- data/vendor/liburing/test/unlink.c +94 -1
- data/vendor/liburing/test/uring_cmd_ublk.c +1252 -0
- data/vendor/liburing/test/waitid.c +62 -8
- data/vendor/liburing/test/wq-aff.c +35 -0
- data/vendor/liburing/test/xfail_prep_link_timeout_out_of_scope.c +46 -0
- data/vendor/liburing/test/xfail_register_buffers_out_of_scope.c +51 -0
- metadata +37 -6
- data/examples/event_loop.rb +0 -69
- data/examples/fibers.rb +0 -105
- data/examples/http_server_multishot.rb +0 -57
- data/examples/http_server_simpler.rb +0 -34
@@ -95,6 +95,8 @@ static int __test_io(const char *file, struct io_uring *ring, int tc, int read,
|
|
95
95
|
|
96
96
|
fd = open(file, open_flags);
|
97
97
|
if (fd < 0) {
|
98
|
+
if (errno == EACCES || errno == EPERM)
|
99
|
+
return T_EXIT_SKIP;
|
98
100
|
perror("file open");
|
99
101
|
goto err;
|
100
102
|
}
|
@@ -165,6 +167,8 @@ static int __test_io(const char *file, struct io_uring *ring, int tc, int read,
|
|
165
167
|
}
|
166
168
|
}
|
167
169
|
sqe->opcode = IORING_OP_URING_CMD;
|
170
|
+
if (do_fixed)
|
171
|
+
sqe->uring_cmd_flags |= IORING_URING_CMD_FIXED;
|
168
172
|
sqe->user_data = ((uint64_t)offset << 32) | i;
|
169
173
|
if (sqthread)
|
170
174
|
sqe->flags |= IOSQE_FIXED_FILE;
|
@@ -21,6 +21,7 @@
|
|
21
21
|
#include <linux/mman.h>
|
22
22
|
#include <sys/time.h>
|
23
23
|
#include <sys/resource.h>
|
24
|
+
#include <sys/vfs.h>
|
24
25
|
#include <limits.h>
|
25
26
|
|
26
27
|
#include "helpers.h"
|
@@ -76,8 +77,13 @@ static int new_io_uring(int entries, struct io_uring_params *p)
|
|
76
77
|
|
77
78
|
#define MAXFDS (UINT_MAX * sizeof(int))
|
78
79
|
|
80
|
+
#define OFS_MAGIC 0x794c7630
|
81
|
+
#define TMPFS_MAGIC 0x01021994
|
82
|
+
#define RAMFS_MAGIC 0x858458f6
|
83
|
+
|
79
84
|
static void *map_filebacked(size_t size)
|
80
85
|
{
|
86
|
+
struct statfs buf;
|
81
87
|
int fd, ret;
|
82
88
|
void *addr;
|
83
89
|
char template[32] = "io_uring_register-test-XXXXXXXX";
|
@@ -87,8 +93,21 @@ static void *map_filebacked(size_t size)
|
|
87
93
|
perror("mkstemp");
|
88
94
|
return NULL;
|
89
95
|
}
|
96
|
+
if (statfs(template, &buf) < 0) {
|
97
|
+
perror("statfs");
|
98
|
+
unlink(template);
|
99
|
+
close(fd);
|
100
|
+
return NULL;
|
101
|
+
}
|
90
102
|
unlink(template);
|
91
103
|
|
104
|
+
/* virtual file systems may not present as file mapped */
|
105
|
+
if (buf.f_type == OFS_MAGIC || buf.f_type == RAMFS_MAGIC ||
|
106
|
+
buf.f_type == TMPFS_MAGIC) {
|
107
|
+
close(fd);
|
108
|
+
return NULL;
|
109
|
+
}
|
110
|
+
|
92
111
|
ret = ftruncate(fd, size);
|
93
112
|
if (ret < 0) {
|
94
113
|
perror("ftruncate");
|
@@ -365,12 +384,12 @@ static int test_iovec_size(int fd)
|
|
365
384
|
|
366
385
|
/* file-backed buffers -- not supported */
|
367
386
|
buf = map_filebacked(2*1024*1024);
|
368
|
-
if (
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
387
|
+
if (buf) {
|
388
|
+
iov.iov_base = buf;
|
389
|
+
iov.iov_len = 2*1024*1024;
|
390
|
+
status |= expect_fail(fd, IORING_REGISTER_BUFFERS, &iov, 1, -EFAULT, -EOPNOTSUPP);
|
391
|
+
munmap(buf, 2*1024*1024);
|
392
|
+
}
|
374
393
|
|
375
394
|
/* bump up against the soft limit and make sure we get EFAULT
|
376
395
|
* or whatever we're supposed to get. NOTE: this requires
|
@@ -417,14 +436,14 @@ static int ioring_poll(struct io_uring *ring, int fd, int fixed)
|
|
417
436
|
return ret;
|
418
437
|
}
|
419
438
|
|
420
|
-
static int
|
439
|
+
static int __test_poll_ringfd(int ring_flags)
|
421
440
|
{
|
422
441
|
int status = 0;
|
423
442
|
int ret;
|
424
443
|
int fd;
|
425
444
|
struct io_uring ring;
|
426
445
|
|
427
|
-
ret = io_uring_queue_init(
|
446
|
+
ret = io_uring_queue_init(2, &ring, ring_flags);
|
428
447
|
if (ret) {
|
429
448
|
perror("io_uring_queue_init");
|
430
449
|
return 1;
|
@@ -447,6 +466,17 @@ static int test_poll_ringfd(void)
|
|
447
466
|
return status;
|
448
467
|
}
|
449
468
|
|
469
|
+
static int test_poll_ringfd(void)
|
470
|
+
{
|
471
|
+
int ret;
|
472
|
+
|
473
|
+
ret = __test_poll_ringfd(0);
|
474
|
+
if (ret)
|
475
|
+
return ret;
|
476
|
+
|
477
|
+
return __test_poll_ringfd(IORING_SETUP_SQPOLL);
|
478
|
+
}
|
479
|
+
|
450
480
|
int main(int argc, char **argv)
|
451
481
|
{
|
452
482
|
int fd, ret;
|
@@ -26,6 +26,8 @@ static int do_iopoll(const char *fname)
|
|
26
26
|
|
27
27
|
fd = open(fname, O_RDONLY | O_DIRECT);
|
28
28
|
if (fd < 0) {
|
29
|
+
if (errno == EINVAL || errno == EPERM || errno == EACCES)
|
30
|
+
return T_EXIT_SKIP;
|
29
31
|
perror("open");
|
30
32
|
return T_EXIT_SKIP;
|
31
33
|
}
|
@@ -39,6 +41,8 @@ static int do_iopoll(const char *fname)
|
|
39
41
|
io_uring_submit(&ring);
|
40
42
|
|
41
43
|
close(fd);
|
44
|
+
free(iov->iov_base);
|
45
|
+
free(iov);
|
42
46
|
return T_EXIT_PASS;
|
43
47
|
}
|
44
48
|
|
@@ -87,7 +87,7 @@ static int __test_io(const char *file, struct io_uring *ring, int write, int sqt
|
|
87
87
|
}
|
88
88
|
fd = open(file, open_flags);
|
89
89
|
if (fd < 0) {
|
90
|
-
if (errno == EINVAL)
|
90
|
+
if (errno == EINVAL || errno == EPERM || errno == EACCES)
|
91
91
|
return 0;
|
92
92
|
perror("file open");
|
93
93
|
goto err;
|
@@ -230,7 +230,7 @@ static int test_io_uring_cqe_peek(const char *file)
|
|
230
230
|
|
231
231
|
fd = open(file, O_RDONLY | O_DIRECT);
|
232
232
|
if (fd < 0) {
|
233
|
-
if (errno == EINVAL) {
|
233
|
+
if (errno == EINVAL || errno == EPERM || errno == EACCES) {
|
234
234
|
io_uring_queue_exit(&ring);
|
235
235
|
return T_EXIT_SKIP;
|
236
236
|
}
|
@@ -302,7 +302,7 @@ static int test_io_uring_submit_enters(const char *file)
|
|
302
302
|
open_flags = O_WRONLY | O_DIRECT;
|
303
303
|
fd = open(file, open_flags);
|
304
304
|
if (fd < 0) {
|
305
|
-
if (errno == EINVAL)
|
305
|
+
if (errno == EINVAL || errno == EPERM || errno == EACCES)
|
306
306
|
return T_EXIT_SKIP;
|
307
307
|
perror("file open");
|
308
308
|
goto err;
|
@@ -0,0 +1,203 @@
|
|
1
|
+
/* SPDX-License-Identifier: MIT */
|
2
|
+
/*
|
3
|
+
* Description: read /proc/kallsyms. Mostly just here so that fops->read() can
|
4
|
+
* get exercised, with and without registered buffers
|
5
|
+
*/
|
6
|
+
#include <errno.h>
|
7
|
+
#include <stdio.h>
|
8
|
+
#include <unistd.h>
|
9
|
+
#include <stdlib.h>
|
10
|
+
#include <string.h>
|
11
|
+
#include <fcntl.h>
|
12
|
+
#include <sys/types.h>
|
13
|
+
#include <poll.h>
|
14
|
+
#include <sys/eventfd.h>
|
15
|
+
#include <sys/resource.h>
|
16
|
+
|
17
|
+
#include "helpers.h"
|
18
|
+
#include "liburing.h"
|
19
|
+
|
20
|
+
#define FILE_SIZE (8 * 1024)
|
21
|
+
#define BS 8192
|
22
|
+
#define BUFFERS (FILE_SIZE / BS)
|
23
|
+
|
24
|
+
static struct iovec *vecs;
|
25
|
+
static int warned;
|
26
|
+
|
27
|
+
static int __test_io(const char *file, struct io_uring *ring, int fixed, int nonvec)
|
28
|
+
{
|
29
|
+
struct io_uring_sqe *sqe;
|
30
|
+
struct io_uring_cqe *cqe;
|
31
|
+
int open_flags;
|
32
|
+
int i, fd = -1, ret;
|
33
|
+
off_t offset;
|
34
|
+
|
35
|
+
open_flags = O_RDONLY;
|
36
|
+
if (fixed) {
|
37
|
+
ret = t_register_buffers(ring, vecs, BUFFERS);
|
38
|
+
if (ret == T_SETUP_SKIP)
|
39
|
+
return 0;
|
40
|
+
if (ret != T_SETUP_OK) {
|
41
|
+
fprintf(stderr, "buffer reg failed: %d\n", ret);
|
42
|
+
goto err;
|
43
|
+
}
|
44
|
+
}
|
45
|
+
|
46
|
+
fd = open(file, open_flags);
|
47
|
+
if (fd < 0) {
|
48
|
+
if (errno == EINVAL || errno == EPERM || errno == ENOENT)
|
49
|
+
return 0;
|
50
|
+
perror("file open");
|
51
|
+
goto err;
|
52
|
+
}
|
53
|
+
|
54
|
+
offset = 0;
|
55
|
+
for (i = 0; i < BUFFERS; i++) {
|
56
|
+
int do_fixed = fixed;
|
57
|
+
|
58
|
+
sqe = io_uring_get_sqe(ring);
|
59
|
+
if (!sqe) {
|
60
|
+
fprintf(stderr, "sqe get failed\n");
|
61
|
+
goto err;
|
62
|
+
}
|
63
|
+
if (fixed && (i & 1))
|
64
|
+
do_fixed = 0;
|
65
|
+
if (do_fixed) {
|
66
|
+
io_uring_prep_read_fixed(sqe, fd, vecs[i].iov_base,
|
67
|
+
vecs[i].iov_len, offset, i);
|
68
|
+
} else if (nonvec) {
|
69
|
+
io_uring_prep_read(sqe, fd, vecs[i].iov_base,
|
70
|
+
vecs[i].iov_len, offset);
|
71
|
+
} else {
|
72
|
+
io_uring_prep_readv(sqe, fd, &vecs[i], 1, offset);
|
73
|
+
}
|
74
|
+
sqe->user_data = i;
|
75
|
+
offset += BS;
|
76
|
+
}
|
77
|
+
|
78
|
+
ret = io_uring_submit(ring);
|
79
|
+
if (ret != BUFFERS) {
|
80
|
+
fprintf(stderr, "submit got %d, wanted %d\n", ret, BUFFERS);
|
81
|
+
goto err;
|
82
|
+
}
|
83
|
+
|
84
|
+
for (i = 0; i < BUFFERS; i++) {
|
85
|
+
ret = io_uring_wait_cqe(ring, &cqe);
|
86
|
+
if (ret) {
|
87
|
+
fprintf(stderr, "wait_cqe=%d\n", ret);
|
88
|
+
goto err;
|
89
|
+
}
|
90
|
+
if (cqe->res == -EINVAL && nonvec) {
|
91
|
+
if (!warned) {
|
92
|
+
fprintf(stdout, "Non-vectored IO not "
|
93
|
+
"supported, skipping\n");
|
94
|
+
warned = 1;
|
95
|
+
}
|
96
|
+
}
|
97
|
+
io_uring_cqe_seen(ring, cqe);
|
98
|
+
}
|
99
|
+
|
100
|
+
if (fixed) {
|
101
|
+
ret = io_uring_unregister_buffers(ring);
|
102
|
+
if (ret) {
|
103
|
+
fprintf(stderr, "buffer unreg failed: %d\n", ret);
|
104
|
+
goto err;
|
105
|
+
}
|
106
|
+
}
|
107
|
+
|
108
|
+
close(fd);
|
109
|
+
return 0;
|
110
|
+
err:
|
111
|
+
if (fd != -1)
|
112
|
+
close(fd);
|
113
|
+
return 1;
|
114
|
+
}
|
115
|
+
static int test_io(const char *file, int fixed, int nonvec)
|
116
|
+
{
|
117
|
+
struct io_uring ring;
|
118
|
+
int ret, ring_flags = 0;
|
119
|
+
|
120
|
+
ret = t_create_ring(64, &ring, ring_flags);
|
121
|
+
if (ret == T_SETUP_SKIP)
|
122
|
+
return 0;
|
123
|
+
if (ret != T_SETUP_OK) {
|
124
|
+
fprintf(stderr, "ring create failed: %d\n", ret);
|
125
|
+
return 1;
|
126
|
+
}
|
127
|
+
|
128
|
+
ret = __test_io(file, &ring, fixed, nonvec);
|
129
|
+
io_uring_queue_exit(&ring);
|
130
|
+
return ret;
|
131
|
+
}
|
132
|
+
|
133
|
+
static int has_nonvec_read(void)
|
134
|
+
{
|
135
|
+
struct io_uring_probe *p;
|
136
|
+
struct io_uring ring;
|
137
|
+
int ret;
|
138
|
+
|
139
|
+
ret = io_uring_queue_init(1, &ring, 0);
|
140
|
+
if (ret) {
|
141
|
+
fprintf(stderr, "queue init failed: %d\n", ret);
|
142
|
+
exit(ret);
|
143
|
+
}
|
144
|
+
|
145
|
+
p = t_calloc(1, sizeof(*p) + 256 * sizeof(struct io_uring_probe_op));
|
146
|
+
ret = io_uring_register_probe(&ring, p, 256);
|
147
|
+
/* if we don't have PROBE_REGISTER, we don't have OP_READ/WRITE */
|
148
|
+
if (ret == -EINVAL) {
|
149
|
+
out:
|
150
|
+
io_uring_queue_exit(&ring);
|
151
|
+
free(p);
|
152
|
+
return 0;
|
153
|
+
} else if (ret) {
|
154
|
+
fprintf(stderr, "register_probe: %d\n", ret);
|
155
|
+
goto out;
|
156
|
+
}
|
157
|
+
|
158
|
+
if (p->ops_len <= IORING_OP_READ)
|
159
|
+
goto out;
|
160
|
+
if (!(p->ops[IORING_OP_READ].flags & IO_URING_OP_SUPPORTED))
|
161
|
+
goto out;
|
162
|
+
io_uring_queue_exit(&ring);
|
163
|
+
free(p);
|
164
|
+
return 1;
|
165
|
+
}
|
166
|
+
|
167
|
+
int main(int argc, char *argv[])
|
168
|
+
{
|
169
|
+
int ret, nonvec;
|
170
|
+
|
171
|
+
if (argc > 1)
|
172
|
+
return T_EXIT_SKIP;
|
173
|
+
|
174
|
+
vecs = t_create_buffers(BUFFERS, BS);
|
175
|
+
|
176
|
+
/* if we don't have nonvec read, skip testing that */
|
177
|
+
nonvec = has_nonvec_read();
|
178
|
+
|
179
|
+
if (nonvec) {
|
180
|
+
ret = test_io("/proc/kallsyms", 0, 0);
|
181
|
+
if (ret)
|
182
|
+
goto err;
|
183
|
+
}
|
184
|
+
|
185
|
+
ret = test_io("/proc/kallsyms", 0, 1);
|
186
|
+
if (ret)
|
187
|
+
goto err;
|
188
|
+
|
189
|
+
if (nonvec) {
|
190
|
+
ret = test_io("/proc/kallsyms", 1, 0);
|
191
|
+
if (ret)
|
192
|
+
goto err;
|
193
|
+
}
|
194
|
+
|
195
|
+
ret = test_io("/proc/kallsyms", 1, 1);
|
196
|
+
if (ret)
|
197
|
+
goto err;
|
198
|
+
|
199
|
+
return 0;
|
200
|
+
err:
|
201
|
+
fprintf(stderr, "Reading kallsyms failed\n");
|
202
|
+
return 1;
|
203
|
+
}
|
@@ -10,6 +10,7 @@
|
|
10
10
|
#include <string.h>
|
11
11
|
#include <fcntl.h>
|
12
12
|
#include <poll.h>
|
13
|
+
#include <sys/time.h>
|
13
14
|
|
14
15
|
#include "liburing.h"
|
15
16
|
#include "helpers.h"
|
@@ -537,6 +538,139 @@ err:
|
|
537
538
|
return 1;
|
538
539
|
}
|
539
540
|
|
541
|
+
static int test_link_timeout_update(struct io_uring *ring, int async)
|
542
|
+
{
|
543
|
+
struct __kernel_timespec ts;
|
544
|
+
struct io_uring_cqe *cqe;
|
545
|
+
struct io_uring_sqe *sqe;
|
546
|
+
struct timeval start;
|
547
|
+
unsigned long msec;
|
548
|
+
int fds[2], ret, i;
|
549
|
+
struct iovec iov;
|
550
|
+
char buffer[128];
|
551
|
+
|
552
|
+
if (pipe(fds)) {
|
553
|
+
perror("pipe");
|
554
|
+
return 1;
|
555
|
+
}
|
556
|
+
|
557
|
+
sqe = io_uring_get_sqe(ring);
|
558
|
+
if (!sqe) {
|
559
|
+
printf("get sqe failed\n");
|
560
|
+
goto err;
|
561
|
+
}
|
562
|
+
iov.iov_base = buffer;
|
563
|
+
iov.iov_len = sizeof(buffer);
|
564
|
+
io_uring_prep_readv(sqe, fds[0], &iov, 1, 0);
|
565
|
+
sqe->flags |= IOSQE_IO_LINK;
|
566
|
+
sqe->user_data = 1;
|
567
|
+
|
568
|
+
sqe = io_uring_get_sqe(ring);
|
569
|
+
if (!sqe) {
|
570
|
+
printf("get sqe failed\n");
|
571
|
+
goto err;
|
572
|
+
}
|
573
|
+
ts.tv_sec = 5;
|
574
|
+
ts.tv_nsec = 0;
|
575
|
+
io_uring_prep_link_timeout(sqe, &ts, 0);
|
576
|
+
sqe->user_data = 2;
|
577
|
+
|
578
|
+
ret = io_uring_submit(ring);
|
579
|
+
if (ret != 2) {
|
580
|
+
printf("sqe submit failed: %d\n", ret);
|
581
|
+
goto err;
|
582
|
+
}
|
583
|
+
|
584
|
+
ts.tv_sec = 0;
|
585
|
+
ts.tv_nsec = 100000000LL;
|
586
|
+
sqe = io_uring_get_sqe(ring);
|
587
|
+
io_uring_prep_timeout_update(sqe, &ts, 2, IORING_LINK_TIMEOUT_UPDATE);
|
588
|
+
if (async)
|
589
|
+
sqe->flags |= IOSQE_ASYNC;
|
590
|
+
sqe->user_data = 3;
|
591
|
+
|
592
|
+
io_uring_submit(ring);
|
593
|
+
|
594
|
+
gettimeofday(&start, NULL);
|
595
|
+
for (i = 0; i < 3; i++) {
|
596
|
+
ret = io_uring_wait_cqe(ring, &cqe);
|
597
|
+
if (ret < 0) {
|
598
|
+
printf("wait completion %d\n", ret);
|
599
|
+
goto err;
|
600
|
+
}
|
601
|
+
switch (cqe->user_data) {
|
602
|
+
case 1:
|
603
|
+
if (cqe->res != -EINTR && cqe->res != -ECANCELED) {
|
604
|
+
fprintf(stderr, "Req %" PRIu64 " got %d\n", (uint64_t) cqe->user_data,
|
605
|
+
cqe->res);
|
606
|
+
goto err;
|
607
|
+
}
|
608
|
+
break;
|
609
|
+
case 2:
|
610
|
+
/* FASTPOLL kernels can cancel successfully */
|
611
|
+
if (cqe->res != -EALREADY && cqe->res != -ETIME) {
|
612
|
+
fprintf(stderr, "Req %" PRIu64 " got %d\n", (uint64_t) cqe->user_data,
|
613
|
+
cqe->res);
|
614
|
+
goto err;
|
615
|
+
}
|
616
|
+
break;
|
617
|
+
case 3:
|
618
|
+
if (cqe->res) {
|
619
|
+
fprintf(stderr, "Req %" PRIu64 " got %d\n", (uint64_t) cqe->user_data,
|
620
|
+
cqe->res);
|
621
|
+
goto err;
|
622
|
+
}
|
623
|
+
break;
|
624
|
+
}
|
625
|
+
|
626
|
+
io_uring_cqe_seen(ring, cqe);
|
627
|
+
}
|
628
|
+
|
629
|
+
msec = mtime_since_now(&start);
|
630
|
+
if (msec < 10 || msec > 200) {
|
631
|
+
fprintf(stderr, "Timeout appears incorrect: %lu\n", msec);
|
632
|
+
goto err;
|
633
|
+
}
|
634
|
+
|
635
|
+
close(fds[0]);
|
636
|
+
close(fds[1]);
|
637
|
+
return 0;
|
638
|
+
err:
|
639
|
+
return 1;
|
640
|
+
}
|
641
|
+
|
642
|
+
static int test_link_timeout_update_invalid(struct io_uring *ring, int async)
|
643
|
+
{
|
644
|
+
struct __kernel_timespec ts;
|
645
|
+
struct io_uring_cqe *cqe;
|
646
|
+
struct io_uring_sqe *sqe;
|
647
|
+
int ret;
|
648
|
+
|
649
|
+
ts.tv_sec = 0;
|
650
|
+
ts.tv_nsec = 100000000LL;
|
651
|
+
sqe = io_uring_get_sqe(ring);
|
652
|
+
io_uring_prep_timeout_update(sqe, &ts, 2, IORING_LINK_TIMEOUT_UPDATE);
|
653
|
+
sqe->user_data = 0xcafe0000;
|
654
|
+
if (async)
|
655
|
+
sqe->flags |= IOSQE_ASYNC;
|
656
|
+
|
657
|
+
io_uring_submit(ring);
|
658
|
+
|
659
|
+
ret = io_uring_wait_cqe(ring, &cqe);
|
660
|
+
if (ret < 0) {
|
661
|
+
printf("wait completion %d\n", ret);
|
662
|
+
goto err;
|
663
|
+
}
|
664
|
+
if (cqe->res != -ENOENT) {
|
665
|
+
fprintf(stderr, "bad timeout update: %d\n", cqe->res);
|
666
|
+
goto err;
|
667
|
+
}
|
668
|
+
io_uring_cqe_seen(ring, cqe);
|
669
|
+
return 0;
|
670
|
+
err:
|
671
|
+
return 1;
|
672
|
+
}
|
673
|
+
|
540
674
|
static int test_timeout_link_chain1(struct io_uring *ring)
|
541
675
|
{
|
542
676
|
struct __kernel_timespec ts;
|
@@ -1104,5 +1238,30 @@ int main(int argc, char *argv[])
|
|
1104
1238
|
return ret;
|
1105
1239
|
}
|
1106
1240
|
|
1241
|
+
ret = test_link_timeout_update(&ring, 0);
|
1242
|
+
if (ret) {
|
1243
|
+
printf("test_link_timeout_update 0 failed\n");
|
1244
|
+
return ret;
|
1245
|
+
}
|
1246
|
+
|
1247
|
+
ret = test_link_timeout_update(&ring, 1);
|
1248
|
+
if (ret) {
|
1249
|
+
printf("test_link_timeout_update 1 failed\n");
|
1250
|
+
return ret;
|
1251
|
+
}
|
1252
|
+
|
1253
|
+
ret = test_link_timeout_update_invalid(&ring, 0);
|
1254
|
+
if (ret) {
|
1255
|
+
printf("test_link_timeout_update_invalid 0 failed\n");
|
1256
|
+
return ret;
|
1257
|
+
}
|
1258
|
+
|
1259
|
+
ret = test_link_timeout_update_invalid(&ring, 1);
|
1260
|
+
if (ret) {
|
1261
|
+
printf("test_link_timeout_update_invalid 1 failed\n");
|
1262
|
+
return ret;
|
1263
|
+
}
|
1264
|
+
|
1265
|
+
|
1107
1266
|
return T_EXIT_PASS;
|
1108
1267
|
}
|