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
@@ -114,9 +114,12 @@ run_test()
|
|
114
114
|
elif [ "$status" -eq 77 ]; then
|
115
115
|
echo "Skipped"
|
116
116
|
SKIPPED+=("<$test_string>")
|
117
|
-
elif [ "$status" -ne 0 ]; then
|
117
|
+
elif [[ $test_string != xfail* ]] && [ "$status" -ne 0 ]; then
|
118
118
|
echo "Test $test_name failed with ret $status"
|
119
119
|
FAILED+=("<$test_string>")
|
120
|
+
elif [[ $test_string == xfail* ]] && [ "$status" -ne 1 ]; then
|
121
|
+
echo "Test $test_name expected fail status 1 but returned $status"
|
122
|
+
FAILED+=("<$test_string>")
|
120
123
|
elif ! _check_dmesg "$dmesg_marker" "$test_name"; then
|
121
124
|
echo "Test $test_name failed dmesg check"
|
122
125
|
FAILED+=("<$test_string>")
|
@@ -153,10 +156,22 @@ for tst in "${TESTS[@]}"; do
|
|
153
156
|
fi
|
154
157
|
done
|
155
158
|
|
159
|
+
if [ "$DO_KMSG" -eq "1" ]; then
|
160
|
+
for dmesg_file in *.dmesg; do
|
161
|
+
if [ -f "$dmesg_file" ]; then
|
162
|
+
echo "Found dmesg file $dmesg_file, outputting:"
|
163
|
+
cat "$dmesg_file"
|
164
|
+
fi
|
165
|
+
done
|
166
|
+
fi
|
167
|
+
|
156
168
|
if [ "${#TIMED_OUT[*]}" -ne 0 ]; then
|
157
169
|
echo "Tests timed out (${#TIMED_OUT[*]}): ${TIMED_OUT[*]}"
|
158
170
|
fi
|
159
171
|
|
172
|
+
KVER=$(uname -rv)
|
173
|
+
echo "Test run complete, kernel: $KVER"
|
174
|
+
|
160
175
|
if [ "${#FAILED[*]}" -ne 0 ]; then
|
161
176
|
echo "Tests failed (${#FAILED[*]}): ${FAILED[*]}"
|
162
177
|
exit 1
|
@@ -739,6 +739,59 @@ static int test_async_addr(struct io_uring *ring)
|
|
739
739
|
return 0;
|
740
740
|
}
|
741
741
|
|
742
|
+
static int test_sendzc_report(struct io_uring *ring)
|
743
|
+
{
|
744
|
+
struct io_uring_sqe *sqe;
|
745
|
+
struct io_uring_cqe *cqe;
|
746
|
+
struct sockaddr_storage addr;
|
747
|
+
int sock_tx, sock_rx;
|
748
|
+
int ret;
|
749
|
+
|
750
|
+
ret = create_socketpair_ip(&addr, &sock_tx, &sock_rx, true, true, false, true);
|
751
|
+
if (ret) {
|
752
|
+
fprintf(stderr, "sock prep failed %d\n", ret);
|
753
|
+
return 1;
|
754
|
+
}
|
755
|
+
|
756
|
+
sqe = io_uring_get_sqe(ring);
|
757
|
+
io_uring_prep_send_zc(sqe, sock_tx, tx_buffer, 1, 0,
|
758
|
+
IORING_SEND_ZC_REPORT_USAGE);
|
759
|
+
ret = io_uring_submit(ring);
|
760
|
+
if (ret != 1) {
|
761
|
+
fprintf(stderr, "io_uring_submit failed %i\n", ret);
|
762
|
+
return 1;
|
763
|
+
}
|
764
|
+
ret = io_uring_wait_cqe(ring, &cqe);
|
765
|
+
if (ret) {
|
766
|
+
fprintf(stderr, "io_uring_wait_cqe failed %i\n", ret);
|
767
|
+
return 1;
|
768
|
+
}
|
769
|
+
if (cqe->res != 1 && cqe->res != -EINVAL) {
|
770
|
+
fprintf(stderr, "sendzc report failed %u\n", cqe->res);
|
771
|
+
return 1;
|
772
|
+
}
|
773
|
+
if (!(cqe->flags & IORING_CQE_F_MORE)) {
|
774
|
+
fprintf(stderr, "expected notification %i\n", cqe->res);
|
775
|
+
return 1;
|
776
|
+
}
|
777
|
+
io_uring_cqe_seen(ring, cqe);
|
778
|
+
|
779
|
+
ret = io_uring_wait_cqe(ring, &cqe);
|
780
|
+
if (ret) {
|
781
|
+
fprintf(stderr, "io_uring_wait_cqe failed %i\n", ret);
|
782
|
+
return 1;
|
783
|
+
}
|
784
|
+
if (cqe->flags & IORING_CQE_F_MORE) {
|
785
|
+
fprintf(stderr, "F_MORE after notification\n");
|
786
|
+
return 1;
|
787
|
+
}
|
788
|
+
io_uring_cqe_seen(ring, cqe);
|
789
|
+
|
790
|
+
close(sock_tx);
|
791
|
+
close(sock_rx);
|
792
|
+
return 0;
|
793
|
+
}
|
794
|
+
|
742
795
|
/* see also send_recv.c:test_invalid */
|
743
796
|
static int test_invalid_zc(int fds[2])
|
744
797
|
{
|
@@ -833,6 +886,12 @@ static int run_basic_tests(void)
|
|
833
886
|
return T_EXIT_FAIL;
|
834
887
|
}
|
835
888
|
|
889
|
+
ret = test_sendzc_report(&ring);
|
890
|
+
if (ret) {
|
891
|
+
fprintf(stderr, "test_sendzc_report() failed\n");
|
892
|
+
return T_EXIT_FAIL;
|
893
|
+
}
|
894
|
+
|
836
895
|
io_uring_queue_exit(&ring);
|
837
896
|
}
|
838
897
|
|
@@ -365,6 +365,43 @@ static int test(int use_sqthread, int regfiles, int socket_direct, int alloc)
|
|
365
365
|
return (intptr_t)retval;
|
366
366
|
}
|
367
367
|
|
368
|
+
static int test_bad_socket(void)
|
369
|
+
{
|
370
|
+
struct io_uring ring;
|
371
|
+
struct io_uring_cqe *cqe;
|
372
|
+
struct io_uring_sqe *sqe;
|
373
|
+
int ret;
|
374
|
+
|
375
|
+
ret = io_uring_queue_init(1, &ring, 0);
|
376
|
+
if (ret) {
|
377
|
+
fprintf(stderr, "queue init failed: %d\n", ret);
|
378
|
+
return 1;
|
379
|
+
}
|
380
|
+
|
381
|
+
sqe = io_uring_get_sqe(&ring);
|
382
|
+
io_uring_prep_socket(sqe, -1, SOCK_DGRAM, 0, 0);
|
383
|
+
ret = io_uring_submit(&ring);
|
384
|
+
if (ret != 1) {
|
385
|
+
fprintf(stderr, "socket submit: %d\n", ret);
|
386
|
+
goto err;
|
387
|
+
}
|
388
|
+
ret = io_uring_wait_cqe(&ring, &cqe);
|
389
|
+
if (ret) {
|
390
|
+
fprintf(stderr, "wait_cqe: %d\n", ret);
|
391
|
+
goto err;
|
392
|
+
}
|
393
|
+
if (cqe->res != -EAFNOSUPPORT) {
|
394
|
+
fprintf(stderr, "socket res: %d\n", cqe->res);
|
395
|
+
goto err;
|
396
|
+
}
|
397
|
+
io_uring_cqe_seen(&ring, cqe);
|
398
|
+
io_uring_queue_exit(&ring);
|
399
|
+
return 0;
|
400
|
+
err:
|
401
|
+
io_uring_queue_exit(&ring);
|
402
|
+
return 1;
|
403
|
+
}
|
404
|
+
|
368
405
|
int main(int argc, char *argv[])
|
369
406
|
{
|
370
407
|
int ret;
|
@@ -404,5 +441,11 @@ int main(int argc, char *argv[])
|
|
404
441
|
return ret;
|
405
442
|
}
|
406
443
|
|
444
|
+
ret = test_bad_socket();
|
445
|
+
if (ret) {
|
446
|
+
fprintf(stderr, "test bad socket failed\n");
|
447
|
+
return 1;
|
448
|
+
}
|
449
|
+
|
407
450
|
return 0;
|
408
451
|
}
|
@@ -191,7 +191,7 @@ static int do_splice(struct io_uring *ring,
|
|
191
191
|
IORING_OP_SPLICE);
|
192
192
|
}
|
193
193
|
|
194
|
-
static int do_tee(struct io_uring *ring, int fd_in, int fd_out,
|
194
|
+
static int do_tee(struct io_uring *ring, int fd_in, int fd_out,
|
195
195
|
unsigned int len)
|
196
196
|
{
|
197
197
|
return do_splice_op(ring, fd_in, 0, fd_out, 0, len, IORING_OP_TEE);
|
@@ -504,6 +504,8 @@ int main(int argc, char *argv[])
|
|
504
504
|
splice_flags = SPLICE_F_FD_IN_FIXED;
|
505
505
|
sqe_flags = IOSQE_FIXED_FILE;
|
506
506
|
ret = test_splice(&ring, &ctx);
|
507
|
+
free(ctx.buf_in);
|
508
|
+
free(ctx.buf_out);
|
507
509
|
if (ret) {
|
508
510
|
fprintf(stderr, "registered fds splice tests failed\n");
|
509
511
|
return ret;
|
@@ -22,8 +22,10 @@
|
|
22
22
|
#include <unistd.h>
|
23
23
|
|
24
24
|
#include "liburing.h"
|
25
|
+
#include "helpers.h"
|
25
26
|
#include "../src/syscall.h"
|
26
27
|
|
28
|
+
#ifndef CONFIG_USE_SANITIZER
|
27
29
|
static void sleep_ms(uint64_t ms)
|
28
30
|
{
|
29
31
|
usleep(ms * 1000);
|
@@ -194,3 +196,9 @@ int main(void)
|
|
194
196
|
loop();
|
195
197
|
return 0;
|
196
198
|
}
|
199
|
+
#else
|
200
|
+
int main(int argc, char *argv[])
|
201
|
+
{
|
202
|
+
return T_EXIT_SKIP;
|
203
|
+
}
|
204
|
+
#endif
|
@@ -10,31 +10,7 @@
|
|
10
10
|
#include <sys/time.h>
|
11
11
|
#include <poll.h>
|
12
12
|
#include "liburing.h"
|
13
|
-
|
14
|
-
static unsigned long long mtime_since(const struct timeval *s,
|
15
|
-
const struct timeval *e)
|
16
|
-
{
|
17
|
-
long long sec, usec;
|
18
|
-
|
19
|
-
sec = e->tv_sec - s->tv_sec;
|
20
|
-
usec = (e->tv_usec - s->tv_usec);
|
21
|
-
if (sec > 0 && usec < 0) {
|
22
|
-
sec--;
|
23
|
-
usec += 1000000;
|
24
|
-
}
|
25
|
-
|
26
|
-
sec *= 1000;
|
27
|
-
usec /= 1000;
|
28
|
-
return sec + usec;
|
29
|
-
}
|
30
|
-
|
31
|
-
static unsigned long long mtime_since_now(struct timeval *tv)
|
32
|
-
{
|
33
|
-
struct timeval end;
|
34
|
-
|
35
|
-
gettimeofday(&end, NULL);
|
36
|
-
return mtime_since(tv, &end);
|
37
|
-
}
|
13
|
+
#include "helpers.h"
|
38
14
|
|
39
15
|
int main(int argc, char *argv[])
|
40
16
|
{
|
@@ -9,41 +9,21 @@
|
|
9
9
|
#include <unistd.h>
|
10
10
|
#include <sys/time.h>
|
11
11
|
#include "liburing.h"
|
12
|
-
|
13
|
-
static unsigned long long mtime_since(const struct timeval *s,
|
14
|
-
const struct timeval *e)
|
15
|
-
{
|
16
|
-
long long sec, usec;
|
17
|
-
|
18
|
-
sec = e->tv_sec - s->tv_sec;
|
19
|
-
usec = (e->tv_usec - s->tv_usec);
|
20
|
-
if (sec > 0 && usec < 0) {
|
21
|
-
sec--;
|
22
|
-
usec += 1000000;
|
23
|
-
}
|
24
|
-
|
25
|
-
sec *= 1000;
|
26
|
-
usec /= 1000;
|
27
|
-
return sec + usec;
|
28
|
-
}
|
29
|
-
|
30
|
-
static unsigned long long mtime_since_now(struct timeval *tv)
|
31
|
-
{
|
32
|
-
struct timeval end;
|
33
|
-
|
34
|
-
gettimeofday(&end, NULL);
|
35
|
-
return mtime_since(tv, &end);
|
36
|
-
}
|
12
|
+
#include "helpers.h"
|
37
13
|
|
38
14
|
int main(int argc, char *argv[])
|
39
15
|
{
|
40
16
|
struct io_uring_params p = {};
|
17
|
+
struct io_uring_sqe *sqe;
|
18
|
+
struct io_uring_cqe *cqe;
|
41
19
|
struct timeval tv;
|
42
20
|
struct io_uring ring;
|
21
|
+
unsigned long elapsed;
|
22
|
+
bool seen_wakeup;
|
43
23
|
int ret;
|
44
24
|
|
45
25
|
if (argc > 1)
|
46
|
-
return
|
26
|
+
return T_EXIT_SKIP;
|
47
27
|
|
48
28
|
p.flags = IORING_SETUP_SQPOLL;
|
49
29
|
p.sq_thread_idle = 100;
|
@@ -52,18 +32,45 @@ int main(int argc, char *argv[])
|
|
52
32
|
if (ret) {
|
53
33
|
if (geteuid()) {
|
54
34
|
printf("%s: skipped, not root\n", argv[0]);
|
55
|
-
return
|
35
|
+
return T_EXIT_SKIP;
|
56
36
|
}
|
57
37
|
fprintf(stderr, "queue_init=%d\n", ret);
|
58
|
-
return
|
38
|
+
return T_EXIT_FAIL;
|
59
39
|
}
|
60
40
|
|
41
|
+
sqe = io_uring_get_sqe(&ring);
|
42
|
+
io_uring_prep_nop(sqe);
|
43
|
+
io_uring_submit(&ring);
|
44
|
+
|
45
|
+
ret = io_uring_wait_cqe(&ring, &cqe);
|
46
|
+
if (ret) {
|
47
|
+
fprintf(stderr, "wait_cqe: %d\n", ret);
|
48
|
+
return T_EXIT_FAIL;
|
49
|
+
}
|
50
|
+
io_uring_cqe_seen(&ring, cqe);
|
51
|
+
|
52
|
+
elapsed = 0;
|
53
|
+
seen_wakeup = false;
|
61
54
|
gettimeofday(&tv, NULL);
|
62
55
|
do {
|
63
|
-
usleep(
|
64
|
-
if ((*ring.sq.kflags) & IORING_SQ_NEED_WAKEUP)
|
65
|
-
|
66
|
-
|
56
|
+
usleep(100);
|
57
|
+
if (IO_URING_READ_ONCE(*ring.sq.kflags) & IORING_SQ_NEED_WAKEUP) {
|
58
|
+
seen_wakeup = true;
|
59
|
+
break;
|
60
|
+
}
|
61
|
+
elapsed = mtime_since_now(&tv);
|
62
|
+
} while (elapsed < 1000);
|
63
|
+
|
64
|
+
if (!seen_wakeup) {
|
65
|
+
fprintf(stderr, "SQPOLL didn't flag wakeup\n");
|
66
|
+
return T_EXIT_FAIL;
|
67
|
+
}
|
68
|
+
|
69
|
+
/* should be around 100 msec */
|
70
|
+
if (elapsed < 90 || elapsed > 110) {
|
71
|
+
fprintf(stderr, "SQPOLL wakeup timing off %lu\n", elapsed);
|
72
|
+
return T_EXIT_FAIL;
|
73
|
+
}
|
67
74
|
|
68
|
-
return
|
75
|
+
return T_EXIT_PASS;
|
69
76
|
}
|
@@ -0,0 +1,136 @@
|
|
1
|
+
/* SPDX-License-Identifier: MIT */
|
2
|
+
/*
|
3
|
+
* Description: test that the app can always get a new sqe after having
|
4
|
+
* called io_uring_sqring_wait().
|
5
|
+
*
|
6
|
+
*/
|
7
|
+
#include <stdio.h>
|
8
|
+
#include <stdlib.h>
|
9
|
+
#include <unistd.h>
|
10
|
+
|
11
|
+
#include "liburing.h"
|
12
|
+
#include "helpers.h"
|
13
|
+
|
14
|
+
#define NR_IOS 10000
|
15
|
+
#define INFLIGHT 256
|
16
|
+
#define FILE_SIZE (256 * 1024 * 1024)
|
17
|
+
|
18
|
+
static int inflight;
|
19
|
+
|
20
|
+
static int reap(struct io_uring *ring)
|
21
|
+
{
|
22
|
+
struct io_uring_cqe *cqe;
|
23
|
+
int ret;
|
24
|
+
|
25
|
+
while (inflight >= INFLIGHT / 2) {
|
26
|
+
ret = io_uring_wait_cqe(ring, &cqe);
|
27
|
+
if (ret < 0) {
|
28
|
+
fprintf(stderr, "wait=%d\n", ret);
|
29
|
+
return 1;
|
30
|
+
}
|
31
|
+
if (cqe->res < 0) {
|
32
|
+
printf("cqe res %d\n", cqe->res);
|
33
|
+
return 1;
|
34
|
+
}
|
35
|
+
io_uring_cqe_seen(ring, cqe);
|
36
|
+
inflight--;
|
37
|
+
}
|
38
|
+
|
39
|
+
return 0;
|
40
|
+
}
|
41
|
+
|
42
|
+
int main(int argc, char *argv[])
|
43
|
+
{
|
44
|
+
struct io_uring_sqe *sqe;
|
45
|
+
struct io_uring ring;
|
46
|
+
int fd = -1, i, iov_off, ret, fret;
|
47
|
+
struct iovec iovs[INFLIGHT];
|
48
|
+
const char *fname;
|
49
|
+
char buf[256];
|
50
|
+
loff_t off;
|
51
|
+
|
52
|
+
if (argc > 1) {
|
53
|
+
fname = argv[1];
|
54
|
+
} else {
|
55
|
+
srand((unsigned)time(NULL));
|
56
|
+
snprintf(buf, sizeof(buf), ".sqwait-%u-%u", (unsigned)rand(),
|
57
|
+
(unsigned)getpid());
|
58
|
+
fname = buf;
|
59
|
+
t_create_file(fname, FILE_SIZE);
|
60
|
+
}
|
61
|
+
|
62
|
+
fret = T_EXIT_SKIP;
|
63
|
+
ret = io_uring_queue_init(8, &ring, IORING_SETUP_SQPOLL);
|
64
|
+
if (ret < 0) {
|
65
|
+
if (errno == EINVAL || errno == EPERM)
|
66
|
+
goto err;
|
67
|
+
fprintf(stderr, "queue init %d\n", ret);
|
68
|
+
fret = T_EXIT_FAIL;
|
69
|
+
goto err;
|
70
|
+
}
|
71
|
+
|
72
|
+
fd = open(fname, O_RDONLY | O_DIRECT);
|
73
|
+
if (fd < 0) {
|
74
|
+
if (errno == EACCES || errno == EPERM || errno == EINVAL)
|
75
|
+
return T_EXIT_SKIP;
|
76
|
+
perror("open");
|
77
|
+
fret = T_EXIT_FAIL;
|
78
|
+
goto err;
|
79
|
+
}
|
80
|
+
|
81
|
+
for (i = 0; i < INFLIGHT; i++) {
|
82
|
+
if (posix_memalign(&iovs[i].iov_base, 4096, 4096))
|
83
|
+
goto err;
|
84
|
+
iovs[i].iov_len = 4096;
|
85
|
+
}
|
86
|
+
|
87
|
+
iov_off = off = 0;
|
88
|
+
for (i = 0; i < NR_IOS; i++) {
|
89
|
+
struct iovec *iov = &iovs[iov_off];
|
90
|
+
|
91
|
+
sqe = io_uring_get_sqe(&ring);
|
92
|
+
if (!sqe) {
|
93
|
+
ret = io_uring_sqring_wait(&ring);
|
94
|
+
if (ret < 0) {
|
95
|
+
if (ret == -EINVAL)
|
96
|
+
return T_EXIT_SKIP;
|
97
|
+
fprintf(stderr, "sqwait=%d\n", ret);
|
98
|
+
fret = T_EXIT_FAIL;
|
99
|
+
goto err;
|
100
|
+
}
|
101
|
+
sqe = io_uring_get_sqe(&ring);
|
102
|
+
if (!sqe) {
|
103
|
+
fprintf(stderr, "No sqe post wait\n");
|
104
|
+
fret = T_EXIT_FAIL;
|
105
|
+
goto err;
|
106
|
+
}
|
107
|
+
}
|
108
|
+
io_uring_prep_read(sqe, fd, iov->iov_base, iov->iov_len, 0);
|
109
|
+
io_uring_submit(&ring);
|
110
|
+
inflight++;
|
111
|
+
|
112
|
+
iov_off++;
|
113
|
+
if (iov_off == INFLIGHT)
|
114
|
+
iov_off = 0;
|
115
|
+
off += 8192;
|
116
|
+
if (off > FILE_SIZE - 8192)
|
117
|
+
off = 0;
|
118
|
+
if (reap(&ring)) {
|
119
|
+
fret = T_EXIT_FAIL;
|
120
|
+
goto err;
|
121
|
+
}
|
122
|
+
}
|
123
|
+
|
124
|
+
if (fd != -1)
|
125
|
+
close(fd);
|
126
|
+
if (fname != argv[1])
|
127
|
+
unlink(fname);
|
128
|
+
io_uring_queue_exit(&ring);
|
129
|
+
return T_EXIT_PASS;
|
130
|
+
err:
|
131
|
+
if (fd != -1)
|
132
|
+
close(fd);
|
133
|
+
if (fname != argv[1])
|
134
|
+
unlink(fname);
|
135
|
+
return fret;
|
136
|
+
}
|
@@ -36,6 +36,81 @@ static int statx_syscall_supported(void)
|
|
36
36
|
return errno == ENOSYS ? 0 : -1;
|
37
37
|
}
|
38
38
|
|
39
|
+
static int test_statx_invalid_buf(struct io_uring *ring, const char *path)
|
40
|
+
{
|
41
|
+
struct io_uring_cqe *cqe;
|
42
|
+
struct io_uring_sqe *sqe;
|
43
|
+
struct statx *x = (struct statx *) (uintptr_t) 0x1234;
|
44
|
+
int ret;
|
45
|
+
|
46
|
+
sqe = io_uring_get_sqe(ring);
|
47
|
+
if (!sqe) {
|
48
|
+
fprintf(stderr, "get sqe failed\n");
|
49
|
+
goto err;
|
50
|
+
}
|
51
|
+
io_uring_prep_statx(sqe, -1, path, 0, STATX_ALL, x);
|
52
|
+
|
53
|
+
ret = io_uring_submit(ring);
|
54
|
+
if (ret <= 0) {
|
55
|
+
fprintf(stderr, "sqe submit failed: %d\n", ret);
|
56
|
+
goto err;
|
57
|
+
}
|
58
|
+
|
59
|
+
ret = io_uring_wait_cqe(ring, &cqe);
|
60
|
+
if (ret < 0) {
|
61
|
+
fprintf(stderr, "wait completion %d\n", ret);
|
62
|
+
goto err;
|
63
|
+
}
|
64
|
+
ret = cqe->res;
|
65
|
+
io_uring_cqe_seen(ring, cqe);
|
66
|
+
if (ret != -EFAULT) {
|
67
|
+
fprintf(stderr, "Invalid address didn't fail\n");
|
68
|
+
goto err;
|
69
|
+
}
|
70
|
+
|
71
|
+
return 0;
|
72
|
+
err:
|
73
|
+
return -1;
|
74
|
+
}
|
75
|
+
|
76
|
+
static int test_statx_invalid_path(struct io_uring *ring)
|
77
|
+
{
|
78
|
+
const char *path = (const char *) (uintptr_t) 0x1234;
|
79
|
+
struct io_uring_cqe *cqe;
|
80
|
+
struct io_uring_sqe *sqe;
|
81
|
+
struct statx x1 = { };
|
82
|
+
int ret;
|
83
|
+
|
84
|
+
sqe = io_uring_get_sqe(ring);
|
85
|
+
if (!sqe) {
|
86
|
+
fprintf(stderr, "get sqe failed\n");
|
87
|
+
goto err;
|
88
|
+
}
|
89
|
+
io_uring_prep_statx(sqe, -1, path, 0, STATX_ALL, &x1);
|
90
|
+
|
91
|
+
ret = io_uring_submit(ring);
|
92
|
+
if (ret <= 0) {
|
93
|
+
fprintf(stderr, "sqe submit failed: %d\n", ret);
|
94
|
+
goto err;
|
95
|
+
}
|
96
|
+
|
97
|
+
ret = io_uring_wait_cqe(ring, &cqe);
|
98
|
+
if (ret < 0) {
|
99
|
+
fprintf(stderr, "wait completion %d\n", ret);
|
100
|
+
goto err;
|
101
|
+
}
|
102
|
+
ret = cqe->res;
|
103
|
+
io_uring_cqe_seen(ring, cqe);
|
104
|
+
if (ret != -EFAULT) {
|
105
|
+
fprintf(stderr, "Invalid address didn't fail\n");
|
106
|
+
goto err;
|
107
|
+
}
|
108
|
+
|
109
|
+
return 0;
|
110
|
+
err:
|
111
|
+
return -1;
|
112
|
+
}
|
113
|
+
|
39
114
|
static int test_statx(struct io_uring *ring, const char *path)
|
40
115
|
{
|
41
116
|
struct io_uring_cqe *cqe;
|
@@ -86,6 +161,8 @@ static int test_statx_fd(struct io_uring *ring, const char *path)
|
|
86
161
|
|
87
162
|
fd = open(path, O_RDONLY);
|
88
163
|
if (fd < 0) {
|
164
|
+
if (errno == EPERM || errno == EACCES)
|
165
|
+
return 0;
|
89
166
|
perror("open");
|
90
167
|
return 1;
|
91
168
|
}
|
@@ -156,6 +233,18 @@ int main(int argc, char *argv[])
|
|
156
233
|
goto err;
|
157
234
|
}
|
158
235
|
|
236
|
+
ret = test_statx_invalid_path(&ring);
|
237
|
+
if (ret) {
|
238
|
+
fprintf(stderr, "test_statx_invalid_path failed: %d\n", ret);
|
239
|
+
goto err;
|
240
|
+
}
|
241
|
+
|
242
|
+
ret = test_statx_invalid_buf(&ring, fname);
|
243
|
+
if (ret) {
|
244
|
+
fprintf(stderr, "test_statx_invalid_buf failed: %d\n", ret);
|
245
|
+
goto err;
|
246
|
+
}
|
247
|
+
|
159
248
|
ret = test_statx_fd(&ring, fname);
|
160
249
|
if (ret) {
|
161
250
|
fprintf(stderr, "test_statx_fd failed: %d\n", ret);
|
@@ -89,6 +89,7 @@ static int test_pipe_io_fixed(struct io_uring *ring)
|
|
89
89
|
io_uring_cqe_seen(ring, cqe);
|
90
90
|
}
|
91
91
|
io_uring_unregister_buffers(ring);
|
92
|
+
free(vecs[0].iov_base);
|
92
93
|
return 0;
|
93
94
|
err:
|
94
95
|
return 1;
|
@@ -143,6 +144,7 @@ static int test_stdout_io_fixed(struct io_uring *ring)
|
|
143
144
|
}
|
144
145
|
io_uring_cqe_seen(ring, cqe);
|
145
146
|
io_uring_unregister_buffers(ring);
|
147
|
+
free(vecs.iov_base);
|
146
148
|
return 0;
|
147
149
|
err:
|
148
150
|
return 1;
|
@@ -13,33 +13,9 @@
|
|
13
13
|
#include <sys/time.h>
|
14
14
|
|
15
15
|
#include "liburing.h"
|
16
|
+
#include "helpers.h"
|
16
17
|
#include "test.h"
|
17
18
|
|
18
|
-
static unsigned long long mtime_since(const struct timeval *s,
|
19
|
-
const struct timeval *e)
|
20
|
-
{
|
21
|
-
long long sec, usec;
|
22
|
-
|
23
|
-
sec = e->tv_sec - s->tv_sec;
|
24
|
-
usec = (e->tv_usec - s->tv_usec);
|
25
|
-
if (sec > 0 && usec < 0) {
|
26
|
-
sec--;
|
27
|
-
usec += 1000000;
|
28
|
-
}
|
29
|
-
|
30
|
-
sec *= 1000;
|
31
|
-
usec /= 1000;
|
32
|
-
return sec + usec;
|
33
|
-
}
|
34
|
-
|
35
|
-
static unsigned long long mtime_since_now(struct timeval *tv)
|
36
|
-
{
|
37
|
-
struct timeval end;
|
38
|
-
|
39
|
-
gettimeofday(&end, NULL);
|
40
|
-
return mtime_since(tv, &end);
|
41
|
-
}
|
42
|
-
|
43
19
|
static int test(struct io_uring *ring)
|
44
20
|
{
|
45
21
|
struct io_uring_cqe *cqe;
|