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
@@ -19,6 +19,7 @@
|
|
19
19
|
|
20
20
|
static int nr_msgs;
|
21
21
|
static int use_tcp;
|
22
|
+
static int classic_buffers;
|
22
23
|
|
23
24
|
#define RECV_BIDS 8192
|
24
25
|
#define RECV_BID_MASK (RECV_BIDS - 1)
|
@@ -113,6 +114,9 @@ static int recv_prep(struct io_uring *ring, struct recv_data *rd, int *sock)
|
|
113
114
|
|
114
115
|
pthread_barrier_wait(&rd->connect);
|
115
116
|
|
117
|
+
if (rd->abort)
|
118
|
+
goto err;
|
119
|
+
|
116
120
|
socklen = sizeof(saddr);
|
117
121
|
use_fd = accept(sockfd, (struct sockaddr *)&saddr, &socklen);
|
118
122
|
if (use_fd < 0) {
|
@@ -245,13 +249,36 @@ err:
|
|
245
249
|
return 1;
|
246
250
|
}
|
247
251
|
|
252
|
+
static int provide_classic_buffers(struct io_uring *ring, void *buf, int nbufs, int bgid)
|
253
|
+
{
|
254
|
+
struct io_uring_sqe *sqe;
|
255
|
+
struct io_uring_cqe *cqe;
|
256
|
+
int ret;
|
257
|
+
|
258
|
+
sqe = io_uring_get_sqe(ring);
|
259
|
+
io_uring_prep_provide_buffers(sqe, buf, MSG_SIZE, nbufs, bgid, 0);
|
260
|
+
io_uring_submit(ring);
|
261
|
+
|
262
|
+
ret = io_uring_wait_cqe(ring, &cqe);
|
263
|
+
if (ret) {
|
264
|
+
fprintf(stderr, "provide buffer wait: %d\n", ret);
|
265
|
+
return 1;
|
266
|
+
}
|
267
|
+
if (cqe->res) {
|
268
|
+
fprintf(stderr, "provide buffers fail: %d\n", cqe->res);
|
269
|
+
return 1;
|
270
|
+
}
|
271
|
+
io_uring_cqe_seen(ring, cqe);
|
272
|
+
return 0;
|
273
|
+
}
|
274
|
+
|
248
275
|
static void *recv_fn(void *data)
|
249
276
|
{
|
250
277
|
struct recv_data *rd = data;
|
251
278
|
struct io_uring_params p = { };
|
252
279
|
struct io_uring ring;
|
253
280
|
struct io_uring_buf_ring *br;
|
254
|
-
void *buf, *ptr;
|
281
|
+
void *buf = NULL, *ptr;
|
255
282
|
int ret, sock, i;
|
256
283
|
|
257
284
|
p.cq_entries = 4096;
|
@@ -264,22 +291,31 @@ static void *recv_fn(void *data)
|
|
264
291
|
goto err;
|
265
292
|
}
|
266
293
|
|
267
|
-
if (posix_memalign(&buf,
|
294
|
+
if (posix_memalign(&buf, sysconf(_SC_PAGESIZE), MSG_SIZE * RECV_BIDS))
|
268
295
|
goto err;
|
269
296
|
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
297
|
+
if (!classic_buffers) {
|
298
|
+
br = io_uring_setup_buf_ring(&ring, RECV_BIDS, RECV_BGID, 0, &ret);
|
299
|
+
if (!br) {
|
300
|
+
if (ret != -EINVAL)
|
301
|
+
fprintf(stderr, "failed setting up recv ring %d\n", ret);
|
302
|
+
goto err;
|
303
|
+
}
|
275
304
|
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
305
|
+
ptr = buf;
|
306
|
+
for (i = 0; i < RECV_BIDS; i++) {
|
307
|
+
io_uring_buf_ring_add(br, ptr, MSG_SIZE, i, RECV_BID_MASK, i);
|
308
|
+
ptr += MSG_SIZE;
|
309
|
+
}
|
310
|
+
io_uring_buf_ring_advance(br, RECV_BIDS);
|
311
|
+
rd->recv_buf = buf;
|
312
|
+
} else {
|
313
|
+
ret = provide_classic_buffers(&ring, buf, RECV_BIDS, RECV_BGID);
|
314
|
+
if (ret) {
|
315
|
+
fprintf(stderr, "failed providing classic buffers\n");
|
316
|
+
goto err;
|
317
|
+
}
|
280
318
|
}
|
281
|
-
io_uring_buf_ring_advance(br, RECV_BIDS);
|
282
|
-
rd->recv_buf = buf;
|
283
319
|
|
284
320
|
ret = recv_prep(&ring, rd, &sock);
|
285
321
|
if (ret) {
|
@@ -293,6 +329,7 @@ static void *recv_fn(void *data)
|
|
293
329
|
close(rd->accept_fd);
|
294
330
|
io_uring_queue_exit(&ring);
|
295
331
|
err:
|
332
|
+
free(buf);
|
296
333
|
return (void *)(intptr_t)ret;
|
297
334
|
}
|
298
335
|
|
@@ -402,7 +439,7 @@ static int do_send(struct recv_data *rd)
|
|
402
439
|
struct io_uring_buf_ring *br;
|
403
440
|
int sockfd, ret, len, i;
|
404
441
|
socklen_t optlen;
|
405
|
-
void *buf, *ptr;
|
442
|
+
void *buf = NULL, *ptr;
|
406
443
|
|
407
444
|
ret = io_uring_queue_init_params(16, &ring, &p);
|
408
445
|
if (ret) {
|
@@ -410,29 +447,39 @@ static int do_send(struct recv_data *rd)
|
|
410
447
|
return 1;
|
411
448
|
}
|
412
449
|
if (!(p.features & IORING_FEAT_RECVSEND_BUNDLE)) {
|
450
|
+
rd->abort = 1;
|
413
451
|
no_send_mshot = 1;
|
452
|
+
pthread_barrier_wait(&rd->connect);
|
414
453
|
return 0;
|
415
454
|
}
|
416
455
|
|
417
|
-
if (posix_memalign(&buf,
|
456
|
+
if (posix_memalign(&buf, sysconf(_SC_PAGESIZE), MSG_SIZE * nr_msgs))
|
418
457
|
return 1;
|
419
458
|
|
420
|
-
|
421
|
-
|
422
|
-
if (
|
423
|
-
|
424
|
-
|
459
|
+
if (!classic_buffers) {
|
460
|
+
br = io_uring_setup_buf_ring(&ring, nr_msgs, SEND_BGID, 0, &ret);
|
461
|
+
if (!br) {
|
462
|
+
if (ret == -EINVAL) {
|
463
|
+
fprintf(stderr, "einval on br setup\n");
|
464
|
+
return 0;
|
465
|
+
}
|
466
|
+
fprintf(stderr, "failed setting up send ring %d\n", ret);
|
467
|
+
return 1;
|
425
468
|
}
|
426
|
-
fprintf(stderr, "failed setting up send ring %d\n", ret);
|
427
|
-
return 1;
|
428
|
-
}
|
429
469
|
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
470
|
+
ptr = buf;
|
471
|
+
for (i = 0; i < nr_msgs; i++) {
|
472
|
+
io_uring_buf_ring_add(br, ptr, MSG_SIZE, i, nr_msgs - 1, i);
|
473
|
+
ptr += MSG_SIZE;
|
474
|
+
}
|
475
|
+
io_uring_buf_ring_advance(br, nr_msgs);
|
476
|
+
} else {
|
477
|
+
ret = provide_classic_buffers(&ring, buf, nr_msgs, SEND_BGID);
|
478
|
+
if (ret) {
|
479
|
+
fprintf(stderr, "failed providing classic buffers\n");
|
480
|
+
return ret;
|
481
|
+
}
|
434
482
|
}
|
435
|
-
io_uring_buf_ring_advance(br, nr_msgs);
|
436
483
|
|
437
484
|
memset(&saddr, 0, sizeof(saddr));
|
438
485
|
saddr.sin_family = AF_INET;
|
@@ -509,6 +556,7 @@ static int do_send(struct recv_data *rd)
|
|
509
556
|
|
510
557
|
close(sockfd);
|
511
558
|
io_uring_queue_exit(&ring);
|
559
|
+
free(buf);
|
512
560
|
return 0;
|
513
561
|
|
514
562
|
err:
|
@@ -516,6 +564,7 @@ err:
|
|
516
564
|
err2:
|
517
565
|
io_uring_queue_exit(&ring);
|
518
566
|
pthread_barrier_wait(&rd->finish);
|
567
|
+
free(buf);
|
519
568
|
return 1;
|
520
569
|
}
|
521
570
|
|
@@ -550,8 +599,12 @@ static int test(int backlog, unsigned int max_sends, int *to_eagain,
|
|
550
599
|
}
|
551
600
|
|
552
601
|
ret = do_send(&rd);
|
553
|
-
if (no_send_mshot)
|
602
|
+
if (no_send_mshot) {
|
603
|
+
fprintf(stderr, "no_send_mshot, aborting (ignore other errors)\n");
|
604
|
+
rd.abort = 1;
|
605
|
+
pthread_join(recv_thread, &retval);
|
554
606
|
return 0;
|
607
|
+
}
|
555
608
|
|
556
609
|
if (ret)
|
557
610
|
return ret;
|
@@ -656,7 +709,7 @@ static int test_tcp(void)
|
|
656
709
|
use_tcp = 1;
|
657
710
|
ret = run_tests(false);
|
658
711
|
if (ret == T_EXIT_FAIL)
|
659
|
-
fprintf(stderr, "TCP test case failed\n");
|
712
|
+
fprintf(stderr, "TCP test case (classic=%d) failed\n", classic_buffers);
|
660
713
|
return ret;
|
661
714
|
}
|
662
715
|
|
@@ -668,7 +721,7 @@ static int test_udp(void)
|
|
668
721
|
use_port++;
|
669
722
|
ret = run_tests(true);
|
670
723
|
if (ret == T_EXIT_FAIL)
|
671
|
-
fprintf(stderr, "UDP test case failed\n");
|
724
|
+
fprintf(stderr, "UDP test case (classic=%d) failed\n", classic_buffers);
|
672
725
|
return ret;
|
673
726
|
}
|
674
727
|
|
@@ -679,6 +732,16 @@ int main(int argc, char *argv[])
|
|
679
732
|
if (argc > 1)
|
680
733
|
return T_EXIT_SKIP;
|
681
734
|
|
735
|
+
ret = test_tcp();
|
736
|
+
if (ret != T_EXIT_PASS)
|
737
|
+
return ret;
|
738
|
+
|
739
|
+
ret = test_udp();
|
740
|
+
if (ret != T_EXIT_PASS)
|
741
|
+
return ret;
|
742
|
+
|
743
|
+
classic_buffers = 1;
|
744
|
+
|
682
745
|
ret = test_tcp();
|
683
746
|
if (ret != T_EXIT_PASS)
|
684
747
|
return ret;
|
@@ -49,15 +49,16 @@ static int test_nops(struct io_uring *ring, int sq_size, int nr_nops)
|
|
49
49
|
return T_EXIT_PASS;
|
50
50
|
}
|
51
51
|
|
52
|
-
static int test(int nentries)
|
52
|
+
static int test(int nentries, int ring_flags)
|
53
53
|
{
|
54
54
|
struct io_uring ring;
|
55
55
|
unsigned values[2];
|
56
56
|
int ret;
|
57
57
|
|
58
58
|
ret = io_uring_queue_init(nentries, &ring,
|
59
|
-
IORING_SETUP_REGISTERED_FD_ONLY | IORING_SETUP_NO_MMAP
|
60
|
-
|
59
|
+
IORING_SETUP_REGISTERED_FD_ONLY | IORING_SETUP_NO_MMAP |
|
60
|
+
ring_flags);
|
61
|
+
if (ret == -EINVAL || ret == -ENOENT) {
|
61
62
|
no_mmap = 1;
|
62
63
|
return T_EXIT_SKIP;
|
63
64
|
} else if (ret == -ENOMEM) {
|
@@ -110,7 +111,16 @@ int main(int argc, char *argv[])
|
|
110
111
|
return T_EXIT_SKIP;
|
111
112
|
|
112
113
|
/* test single normal page */
|
113
|
-
ret = test(NORMAL_PAGE_ENTRIES);
|
114
|
+
ret = test(NORMAL_PAGE_ENTRIES, 0);
|
115
|
+
if (ret == T_EXIT_SKIP || no_mmap) {
|
116
|
+
return T_EXIT_SKIP;
|
117
|
+
} else if (ret != T_EXIT_PASS) {
|
118
|
+
fprintf(stderr, "test 8 failed\n");
|
119
|
+
return T_EXIT_FAIL;
|
120
|
+
}
|
121
|
+
|
122
|
+
/* test single normal page */
|
123
|
+
ret = test(NORMAL_PAGE_ENTRIES, IORING_SETUP_SQPOLL);
|
114
124
|
if (ret == T_EXIT_SKIP || no_mmap) {
|
115
125
|
return T_EXIT_SKIP;
|
116
126
|
} else if (ret != T_EXIT_PASS) {
|
@@ -119,7 +129,7 @@ int main(int argc, char *argv[])
|
|
119
129
|
}
|
120
130
|
|
121
131
|
/* test with entries requiring a huge page */
|
122
|
-
ret = test(HUGE_PAGE_ENTRIES);
|
132
|
+
ret = test(HUGE_PAGE_ENTRIES, 0);
|
123
133
|
if (ret == T_EXIT_SKIP) {
|
124
134
|
return T_EXIT_SKIP;
|
125
135
|
} else if (ret != T_EXIT_PASS) {
|
@@ -0,0 +1,251 @@
|
|
1
|
+
/* SPDX-License-Identifier: MIT */
|
2
|
+
/*
|
3
|
+
* Description: Test that registered waits work
|
4
|
+
*/
|
5
|
+
#include <errno.h>
|
6
|
+
#include <stdio.h>
|
7
|
+
#include <unistd.h>
|
8
|
+
#include <stdlib.h>
|
9
|
+
#include <string.h>
|
10
|
+
#include <fcntl.h>
|
11
|
+
#include <sys/time.h>
|
12
|
+
|
13
|
+
#include "liburing.h"
|
14
|
+
#include "helpers.h"
|
15
|
+
#include "test.h"
|
16
|
+
|
17
|
+
static struct io_uring_reg_wait *reg;
|
18
|
+
|
19
|
+
static int test_invalid_reg2(void)
|
20
|
+
{
|
21
|
+
struct io_uring ring;
|
22
|
+
void *buf, *ptr;
|
23
|
+
int ret;
|
24
|
+
|
25
|
+
io_uring_queue_init(1, &ring, 0);
|
26
|
+
|
27
|
+
if (posix_memalign(&buf, 4096, 4096))
|
28
|
+
return T_EXIT_FAIL;
|
29
|
+
memset(buf, 0, 4096);
|
30
|
+
ptr = buf + 4096 - 32;
|
31
|
+
|
32
|
+
ret = io_uring_register_wait_reg(&ring, ptr, 1);
|
33
|
+
if (ret != -EINVAL) {
|
34
|
+
fprintf(stderr, "register cqwait: %d\n", ret);
|
35
|
+
return T_EXIT_FAIL;
|
36
|
+
}
|
37
|
+
|
38
|
+
ptr = buf + (sizeof(struct io_uring_reg_wait) / 2);
|
39
|
+
ret = io_uring_register_wait_reg(&ring, ptr, 1);
|
40
|
+
if (ret != -EINVAL) {
|
41
|
+
fprintf(stderr, "register cqwait: %d\n", ret);
|
42
|
+
return T_EXIT_FAIL;
|
43
|
+
}
|
44
|
+
|
45
|
+
free(buf);
|
46
|
+
buf = (void *) 0x1000;
|
47
|
+
ret = io_uring_register_wait_reg(&ring, buf, 1);
|
48
|
+
if (ret != -EFAULT) {
|
49
|
+
fprintf(stderr, "register cqwait: %d\n", ret);
|
50
|
+
return T_EXIT_FAIL;
|
51
|
+
}
|
52
|
+
|
53
|
+
buf = (void *) 0x1240;
|
54
|
+
ret = io_uring_register_wait_reg(&ring, buf, 1);
|
55
|
+
if (ret != -EFAULT) {
|
56
|
+
fprintf(stderr, "register cqwait: %d\n", ret);
|
57
|
+
return T_EXIT_FAIL;
|
58
|
+
}
|
59
|
+
|
60
|
+
buf = (void *) 0x1241;
|
61
|
+
ret = io_uring_register_wait_reg(&ring, buf, 1);
|
62
|
+
if (ret != -EINVAL) {
|
63
|
+
fprintf(stderr, "register cqwait: %d\n", ret);
|
64
|
+
return T_EXIT_FAIL;
|
65
|
+
}
|
66
|
+
|
67
|
+
io_uring_queue_exit(&ring);
|
68
|
+
return T_EXIT_PASS;
|
69
|
+
}
|
70
|
+
|
71
|
+
static int test_invalid_reg(void)
|
72
|
+
{
|
73
|
+
struct io_uring_reg_wait *ireg;
|
74
|
+
struct io_uring_cqe *cqe;
|
75
|
+
struct io_uring ring;
|
76
|
+
struct timeval tv;
|
77
|
+
void *buf, *ptr;
|
78
|
+
int ret;
|
79
|
+
|
80
|
+
io_uring_queue_init(1, &ring, 0);
|
81
|
+
|
82
|
+
if (posix_memalign(&buf, 4096, 4096))
|
83
|
+
return T_EXIT_FAIL;
|
84
|
+
memset(buf, 0, 4096);
|
85
|
+
ptr = buf + 512;
|
86
|
+
ireg = ptr;
|
87
|
+
|
88
|
+
ret = io_uring_register_wait_reg(&ring, ireg, 56);
|
89
|
+
if (ret) {
|
90
|
+
fprintf(stderr, "register cqwait: %d\n", ret);
|
91
|
+
return T_EXIT_FAIL;
|
92
|
+
}
|
93
|
+
|
94
|
+
ireg = ptr;
|
95
|
+
memset(ireg, 0, sizeof(*ireg));
|
96
|
+
ireg->ts.tv_sec = 1;
|
97
|
+
ireg->ts.tv_nsec = 0;
|
98
|
+
ireg->flags = IORING_REG_WAIT_TS;
|
99
|
+
|
100
|
+
gettimeofday(&tv, NULL);
|
101
|
+
ret = io_uring_submit_and_wait_reg(&ring, &cqe, 1, 0);
|
102
|
+
if (ret != -ETIME) {
|
103
|
+
fprintf(stderr, "wait_reg failed: %d\n", ret);
|
104
|
+
return T_EXIT_FAIL;
|
105
|
+
}
|
106
|
+
|
107
|
+
ret = mtime_since_now(&tv);
|
108
|
+
/* allow some slack, should be around 1.1s */
|
109
|
+
if (ret < 1000 || ret > 1200) {
|
110
|
+
fprintf(stderr, "wait too long or short: %d\n", ret);
|
111
|
+
goto err;
|
112
|
+
}
|
113
|
+
|
114
|
+
memset(ireg, 0, sizeof(*ireg));
|
115
|
+
ireg->ts.tv_sec = 1;
|
116
|
+
ireg->ts.tv_nsec = 0;
|
117
|
+
ireg->flags = IORING_REG_WAIT_TS;
|
118
|
+
|
119
|
+
gettimeofday(&tv, NULL);
|
120
|
+
ret = io_uring_submit_and_wait_reg(&ring, &cqe, 1, 56);
|
121
|
+
if (ret != -EFAULT) {
|
122
|
+
fprintf(stderr, "out-of-range reg_wait failed: %d\n", ret);
|
123
|
+
return T_EXIT_FAIL;
|
124
|
+
}
|
125
|
+
|
126
|
+
free(buf);
|
127
|
+
io_uring_queue_exit(&ring);
|
128
|
+
return T_EXIT_PASS;
|
129
|
+
err:
|
130
|
+
io_uring_queue_exit(&ring);
|
131
|
+
return T_EXIT_FAIL;
|
132
|
+
}
|
133
|
+
|
134
|
+
static int test_invalid_sig(struct io_uring *ring)
|
135
|
+
{
|
136
|
+
struct io_uring_cqe *cqe;
|
137
|
+
sigset_t sig;
|
138
|
+
int ret;
|
139
|
+
|
140
|
+
memset(reg, 0, sizeof(*reg));
|
141
|
+
reg->ts.tv_sec = 1;
|
142
|
+
reg->ts.tv_nsec = 0;
|
143
|
+
reg->sigmask = (unsigned long) &sig;
|
144
|
+
reg->sigmask_sz = 1;
|
145
|
+
|
146
|
+
ret = io_uring_submit_and_wait_reg(ring, &cqe, 1, 0);
|
147
|
+
if (ret != -EINVAL) {
|
148
|
+
fprintf(stderr, "sigmask_sz failed: %d\n", ret);
|
149
|
+
return T_EXIT_FAIL;
|
150
|
+
}
|
151
|
+
|
152
|
+
memset(reg, 0, sizeof(*reg));
|
153
|
+
reg->ts.tv_sec = 1;
|
154
|
+
reg->ts.tv_nsec = 0;
|
155
|
+
reg->sigmask = 100;
|
156
|
+
reg->sigmask_sz = 8;
|
157
|
+
|
158
|
+
ret = io_uring_submit_and_wait_reg(ring, &cqe, 1, 0);
|
159
|
+
if (ret != -EFAULT) {
|
160
|
+
fprintf(stderr, "sigmask invalid failed: %d\n", ret);
|
161
|
+
return T_EXIT_FAIL;
|
162
|
+
}
|
163
|
+
|
164
|
+
return T_EXIT_PASS;
|
165
|
+
}
|
166
|
+
|
167
|
+
static int test_basic(struct io_uring *ring)
|
168
|
+
{
|
169
|
+
struct io_uring_cqe *cqe;
|
170
|
+
struct timeval tv;
|
171
|
+
int ret;
|
172
|
+
|
173
|
+
memset(reg, 0, sizeof(*reg));
|
174
|
+
reg->ts.tv_sec = 1;
|
175
|
+
reg->ts.tv_nsec = 100000000ULL;
|
176
|
+
reg->flags = IORING_REG_WAIT_TS;
|
177
|
+
|
178
|
+
gettimeofday(&tv, NULL);
|
179
|
+
ret = io_uring_submit_and_wait_reg(ring, &cqe, 2, 0);
|
180
|
+
if (ret != -ETIME) {
|
181
|
+
fprintf(stderr, "submit_and_wait_reg: %d\n", ret);
|
182
|
+
goto err;
|
183
|
+
}
|
184
|
+
ret = mtime_since_now(&tv);
|
185
|
+
/* allow some slack, should be around 1.1s */
|
186
|
+
if (ret < 1000 || ret > 1200) {
|
187
|
+
fprintf(stderr, "wait too long or short: %d\n", ret);
|
188
|
+
goto err;
|
189
|
+
}
|
190
|
+
return T_EXIT_PASS;
|
191
|
+
err:
|
192
|
+
return T_EXIT_FAIL;
|
193
|
+
}
|
194
|
+
|
195
|
+
static int test_ring(void)
|
196
|
+
{
|
197
|
+
struct io_uring ring;
|
198
|
+
struct io_uring_params p = { };
|
199
|
+
int ret;
|
200
|
+
|
201
|
+
p.flags = 0;
|
202
|
+
ret = io_uring_queue_init_params(8, &ring, &p);
|
203
|
+
if (ret) {
|
204
|
+
fprintf(stderr, "ring setup failed: %d\n", ret);
|
205
|
+
return 1;
|
206
|
+
}
|
207
|
+
|
208
|
+
reg = io_uring_setup_reg_wait(&ring, 64, &ret);
|
209
|
+
if (!reg) {
|
210
|
+
if (ret == -EINVAL)
|
211
|
+
return T_EXIT_SKIP;
|
212
|
+
fprintf(stderr, "setup_reg_wait: %d\n", ret);
|
213
|
+
return T_EXIT_FAIL;
|
214
|
+
}
|
215
|
+
|
216
|
+
ret = test_basic(&ring);
|
217
|
+
if (ret == T_EXIT_FAIL) {
|
218
|
+
fprintf(stderr, "test failed\n");
|
219
|
+
goto err;
|
220
|
+
}
|
221
|
+
|
222
|
+
ret = test_invalid_sig(&ring);
|
223
|
+
if (ret == T_EXIT_FAIL) {
|
224
|
+
fprintf(stderr, "test_invalid sig failed\n");
|
225
|
+
goto err;
|
226
|
+
}
|
227
|
+
|
228
|
+
ret = test_invalid_reg();
|
229
|
+
if (ret == T_EXIT_FAIL) {
|
230
|
+
fprintf(stderr, "test_invalid_reg failed\n");
|
231
|
+
goto err;
|
232
|
+
}
|
233
|
+
|
234
|
+
ret = test_invalid_reg2();
|
235
|
+
if (ret == T_EXIT_FAIL) {
|
236
|
+
fprintf(stderr, "test_invalid_reg2 failed\n");
|
237
|
+
goto err;
|
238
|
+
}
|
239
|
+
|
240
|
+
err:
|
241
|
+
io_uring_queue_exit(&ring);
|
242
|
+
return ret;
|
243
|
+
}
|
244
|
+
|
245
|
+
int main(int argc, char *argv[])
|
246
|
+
{
|
247
|
+
if (argc > 1)
|
248
|
+
return 0;
|
249
|
+
|
250
|
+
return test_ring();
|
251
|
+
}
|