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
@@ -80,7 +80,7 @@ static int __test_io(const char *file, struct io_uring *ring, int write,
|
|
80
80
|
if (fixed) {
|
81
81
|
ret = t_register_buffers(ring, vecs, BUFFERS);
|
82
82
|
if (ret == T_SETUP_SKIP)
|
83
|
-
return
|
83
|
+
return T_EXIT_SKIP;
|
84
84
|
if (ret != T_SETUP_OK) {
|
85
85
|
fprintf(stderr, "buffer reg failed: %d\n", ret);
|
86
86
|
goto err;
|
@@ -91,6 +91,8 @@ static int __test_io(const char *file, struct io_uring *ring, int write,
|
|
91
91
|
if (fd < 0) {
|
92
92
|
if (errno == EINVAL)
|
93
93
|
return 0;
|
94
|
+
if (errno == EPERM || errno == EACCES)
|
95
|
+
return T_EXIT_SKIP;
|
94
96
|
perror("file open");
|
95
97
|
goto err;
|
96
98
|
}
|
@@ -290,6 +292,7 @@ static int has_nonvec_read(void)
|
|
290
292
|
if (ret == -EINVAL) {
|
291
293
|
out:
|
292
294
|
io_uring_queue_exit(&ring);
|
295
|
+
free(p);
|
293
296
|
return 0;
|
294
297
|
} else if (ret) {
|
295
298
|
fprintf(stderr, "register_probe: %d\n", ret);
|
@@ -301,6 +304,7 @@ out:
|
|
301
304
|
if (!(p->ops[IORING_OP_READ].flags & IO_URING_OP_SUPPORTED))
|
302
305
|
goto out;
|
303
306
|
io_uring_queue_exit(&ring);
|
307
|
+
free(p);
|
304
308
|
return 1;
|
305
309
|
}
|
306
310
|
|
@@ -318,6 +322,8 @@ static int test_eventfd_read(int flags)
|
|
318
322
|
if (ret == T_SETUP_SKIP)
|
319
323
|
return 0;
|
320
324
|
if (ret != T_SETUP_OK) {
|
325
|
+
if (ret == -EINVAL)
|
326
|
+
return 0;
|
321
327
|
fprintf(stderr, "ring create failed: %d\n", ret);
|
322
328
|
return 1;
|
323
329
|
}
|
@@ -384,6 +390,8 @@ int main(int argc, char *argv[])
|
|
384
390
|
|
385
391
|
ret = test_io(fname, write, buffered, sqthread, fixed, nonvec,
|
386
392
|
BS);
|
393
|
+
if (ret == T_EXIT_SKIP)
|
394
|
+
continue;
|
387
395
|
if (ret) {
|
388
396
|
fprintf(stderr, "test_io failed %d/%d/%d/%d/%d\n",
|
389
397
|
write, buffered, sqthread, fixed, nonvec);
|
@@ -0,0 +1,69 @@
|
|
1
|
+
/* SPDX-License-Identifier: MIT */
|
2
|
+
/*
|
3
|
+
* Description: Test O_NONBLOCK reading from fifo, should result in proper
|
4
|
+
* retry and a positive read results. Buggy result would be
|
5
|
+
* -EAGAIN being returned to the user.
|
6
|
+
*/
|
7
|
+
#include <stdio.h>
|
8
|
+
#include <stdlib.h>
|
9
|
+
#include <unistd.h>
|
10
|
+
|
11
|
+
#include "liburing.h"
|
12
|
+
#include "helpers.h"
|
13
|
+
|
14
|
+
int main(int argc, char *argv[])
|
15
|
+
{
|
16
|
+
struct io_uring_sqe *sqe;
|
17
|
+
struct io_uring_cqe *cqe;
|
18
|
+
struct io_uring ring;
|
19
|
+
char buf[32];
|
20
|
+
int fds[2];
|
21
|
+
int flags;
|
22
|
+
int ret;
|
23
|
+
|
24
|
+
io_uring_queue_init(1, &ring, 0);
|
25
|
+
|
26
|
+
if (pipe(fds) < 0) {
|
27
|
+
perror("pipe");
|
28
|
+
return T_EXIT_FAIL;
|
29
|
+
}
|
30
|
+
|
31
|
+
flags = fcntl(fds[0], F_GETFL, 0);
|
32
|
+
if (flags < 0) {
|
33
|
+
perror("fcntl get");
|
34
|
+
return T_EXIT_FAIL;
|
35
|
+
}
|
36
|
+
flags |= O_NONBLOCK;
|
37
|
+
ret = fcntl(fds[0], F_SETFL, flags);
|
38
|
+
if (ret < 0) {
|
39
|
+
perror("fcntl set");
|
40
|
+
return T_EXIT_FAIL;
|
41
|
+
}
|
42
|
+
|
43
|
+
sqe = io_uring_get_sqe(&ring);
|
44
|
+
io_uring_prep_read(sqe, fds[0], buf, sizeof(buf), 0);
|
45
|
+
io_uring_submit(&ring);
|
46
|
+
|
47
|
+
usleep(10000);
|
48
|
+
|
49
|
+
ret = write(fds[1], "Hello\n", 6);
|
50
|
+
if (ret < 0) {
|
51
|
+
perror("pipe write");
|
52
|
+
return T_EXIT_FAIL;
|
53
|
+
}
|
54
|
+
|
55
|
+
ret = io_uring_wait_cqe(&ring, &cqe);
|
56
|
+
if (ret < 0) {
|
57
|
+
fprintf(stderr, "wait=%d\n", ret);
|
58
|
+
return T_EXIT_FAIL;
|
59
|
+
}
|
60
|
+
|
61
|
+
if (cqe->res < 0) {
|
62
|
+
fprintf(stderr, "cqe res %d\n", cqe->res);
|
63
|
+
return T_EXIT_FAIL;
|
64
|
+
}
|
65
|
+
|
66
|
+
io_uring_cqe_seen(&ring, cqe);
|
67
|
+
io_uring_queue_exit(&ring);
|
68
|
+
return T_EXIT_PASS;
|
69
|
+
}
|
@@ -0,0 +1,48 @@
|
|
1
|
+
/* SPDX-License-Identifier: MIT */
|
2
|
+
/*
|
3
|
+
* Description: test that a defer task_work file with tags unregistration
|
4
|
+
* doesn't trigger a lockdep violation
|
5
|
+
*
|
6
|
+
*/
|
7
|
+
#include <stdio.h>
|
8
|
+
#include <inttypes.h>
|
9
|
+
#include <stdlib.h>
|
10
|
+
#include <unistd.h>
|
11
|
+
|
12
|
+
#include "liburing.h"
|
13
|
+
#include "helpers.h"
|
14
|
+
|
15
|
+
int main(int argc, char *argv[])
|
16
|
+
{
|
17
|
+
__u64 tags[2] = { 1, 2 };
|
18
|
+
struct io_uring ring;
|
19
|
+
int fds[2], ret;
|
20
|
+
|
21
|
+
if (argc > 1)
|
22
|
+
return T_EXIT_SKIP;
|
23
|
+
|
24
|
+
if (pipe(fds) < 0) {
|
25
|
+
perror("pipe");
|
26
|
+
return 1;
|
27
|
+
}
|
28
|
+
|
29
|
+
ret = io_uring_queue_init(4, &ring, IORING_SETUP_SINGLE_ISSUER|IORING_SETUP_DEFER_TASKRUN);
|
30
|
+
if (ret == -EINVAL) {
|
31
|
+
return T_EXIT_SKIP;
|
32
|
+
} else if (ret < 0) {
|
33
|
+
fprintf(stderr, "queue_init: %d\n", ret);
|
34
|
+
return T_EXIT_FAIL;
|
35
|
+
}
|
36
|
+
|
37
|
+
ret = io_uring_register_files_tags(&ring, fds, tags, 2);
|
38
|
+
if (ret == -EINVAL) {
|
39
|
+
return T_EXIT_SKIP;
|
40
|
+
} else if (ret < 0) {
|
41
|
+
fprintf(stderr, "file_register_init: %d\n", ret);
|
42
|
+
return T_EXIT_FAIL;
|
43
|
+
}
|
44
|
+
|
45
|
+
io_uring_queue_exit(&ring);
|
46
|
+
sleep(1);
|
47
|
+
return 0;
|
48
|
+
}
|
@@ -120,16 +120,21 @@ static int test_grow(struct io_uring *ring)
|
|
120
120
|
fds = open_files(1, 0, off);
|
121
121
|
ret = io_uring_register_files_update(ring, off, fds, 1);
|
122
122
|
if (ret != 1) {
|
123
|
-
if (off == 300 && ret == -EINVAL)
|
123
|
+
if (off == 300 && ret == -EINVAL) {
|
124
|
+
free(fds);
|
124
125
|
break;
|
126
|
+
}
|
125
127
|
fprintf(stderr, "%s: update ret=%d\n", __FUNCTION__, ret);
|
128
|
+
free(fds);
|
126
129
|
break;
|
127
130
|
}
|
128
131
|
if (off >= 300) {
|
129
132
|
fprintf(stderr, "%s: Succeeded beyond end-of-list?\n", __FUNCTION__);
|
133
|
+
free(fds);
|
130
134
|
goto err;
|
131
135
|
}
|
132
136
|
off++;
|
137
|
+
free(fds);
|
133
138
|
} while (1);
|
134
139
|
|
135
140
|
ret = io_uring_unregister_files(ring);
|
@@ -363,8 +368,10 @@ static int test_basic(struct io_uring *ring, int fail)
|
|
363
368
|
ret = io_uring_register_files(ring, files, 100);
|
364
369
|
if (ret) {
|
365
370
|
if (fail) {
|
366
|
-
if (ret == -EBADF || ret == -EFAULT)
|
371
|
+
if (ret == -EBADF || ret == -EFAULT) {
|
372
|
+
close_files(files, nr_files, 0);
|
367
373
|
return 0;
|
374
|
+
}
|
368
375
|
}
|
369
376
|
fprintf(stderr, "%s: register %d\n", __FUNCTION__, ret);
|
370
377
|
goto err;
|
@@ -631,6 +638,7 @@ static int test_sparse_updates(void)
|
|
631
638
|
ret = io_uring_register_files(&ring, fds, 256);
|
632
639
|
if (ret) {
|
633
640
|
fprintf(stderr, "file_register: %d\n", ret);
|
641
|
+
free(fds);
|
634
642
|
return ret;
|
635
643
|
}
|
636
644
|
|
@@ -639,6 +647,7 @@ static int test_sparse_updates(void)
|
|
639
647
|
ret = io_uring_register_files_update(&ring, i, &newfd, 1);
|
640
648
|
if (ret != 1) {
|
641
649
|
fprintf(stderr, "file_update: %d\n", ret);
|
650
|
+
free(fds);
|
642
651
|
return ret;
|
643
652
|
}
|
644
653
|
}
|
@@ -650,6 +659,7 @@ static int test_sparse_updates(void)
|
|
650
659
|
ret = io_uring_register_files(&ring, fds, 256);
|
651
660
|
if (ret) {
|
652
661
|
fprintf(stderr, "file_register: %d\n", ret);
|
662
|
+
free(fds);
|
653
663
|
return ret;
|
654
664
|
}
|
655
665
|
|
@@ -658,12 +668,14 @@ static int test_sparse_updates(void)
|
|
658
668
|
ret = io_uring_register_files_update(&ring, i, &newfd, 1);
|
659
669
|
if (ret != 1) {
|
660
670
|
fprintf(stderr, "file_update: %d\n", ret);
|
671
|
+
free(fds);
|
661
672
|
return ret;
|
662
673
|
}
|
663
674
|
}
|
664
675
|
io_uring_unregister_files(&ring);
|
665
676
|
|
666
677
|
io_uring_queue_exit(&ring);
|
678
|
+
free(fds);
|
667
679
|
return 0;
|
668
680
|
}
|
669
681
|
|
@@ -174,7 +174,7 @@ static int test_update_no_table(void)
|
|
174
174
|
ret = cqe->res;
|
175
175
|
io_uring_cqe_seen(&ring, cqe);
|
176
176
|
if (ret != -EMFILE && ret != -EINVAL && ret != -EOVERFLOW &&
|
177
|
-
ret != -ENXIO) {
|
177
|
+
ret != -ENXIO && ret != -EBADF) {
|
178
178
|
fprintf(stderr, "Bad cqe res: %d\n", ret);
|
179
179
|
goto fail;
|
180
180
|
}
|
@@ -90,6 +90,8 @@ static int test_truncate(struct io_uring *ring, const char *fname, int buffered,
|
|
90
90
|
else
|
91
91
|
fd = open(fname, O_DIRECT | O_RDWR);
|
92
92
|
if (fd < 0) {
|
93
|
+
if (!buffered && errno == EINVAL)
|
94
|
+
return T_EXIT_SKIP;
|
93
95
|
perror("open");
|
94
96
|
return 1;
|
95
97
|
}
|
@@ -346,6 +348,8 @@ static int test(struct io_uring *ring, const char *fname, int buffered,
|
|
346
348
|
flags |= O_DIRECT;
|
347
349
|
fd = open(fname, flags);
|
348
350
|
if (fd < 0) {
|
351
|
+
if (errno == EINVAL || errno == EPERM || errno == EACCES)
|
352
|
+
return T_EXIT_SKIP;
|
349
353
|
perror("open");
|
350
354
|
return 1;
|
351
355
|
}
|
@@ -505,6 +509,8 @@ static int fill_pattern(const char *fname)
|
|
505
509
|
|
506
510
|
fd = open(fname, O_WRONLY);
|
507
511
|
if (fd < 0) {
|
512
|
+
if (errno == EPERM || errno == EACCES)
|
513
|
+
return T_EXIT_SKIP;
|
508
514
|
perror("open");
|
509
515
|
return 1;
|
510
516
|
}
|
@@ -557,89 +563,94 @@ int main(int argc, char *argv[])
|
|
557
563
|
goto err;
|
558
564
|
}
|
559
565
|
|
560
|
-
|
566
|
+
ret = fill_pattern(fname);
|
567
|
+
if (ret == T_EXIT_SKIP)
|
568
|
+
return T_EXIT_SKIP;
|
569
|
+
else if (ret)
|
561
570
|
goto err;
|
562
571
|
|
563
572
|
ret = test(&ring, fname, 1, 0, 0, 0, 0);
|
573
|
+
if (ret == T_EXIT_SKIP)
|
574
|
+
return T_EXIT_SKIP;
|
564
575
|
if (ret) {
|
565
576
|
fprintf(stderr, "Buffered novec test failed\n");
|
566
577
|
goto err;
|
567
578
|
}
|
568
579
|
ret = test(&ring, fname, 1, 0, 0, 1, 0);
|
569
|
-
if (ret) {
|
580
|
+
if (ret == T_EXIT_FAIL) {
|
570
581
|
fprintf(stderr, "Buffered novec reg test failed\n");
|
571
582
|
goto err;
|
572
583
|
}
|
573
584
|
ret = test(&ring, fname, 1, 0, 0, 0, 1);
|
574
|
-
if (ret) {
|
585
|
+
if (ret == T_EXIT_FAIL) {
|
575
586
|
fprintf(stderr, "Buffered novec provide test failed\n");
|
576
587
|
goto err;
|
577
588
|
}
|
578
589
|
ret = test(&ring, fname, 1, 1, 0, 0, 0);
|
579
|
-
if (ret) {
|
590
|
+
if (ret == T_EXIT_FAIL) {
|
580
591
|
fprintf(stderr, "Buffered vec test failed\n");
|
581
592
|
goto err;
|
582
593
|
}
|
583
594
|
ret = test(&ring, fname, 1, 1, 1, 0, 0);
|
584
|
-
if (ret) {
|
595
|
+
if (ret == T_EXIT_FAIL) {
|
585
596
|
fprintf(stderr, "Buffered small vec test failed\n");
|
586
597
|
goto err;
|
587
598
|
}
|
588
599
|
|
589
600
|
ret = test(&ring, fname, 0, 0, 0, 0, 0);
|
590
|
-
if (ret) {
|
601
|
+
if (ret == T_EXIT_FAIL) {
|
591
602
|
fprintf(stderr, "O_DIRECT novec test failed\n");
|
592
603
|
goto err;
|
593
604
|
}
|
594
605
|
ret = test(&ring, fname, 0, 0, 0, 1, 0);
|
595
|
-
if (ret) {
|
606
|
+
if (ret == T_EXIT_FAIL) {
|
596
607
|
fprintf(stderr, "O_DIRECT novec reg test failed\n");
|
597
608
|
goto err;
|
598
609
|
}
|
599
610
|
ret = test(&ring, fname, 0, 0, 0, 0, 1);
|
600
|
-
if (ret) {
|
611
|
+
if (ret == T_EXIT_FAIL) {
|
601
612
|
fprintf(stderr, "O_DIRECT novec provide test failed\n");
|
602
613
|
goto err;
|
603
614
|
}
|
604
615
|
ret = test(&ring, fname, 0, 1, 0, 0, 0);
|
605
|
-
if (ret) {
|
616
|
+
if (ret == T_EXIT_FAIL) {
|
606
617
|
fprintf(stderr, "O_DIRECT vec test failed\n");
|
607
618
|
goto err;
|
608
619
|
}
|
609
620
|
ret = test(&ring, fname, 0, 1, 1, 0, 0);
|
610
|
-
if (ret) {
|
621
|
+
if (ret == T_EXIT_FAIL) {
|
611
622
|
fprintf(stderr, "O_DIRECT small vec test failed\n");
|
612
623
|
goto err;
|
613
624
|
}
|
614
625
|
|
615
626
|
ret = test_truncate(&ring, fname, 1, 0, 0);
|
616
|
-
if (ret) {
|
627
|
+
if (ret == T_EXIT_FAIL) {
|
617
628
|
fprintf(stderr, "Buffered end truncate read failed\n");
|
618
629
|
goto err;
|
619
630
|
}
|
620
631
|
ret = test_truncate(&ring, fname, 1, 1, 0);
|
621
|
-
if (ret) {
|
632
|
+
if (ret == T_EXIT_FAIL) {
|
622
633
|
fprintf(stderr, "Buffered end truncate vec read failed\n");
|
623
634
|
goto err;
|
624
635
|
}
|
625
636
|
ret = test_truncate(&ring, fname, 1, 0, 1);
|
626
|
-
if (ret) {
|
637
|
+
if (ret == T_EXIT_FAIL) {
|
627
638
|
fprintf(stderr, "Buffered end truncate pbuf read failed\n");
|
628
639
|
goto err;
|
629
640
|
}
|
630
641
|
|
631
642
|
ret = test_truncate(&ring, fname, 0, 0, 0);
|
632
|
-
if (ret) {
|
643
|
+
if (ret == T_EXIT_FAIL) {
|
633
644
|
fprintf(stderr, "O_DIRECT end truncate read failed\n");
|
634
645
|
goto err;
|
635
646
|
}
|
636
647
|
ret = test_truncate(&ring, fname, 0, 1, 0);
|
637
|
-
if (ret) {
|
648
|
+
if (ret == T_EXIT_FAIL) {
|
638
649
|
fprintf(stderr, "O_DIRECT end truncate vec read failed\n");
|
639
650
|
goto err;
|
640
651
|
}
|
641
652
|
ret = test_truncate(&ring, fname, 0, 0, 1);
|
642
|
-
if (ret) {
|
653
|
+
if (ret == T_EXIT_FAIL) {
|
643
654
|
fprintf(stderr, "O_DIRECT end truncate pbuf read failed\n");
|
644
655
|
goto err;
|
645
656
|
}
|
@@ -43,13 +43,12 @@ static void add_accept(struct io_uring *ring, int fd)
|
|
43
43
|
|
44
44
|
sqe = io_uring_get_sqe(ring);
|
45
45
|
io_uring_prep_accept(sqe, fd, 0, 0, SOCK_NONBLOCK | SOCK_CLOEXEC);
|
46
|
-
sqe->flags |= IOSQE_IO_LINK;
|
47
46
|
}
|
48
47
|
|
49
48
|
static int setup_io_uring(void)
|
50
49
|
{
|
51
50
|
int ret;
|
52
|
-
|
51
|
+
|
53
52
|
ret = io_uring_queue_init(16, &ring, 0);
|
54
53
|
if (ret) {
|
55
54
|
fprintf(stderr, "Unable to setup io_uring: %s\n", strerror(-ret));
|
@@ -63,7 +63,7 @@ static int test(struct io_uring *ring)
|
|
63
63
|
return 1;
|
64
64
|
}
|
65
65
|
|
66
|
-
if (cqe->res < 0) {
|
66
|
+
if (cqe->res < 0) {
|
67
67
|
fprintf(stderr, "Error in async operation: %s\n", strerror(-cqe->res));
|
68
68
|
return 1;
|
69
69
|
}
|
@@ -87,6 +87,8 @@ static int test(struct io_uring *ring)
|
|
87
87
|
return 1;
|
88
88
|
}
|
89
89
|
io_uring_cqe_seen(ring, cqe);
|
90
|
+
for (i = 0; i < BUFFERS; i++)
|
91
|
+
free(iov[i].iov_base);
|
90
92
|
return 0;
|
91
93
|
}
|
92
94
|
|
@@ -246,7 +246,8 @@ static int register_submit(struct io_uring *ring, struct iovec *iov,
|
|
246
246
|
|
247
247
|
ret = io_uring_register_buffers(ring, iov, nr_bufs);
|
248
248
|
if (ret) {
|
249
|
-
|
249
|
+
if (ret != -ENOMEM)
|
250
|
+
fprintf(stderr, "Error registering buffers: %s\n", strerror(-ret));
|
250
251
|
return ret;
|
251
252
|
}
|
252
253
|
|
@@ -282,6 +283,8 @@ static int test_one_hugepage(struct io_uring *ring, int fd_in, int fd_out)
|
|
282
283
|
|
283
284
|
ret = register_submit(ring, iov, NR_BUFS, fd_in, fd_out);
|
284
285
|
unmap(iov, NR_BUFS, 0);
|
286
|
+
if (ret == -ENOMEM)
|
287
|
+
return T_EXIT_SKIP;
|
285
288
|
return ret ? T_EXIT_FAIL : T_EXIT_PASS;
|
286
289
|
}
|
287
290
|
|
@@ -296,6 +299,8 @@ static int test_multi_hugepages(struct io_uring *ring, int fd_in, int fd_out)
|
|
296
299
|
|
297
300
|
ret = register_submit(ring, iov, NR_BUFS, fd_in, fd_out);
|
298
301
|
unmap(iov, NR_BUFS, 0);
|
302
|
+
if (ret == -ENOMEM)
|
303
|
+
return T_EXIT_SKIP;
|
299
304
|
return ret ? T_EXIT_FAIL : T_EXIT_PASS;
|
300
305
|
}
|
301
306
|
|
@@ -311,6 +316,8 @@ static int test_unaligned_hugepage(struct io_uring *ring, int fd_in, int fd_out)
|
|
311
316
|
|
312
317
|
ret = register_submit(ring, iov, NR_BUFS, fd_in, fd_out);
|
313
318
|
unmap(iov, NR_BUFS, offset);
|
319
|
+
if (ret == -ENOMEM)
|
320
|
+
return T_EXIT_SKIP;
|
314
321
|
return ret ? T_EXIT_FAIL : T_EXIT_PASS;
|
315
322
|
}
|
316
323
|
|
@@ -326,6 +333,8 @@ static int test_multi_unaligned_mthps(struct io_uring *ring, int fd_in, int fd_o
|
|
326
333
|
|
327
334
|
ret = register_submit(ring, iov, NR_BUFS, fd_in, fd_out);
|
328
335
|
free_bufs(iov, NR_BUFS, offset);
|
336
|
+
if (ret == -ENOMEM)
|
337
|
+
return T_EXIT_SKIP;
|
329
338
|
return ret ? T_EXIT_FAIL : T_EXIT_PASS;
|
330
339
|
}
|
331
340
|
|
@@ -341,6 +350,8 @@ static int test_page_mixture(struct io_uring *ring, int fd_in, int fd_out, int h
|
|
341
350
|
|
342
351
|
ret = register_submit(ring, iov, NR_BUFS, fd_in, fd_out);
|
343
352
|
unmap(iov, NR_BUFS, 0);
|
353
|
+
if (ret == -ENOMEM)
|
354
|
+
return T_EXIT_SKIP;
|
344
355
|
return ret ? T_EXIT_FAIL : T_EXIT_PASS;
|
345
356
|
}
|
346
357
|
|
@@ -120,6 +120,7 @@ static int __test(struct io_uring *ring, int vectored, int async,
|
|
120
120
|
|
121
121
|
if (cqe->res == -EINVAL || cqe->res == -EOPNOTSUPP) {
|
122
122
|
no_futex = 1;
|
123
|
+
free(futex);
|
123
124
|
return 0;
|
124
125
|
}
|
125
126
|
io_uring_cqe_seen(ring, cqe);
|
@@ -134,6 +135,7 @@ static int __test(struct io_uring *ring, int vectored, int async,
|
|
134
135
|
for (i = 0; i < nfutex; i++)
|
135
136
|
pthread_join(threads[i], &tret);
|
136
137
|
|
138
|
+
free(futex);
|
137
139
|
return 0;
|
138
140
|
}
|
139
141
|
|
@@ -145,7 +147,7 @@ static int test(int flags, int vectored)
|
|
145
147
|
ret = io_uring_queue_init(8, &ring, flags);
|
146
148
|
if (ret)
|
147
149
|
return ret;
|
148
|
-
|
150
|
+
|
149
151
|
for (i = 0; i < LOOPS; i++) {
|
150
152
|
int async_cancel = (!i % 2);
|
151
153
|
int async_wait = !(i % 3);
|
@@ -166,7 +168,8 @@ static int test_order(int vectored, int async)
|
|
166
168
|
{
|
167
169
|
struct io_uring_sqe *sqe;
|
168
170
|
struct io_uring_cqe *cqe;
|
169
|
-
struct futex_waitv fw;
|
171
|
+
struct futex_waitv fw = { };
|
172
|
+
struct io_uring_sync_cancel_reg reg = { };
|
170
173
|
struct io_uring ring;
|
171
174
|
unsigned int *futex;
|
172
175
|
int ret, i;
|
@@ -178,10 +181,8 @@ static int test_order(int vectored, int async)
|
|
178
181
|
futex = malloc(sizeof(*futex));
|
179
182
|
*futex = 0;
|
180
183
|
|
181
|
-
fw.val = 0;
|
182
184
|
fw.uaddr = (unsigned long) futex;
|
183
185
|
fw.flags = FUTEX2_SIZE_U32;
|
184
|
-
fw.__reserved = 0;
|
185
186
|
|
186
187
|
/*
|
187
188
|
* Submit two futex waits
|
@@ -241,7 +242,15 @@ static int test_order(int vectored, int async)
|
|
241
242
|
return 1;
|
242
243
|
}
|
243
244
|
|
245
|
+
reg.addr = 2;
|
246
|
+
ret = io_uring_register_sync_cancel(&ring, ®);
|
247
|
+
if (ret != 1) {
|
248
|
+
fprintf(stderr, "Failed to cancel pending futex wait: %d\n", ret);
|
249
|
+
return 1;
|
250
|
+
}
|
251
|
+
|
244
252
|
io_uring_queue_exit(&ring);
|
253
|
+
free(futex);
|
245
254
|
return 0;
|
246
255
|
}
|
247
256
|
|
@@ -322,6 +331,7 @@ static int test_multi_wake(int vectored)
|
|
322
331
|
}
|
323
332
|
|
324
333
|
io_uring_queue_exit(&ring);
|
334
|
+
free(futex);
|
325
335
|
return 0;
|
326
336
|
}
|
327
337
|
|
@@ -378,6 +388,7 @@ static int test_wake_zero(void)
|
|
378
388
|
}
|
379
389
|
|
380
390
|
io_uring_queue_exit(&ring);
|
391
|
+
free(futex);
|
381
392
|
return 0;
|
382
393
|
}
|
383
394
|
|
@@ -459,6 +470,7 @@ static int test_invalid(void)
|
|
459
470
|
io_uring_cqe_seen(&ring, cqe);
|
460
471
|
|
461
472
|
io_uring_queue_exit(&ring);
|
473
|
+
free(futex);
|
462
474
|
return 0;
|
463
475
|
}
|
464
476
|
|
@@ -316,3 +316,50 @@ void t_error(int status, int errnum, const char *format, ...)
|
|
316
316
|
va_end(args);
|
317
317
|
exit(status);
|
318
318
|
}
|
319
|
+
|
320
|
+
unsigned long long mtime_since(const struct timeval *s, const struct timeval *e)
|
321
|
+
{
|
322
|
+
long long sec, usec;
|
323
|
+
|
324
|
+
sec = e->tv_sec - s->tv_sec;
|
325
|
+
usec = (e->tv_usec - s->tv_usec);
|
326
|
+
if (sec > 0 && usec < 0) {
|
327
|
+
sec--;
|
328
|
+
usec += 1000000;
|
329
|
+
}
|
330
|
+
|
331
|
+
sec *= 1000;
|
332
|
+
usec /= 1000;
|
333
|
+
return sec + usec;
|
334
|
+
}
|
335
|
+
|
336
|
+
unsigned long long mtime_since_now(struct timeval *tv)
|
337
|
+
{
|
338
|
+
struct timeval end;
|
339
|
+
|
340
|
+
gettimeofday(&end, NULL);
|
341
|
+
return mtime_since(tv, &end);
|
342
|
+
}
|
343
|
+
|
344
|
+
unsigned long long utime_since(const struct timeval *s, const struct timeval *e)
|
345
|
+
{
|
346
|
+
long long sec, usec;
|
347
|
+
|
348
|
+
sec = e->tv_sec - s->tv_sec;
|
349
|
+
usec = (e->tv_usec - s->tv_usec);
|
350
|
+
if (sec > 0 && usec < 0) {
|
351
|
+
sec--;
|
352
|
+
usec += 1000000;
|
353
|
+
}
|
354
|
+
|
355
|
+
sec *= 1000000;
|
356
|
+
return sec + usec;
|
357
|
+
}
|
358
|
+
|
359
|
+
unsigned long long utime_since_now(struct timeval *tv)
|
360
|
+
{
|
361
|
+
struct timeval end;
|
362
|
+
|
363
|
+
gettimeofday(&end, NULL);
|
364
|
+
return utime_since(tv, &end);
|
365
|
+
}
|
@@ -12,6 +12,7 @@ extern "C" {
|
|
12
12
|
#include "liburing.h"
|
13
13
|
#include "../src/setup.h"
|
14
14
|
#include <arpa/inet.h>
|
15
|
+
#include <sys/time.h>
|
15
16
|
|
16
17
|
enum t_setup_ret {
|
17
18
|
T_SETUP_OK = 0,
|
@@ -101,6 +102,11 @@ static inline int t_io_uring_init_sqarray(unsigned entries, struct io_uring *rin
|
|
101
102
|
|
102
103
|
void t_error(int status, int errnum, const char *format, ...);
|
103
104
|
|
105
|
+
unsigned long long mtime_since(const struct timeval *s, const struct timeval *e);
|
106
|
+
unsigned long long mtime_since_now(struct timeval *tv);
|
107
|
+
unsigned long long utime_since(const struct timeval *s, const struct timeval *e);
|
108
|
+
unsigned long long utime_since_now(struct timeval *tv);
|
109
|
+
|
104
110
|
#ifdef __cplusplus
|
105
111
|
}
|
106
112
|
#endif
|
@@ -13,7 +13,6 @@
|
|
13
13
|
#include <netinet/udp.h>
|
14
14
|
#include <arpa/inet.h>
|
15
15
|
#include <net/if.h>
|
16
|
-
#include <error.h>
|
17
16
|
|
18
17
|
#include "liburing.h"
|
19
18
|
#include "helpers.h"
|
@@ -68,6 +67,7 @@ static int setup_ctx(struct ctx *ctx, struct q_entries *q)
|
|
68
67
|
static void clean_ctx(struct ctx *ctx)
|
69
68
|
{
|
70
69
|
io_uring_queue_exit(&ctx->ring);
|
70
|
+
free(ctx->mem);
|
71
71
|
}
|
72
72
|
|
73
73
|
static int check_red(struct ctx *ctx, unsigned long i)
|
@@ -94,10 +94,12 @@ static int test(struct q_entries *q)
|
|
94
94
|
int j, ret, batch;
|
95
95
|
|
96
96
|
ret = setup_ctx(&ctx, q);
|
97
|
-
if (ret == T_EXIT_SKIP)
|
97
|
+
if (ret == T_EXIT_SKIP) {
|
98
|
+
clean_ctx(&ctx);
|
98
99
|
return T_EXIT_SKIP;
|
99
|
-
else if (ret != T_EXIT_PASS)
|
100
|
+
} else if (ret != T_EXIT_PASS) {
|
100
101
|
return ret;
|
102
|
+
}
|
101
103
|
|
102
104
|
batch = 64;
|
103
105
|
if (batch > q->sqes)
|
@@ -22,30 +22,6 @@
|
|
22
22
|
|
23
23
|
static struct iovec *vecs;
|
24
24
|
|
25
|
-
static unsigned long long utime_since(const struct timeval *s,
|
26
|
-
const struct timeval *e)
|
27
|
-
{
|
28
|
-
long long sec, usec;
|
29
|
-
|
30
|
-
sec = e->tv_sec - s->tv_sec;
|
31
|
-
usec = (e->tv_usec - s->tv_usec);
|
32
|
-
if (sec > 0 && usec < 0) {
|
33
|
-
sec--;
|
34
|
-
usec += 1000000;
|
35
|
-
}
|
36
|
-
|
37
|
-
sec *= 1000000;
|
38
|
-
return sec + usec;
|
39
|
-
}
|
40
|
-
|
41
|
-
static unsigned long long utime_since_now(struct timeval *tv)
|
42
|
-
{
|
43
|
-
struct timeval end;
|
44
|
-
|
45
|
-
gettimeofday(&end, NULL);
|
46
|
-
return utime_since(tv, &end);
|
47
|
-
}
|
48
|
-
|
49
25
|
static int start_io(struct io_uring *ring, int fd, int do_write)
|
50
26
|
{
|
51
27
|
struct io_uring_sqe *sqe;
|