uringmachine 0.3 → 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 +9 -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 +245 -53
- data/ext/um/um.h +21 -9
- data/ext/um/um_class.c +74 -87
- data/ext/um/um_const.c +184 -0
- data/ext/um/um_op.c +10 -13
- 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 +8 -0
- data/test/test_um.rb +227 -7
- 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
@@ -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;
|
@@ -267,19 +294,28 @@ static void *recv_fn(void *data)
|
|
267
294
|
if (posix_memalign(&buf, 4096, 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
456
|
if (posix_memalign(&buf, 4096, 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,14 +49,15 @@ 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
|
59
|
+
IORING_SETUP_REGISTERED_FD_ONLY | IORING_SETUP_NO_MMAP |
|
60
|
+
ring_flags);
|
60
61
|
if (ret == -EINVAL) {
|
61
62
|
no_mmap = 1;
|
62
63
|
return T_EXIT_SKIP;
|
@@ -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,187 @@
|
|
1
|
+
/* SPDX-License-Identifier: MIT */
|
2
|
+
/*
|
3
|
+
* Description: test buffer cloning between rings
|
4
|
+
*
|
5
|
+
*/
|
6
|
+
#include <errno.h>
|
7
|
+
#include <stdio.h>
|
8
|
+
#include <unistd.h>
|
9
|
+
#include <stdlib.h>
|
10
|
+
#include <sys/uio.h>
|
11
|
+
|
12
|
+
#include "liburing.h"
|
13
|
+
#include "helpers.h"
|
14
|
+
|
15
|
+
#define NR_VECS 64
|
16
|
+
#define BUF_SIZE 8192
|
17
|
+
|
18
|
+
static int test(int reg_src, int reg_dst)
|
19
|
+
{
|
20
|
+
struct iovec vecs[NR_VECS];
|
21
|
+
struct io_uring src, dst;
|
22
|
+
int ret, i;
|
23
|
+
|
24
|
+
ret = io_uring_queue_init(1, &src, 0);
|
25
|
+
if (ret) {
|
26
|
+
fprintf(stderr, "ring_init: %d\n", ret);
|
27
|
+
return T_EXIT_FAIL;
|
28
|
+
}
|
29
|
+
ret = io_uring_queue_init(1, &dst, 0);
|
30
|
+
if (ret) {
|
31
|
+
fprintf(stderr, "ring_init: %d\n", ret);
|
32
|
+
return T_EXIT_FAIL;
|
33
|
+
}
|
34
|
+
if (reg_src) {
|
35
|
+
ret = io_uring_register_ring_fd(&src);
|
36
|
+
if (ret < 0) {
|
37
|
+
if (ret == -EINVAL)
|
38
|
+
return T_EXIT_SKIP;
|
39
|
+
fprintf(stderr, "register ring: %d\n", ret);
|
40
|
+
return T_EXIT_FAIL;
|
41
|
+
}
|
42
|
+
}
|
43
|
+
if (reg_dst) {
|
44
|
+
ret = io_uring_register_ring_fd(&dst);
|
45
|
+
if (ret < 0) {
|
46
|
+
if (ret == -EINVAL)
|
47
|
+
return T_EXIT_SKIP;
|
48
|
+
fprintf(stderr, "register ring: %d\n", ret);
|
49
|
+
return T_EXIT_FAIL;
|
50
|
+
}
|
51
|
+
}
|
52
|
+
|
53
|
+
/* test fail with no buffers in src */
|
54
|
+
ret = io_uring_clone_buffers(&dst, &src);
|
55
|
+
if (ret == -EINVAL) {
|
56
|
+
/* no buffer copy support */
|
57
|
+
return T_EXIT_SKIP;
|
58
|
+
} else if (ret != -ENXIO) {
|
59
|
+
fprintf(stderr, "empty copy: %d\n", ret);
|
60
|
+
return T_EXIT_FAIL;
|
61
|
+
}
|
62
|
+
|
63
|
+
for (i = 0; i < NR_VECS; i++) {
|
64
|
+
if (posix_memalign(&vecs[i].iov_base, 4096, BUF_SIZE))
|
65
|
+
return T_EXIT_FAIL;
|
66
|
+
vecs[i].iov_len = BUF_SIZE;
|
67
|
+
}
|
68
|
+
|
69
|
+
ret = io_uring_register_buffers(&src, vecs, NR_VECS);
|
70
|
+
if (ret < 0) {
|
71
|
+
if (ret == -ENOMEM)
|
72
|
+
return T_EXIT_SKIP;
|
73
|
+
return T_EXIT_FAIL;
|
74
|
+
}
|
75
|
+
|
76
|
+
/* copy should work now */
|
77
|
+
ret = io_uring_clone_buffers(&dst, &src);
|
78
|
+
if (ret) {
|
79
|
+
fprintf(stderr, "buffer copy: %d\n", ret);
|
80
|
+
return T_EXIT_FAIL;
|
81
|
+
}
|
82
|
+
|
83
|
+
/* try copy again, should get -EBUSY */
|
84
|
+
ret = io_uring_clone_buffers(&dst, &src);
|
85
|
+
if (ret != -EBUSY) {
|
86
|
+
fprintf(stderr, "busy copy: %d\n", ret);
|
87
|
+
return T_EXIT_FAIL;
|
88
|
+
}
|
89
|
+
|
90
|
+
ret = io_uring_unregister_buffers(&dst);
|
91
|
+
if (ret) {
|
92
|
+
fprintf(stderr, "dst unregister buffers: %d\n", ret);
|
93
|
+
return T_EXIT_FAIL;
|
94
|
+
}
|
95
|
+
|
96
|
+
ret = io_uring_unregister_buffers(&dst);
|
97
|
+
if (ret != -ENXIO) {
|
98
|
+
fprintf(stderr, "dst unregister empty buffers: %d\n", ret);
|
99
|
+
return T_EXIT_FAIL;
|
100
|
+
}
|
101
|
+
|
102
|
+
ret = io_uring_unregister_buffers(&src);
|
103
|
+
if (ret) {
|
104
|
+
fprintf(stderr, "src unregister buffers: %d\n", ret);
|
105
|
+
return T_EXIT_FAIL;
|
106
|
+
}
|
107
|
+
|
108
|
+
ret = io_uring_register_buffers(&dst, vecs, NR_VECS);
|
109
|
+
if (ret < 0) {
|
110
|
+
fprintf(stderr, "register buffers dst; %d\n", ret);
|
111
|
+
return T_EXIT_FAIL;
|
112
|
+
}
|
113
|
+
|
114
|
+
ret = io_uring_clone_buffers(&src, &dst);
|
115
|
+
if (ret) {
|
116
|
+
fprintf(stderr, "buffer copy reverse: %d\n", ret);
|
117
|
+
return T_EXIT_FAIL;
|
118
|
+
}
|
119
|
+
|
120
|
+
ret = io_uring_unregister_buffers(&dst);
|
121
|
+
if (ret) {
|
122
|
+
fprintf(stderr, "dst unregister buffers: %d\n", ret);
|
123
|
+
return T_EXIT_FAIL;
|
124
|
+
}
|
125
|
+
|
126
|
+
ret = io_uring_unregister_buffers(&dst);
|
127
|
+
if (ret != -ENXIO) {
|
128
|
+
fprintf(stderr, "dst unregister empty buffers: %d\n", ret);
|
129
|
+
return T_EXIT_FAIL;
|
130
|
+
}
|
131
|
+
|
132
|
+
ret = io_uring_unregister_buffers(&src);
|
133
|
+
if (ret) {
|
134
|
+
fprintf(stderr, "src unregister buffers: %d\n", ret);
|
135
|
+
return T_EXIT_FAIL;
|
136
|
+
}
|
137
|
+
|
138
|
+
io_uring_queue_exit(&src);
|
139
|
+
io_uring_queue_exit(&dst);
|
140
|
+
|
141
|
+
for (i = 0; i < NR_VECS; i++)
|
142
|
+
free(vecs[i].iov_base);
|
143
|
+
|
144
|
+
return T_EXIT_PASS;
|
145
|
+
}
|
146
|
+
|
147
|
+
int main(int argc, char *argv[])
|
148
|
+
{
|
149
|
+
int ret;
|
150
|
+
|
151
|
+
if (argc > 1)
|
152
|
+
return T_EXIT_SKIP;
|
153
|
+
|
154
|
+
ret = test(0, 0);
|
155
|
+
if (ret == T_EXIT_SKIP) {
|
156
|
+
return T_EXIT_SKIP;
|
157
|
+
} else if (ret != T_EXIT_PASS) {
|
158
|
+
fprintf(stderr, "test 0 0 failed\n");
|
159
|
+
return T_EXIT_FAIL;
|
160
|
+
}
|
161
|
+
|
162
|
+
ret = test(0, 1);
|
163
|
+
if (ret == T_EXIT_SKIP) {
|
164
|
+
return T_EXIT_SKIP;
|
165
|
+
} else if (ret != T_EXIT_PASS) {
|
166
|
+
fprintf(stderr, "test 0 1 failed\n");
|
167
|
+
return T_EXIT_FAIL;
|
168
|
+
}
|
169
|
+
|
170
|
+
ret = test(1, 0);
|
171
|
+
if (ret == T_EXIT_SKIP) {
|
172
|
+
return T_EXIT_SKIP;
|
173
|
+
} else if (ret != T_EXIT_PASS) {
|
174
|
+
fprintf(stderr, "test 1 0 failed\n");
|
175
|
+
return T_EXIT_FAIL;
|
176
|
+
}
|
177
|
+
|
178
|
+
ret = test(1, 1);
|
179
|
+
if (ret == T_EXIT_SKIP) {
|
180
|
+
return T_EXIT_SKIP;
|
181
|
+
} else if (ret != T_EXIT_PASS) {
|
182
|
+
fprintf(stderr, "test 1 1 failed\n");
|
183
|
+
return T_EXIT_FAIL;
|
184
|
+
}
|
185
|
+
|
186
|
+
return T_EXIT_PASS;
|
187
|
+
}
|
@@ -13,6 +13,7 @@
|
|
13
13
|
|
14
14
|
#include "helpers.h"
|
15
15
|
|
16
|
+
#ifndef CONFIG_USE_SANITIZER
|
16
17
|
#ifndef __NR_io_uring_register
|
17
18
|
#define __NR_io_uring_register 427
|
18
19
|
#endif
|
@@ -89,3 +90,9 @@ int main(int argc, char *argv[])
|
|
89
90
|
syscall(__NR_io_uring_register, r[0], 0ul, 0x20002840ul, 2ul);
|
90
91
|
return T_EXIT_PASS;
|
91
92
|
}
|
93
|
+
#else
|
94
|
+
int main(int argc, char *argv[])
|
95
|
+
{
|
96
|
+
return T_EXIT_SKIP;
|
97
|
+
}
|
98
|
+
#endif
|