uringmachine 0.2 → 0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +15 -0
- data/README.md +85 -0
- data/TODO.md +5 -0
- data/examples/echo_server.rb +18 -40
- data/examples/inout.rb +19 -0
- data/examples/nc.rb +36 -0
- data/ext/um/extconf.rb +6 -15
- data/ext/um/um.c +340 -53
- data/ext/um/um.h +33 -11
- data/ext/um/um_class.c +101 -119
- data/ext/um/um_const.c +184 -0
- data/ext/um/um_op.c +39 -18
- data/ext/um/um_utils.c +48 -3
- data/lib/uringmachine/version.rb +1 -1
- data/lib/uringmachine.rb +12 -0
- data/test/helper.rb +13 -12
- data/test/test_um.rb +301 -3
- data/vendor/liburing/.github/workflows/build.yml +29 -1
- data/vendor/liburing/.gitignore +1 -0
- data/vendor/liburing/CHANGELOG +15 -0
- data/vendor/liburing/CONTRIBUTING.md +165 -0
- data/vendor/liburing/configure +32 -0
- data/vendor/liburing/examples/Makefile +8 -1
- data/vendor/liburing/examples/kdigest.c +405 -0
- data/vendor/liburing/examples/proxy.c +75 -8
- data/vendor/liburing/liburing.pc.in +1 -1
- data/vendor/liburing/src/Makefile +16 -2
- data/vendor/liburing/src/include/liburing/io_uring.h +31 -0
- data/vendor/liburing/src/include/liburing/sanitize.h +39 -0
- data/vendor/liburing/src/include/liburing.h +31 -4
- data/vendor/liburing/src/liburing-ffi.map +5 -0
- data/vendor/liburing/src/liburing.map +1 -0
- data/vendor/liburing/src/queue.c +3 -0
- data/vendor/liburing/src/register.c +36 -0
- data/vendor/liburing/src/sanitize.c +176 -0
- data/vendor/liburing/src/setup.c +1 -1
- 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 +31 -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/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/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 +2 -0
- data/vendor/liburing/test/io_uring_register.c +25 -6
- 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 +15 -2
- data/vendor/liburing/test/no-mmap-inval.c +2 -0
- 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 +156 -153
- data/vendor/liburing/test/read-mshot.c +276 -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 +92 -29
- data/vendor/liburing/test/reg-fd-only.c +14 -4
- data/vendor/liburing/test/regbuf-clone.c +187 -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/ringbuf-read.c +5 -0
- data/vendor/liburing/test/ringbuf-status.c +5 -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 +1 -25
- 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 +48 -21
- data/vendor/liburing/test/thread-exit.c +5 -0
- data/vendor/liburing/test/timeout-new.c +1 -26
- data/vendor/liburing/test/timeout.c +12 -26
- 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 +17 -4
- data/examples/event_loop.rb +0 -69
- data/examples/fibers.rb +0 -105
@@ -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;
|
@@ -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
|
@@ -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;
|