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
@@ -23,7 +23,134 @@
|
|
23
23
|
|
24
24
|
#define NR_OVERFLOW (NR_BUFS / 4)
|
25
25
|
|
26
|
-
static int no_buf_ring, no_read_mshot;
|
26
|
+
static int no_buf_ring, no_read_mshot, no_buf_ring_inc;
|
27
|
+
|
28
|
+
static void arm_read(struct io_uring *ring, int fd, int use_mshot)
|
29
|
+
{
|
30
|
+
struct io_uring_sqe *sqe;
|
31
|
+
|
32
|
+
sqe = io_uring_get_sqe(ring);
|
33
|
+
if (use_mshot) {
|
34
|
+
io_uring_prep_read_multishot(sqe, fd, 0, 0, BUF_BGID);
|
35
|
+
} else {
|
36
|
+
io_uring_prep_read(sqe, fd, NULL, 0, 0);
|
37
|
+
sqe->flags = IOSQE_BUFFER_SELECT;
|
38
|
+
sqe->buf_group = BUF_BGID;
|
39
|
+
}
|
40
|
+
|
41
|
+
io_uring_submit(ring);
|
42
|
+
}
|
43
|
+
|
44
|
+
static int test_inc(int use_mshot, int flags)
|
45
|
+
{
|
46
|
+
struct io_uring_buf_ring *br;
|
47
|
+
struct io_uring_params p = { };
|
48
|
+
struct io_uring_cqe *cqe;
|
49
|
+
struct io_uring ring;
|
50
|
+
int nbytes = 65536;
|
51
|
+
int ret, fds[2], i;
|
52
|
+
char tmp[31];
|
53
|
+
char *buf;
|
54
|
+
void *ptr;
|
55
|
+
int bid = -1;
|
56
|
+
int bid_bytes;
|
57
|
+
|
58
|
+
if (no_buf_ring)
|
59
|
+
return 0;
|
60
|
+
|
61
|
+
p.flags = flags;
|
62
|
+
ret = io_uring_queue_init_params(64, &ring, &p);
|
63
|
+
if (ret) {
|
64
|
+
fprintf(stderr, "ring setup failed: %d\n", ret);
|
65
|
+
return 1;
|
66
|
+
}
|
67
|
+
|
68
|
+
if (pipe(fds) < 0) {
|
69
|
+
perror("pipe");
|
70
|
+
return 1;
|
71
|
+
}
|
72
|
+
|
73
|
+
if (posix_memalign((void **) &buf, 4096, 65536))
|
74
|
+
return 1;
|
75
|
+
|
76
|
+
br = io_uring_setup_buf_ring(&ring, 32, BUF_BGID, IOU_PBUF_RING_INC, &ret);
|
77
|
+
if (!br) {
|
78
|
+
if (ret == -EINVAL) {
|
79
|
+
no_buf_ring_inc = 1;
|
80
|
+
free(buf);
|
81
|
+
return 0;
|
82
|
+
}
|
83
|
+
fprintf(stderr, "Buffer ring register failed %d\n", ret);
|
84
|
+
return 1;
|
85
|
+
}
|
86
|
+
|
87
|
+
ptr = buf;
|
88
|
+
buf = ptr + 65536 - 2048;
|
89
|
+
for (i = 0; i < 32; i++) {
|
90
|
+
io_uring_buf_ring_add(br, buf, 2048, i, 31, i);
|
91
|
+
buf -= 2048;
|
92
|
+
}
|
93
|
+
io_uring_buf_ring_advance(br, 32);
|
94
|
+
|
95
|
+
memset(tmp, 0x5a, sizeof(tmp));
|
96
|
+
|
97
|
+
arm_read(&ring, fds[0], use_mshot);
|
98
|
+
|
99
|
+
bid_bytes = 0;
|
100
|
+
do {
|
101
|
+
int write_size = sizeof(tmp);
|
102
|
+
|
103
|
+
if (write_size > nbytes)
|
104
|
+
write_size = nbytes;
|
105
|
+
|
106
|
+
io_uring_get_events(&ring);
|
107
|
+
ret = io_uring_peek_cqe(&ring, &cqe);
|
108
|
+
if (!ret) {
|
109
|
+
int this_bid = cqe->flags >> IORING_CQE_BUFFER_SHIFT;
|
110
|
+
if (bid == -1) {
|
111
|
+
bid = this_bid;
|
112
|
+
} else if (bid != this_bid) {
|
113
|
+
if (bid_bytes != 2048) {
|
114
|
+
fprintf(stderr, "unexpected bid bytes %d\n",
|
115
|
+
bid_bytes);
|
116
|
+
return 1;
|
117
|
+
}
|
118
|
+
bid = this_bid;
|
119
|
+
bid_bytes = 0;
|
120
|
+
}
|
121
|
+
bid_bytes += cqe->res;
|
122
|
+
nbytes -= cqe->res;
|
123
|
+
if (!(cqe->flags & IORING_CQE_F_MORE))
|
124
|
+
arm_read(&ring, fds[0], use_mshot);
|
125
|
+
io_uring_cqe_seen(&ring, cqe);
|
126
|
+
if (!nbytes)
|
127
|
+
break;
|
128
|
+
}
|
129
|
+
usleep(1000);
|
130
|
+
ret = write(fds[1], tmp, write_size);
|
131
|
+
if (ret < 0) {
|
132
|
+
perror("write");
|
133
|
+
return 1;
|
134
|
+
} else if (ret != write_size) {
|
135
|
+
printf("short write %d\n", ret);
|
136
|
+
return 1;
|
137
|
+
}
|
138
|
+
} while (nbytes);
|
139
|
+
|
140
|
+
if (bid_bytes) {
|
141
|
+
if (bid_bytes != 2048) {
|
142
|
+
fprintf(stderr, "unexpected bid bytes %d\n", bid_bytes);
|
143
|
+
return 1;
|
144
|
+
}
|
145
|
+
}
|
146
|
+
|
147
|
+
io_uring_free_buf_ring(&ring, br, 32, BUF_BGID);
|
148
|
+
io_uring_queue_exit(&ring);
|
149
|
+
free(ptr);
|
150
|
+
close(fds[0]);
|
151
|
+
close(fds[1]);
|
152
|
+
return 0;
|
153
|
+
}
|
27
154
|
|
28
155
|
static int test_clamp(void)
|
29
156
|
{
|
@@ -129,21 +256,24 @@ static int test_clamp(void)
|
|
129
256
|
io_uring_cqe_seen(&ring, cqe);
|
130
257
|
}
|
131
258
|
|
259
|
+
io_uring_free_buf_ring(&ring, br, NR_BUFS, BUF_BGID);
|
132
260
|
io_uring_queue_exit(&ring);
|
133
261
|
free(ptr);
|
134
262
|
return 0;
|
135
263
|
}
|
136
264
|
|
137
|
-
static int test(int first_good, int async, int overflow)
|
265
|
+
static int test(int first_good, int async, int overflow, int incremental)
|
138
266
|
{
|
139
267
|
struct io_uring_buf_ring *br;
|
140
268
|
struct io_uring_params p = { };
|
141
269
|
struct io_uring_sqe *sqe;
|
142
270
|
struct io_uring_cqe *cqe;
|
143
271
|
struct io_uring ring;
|
144
|
-
int ret, fds[2], i;
|
272
|
+
int ret, fds[2], i, start_msg = 0;
|
273
|
+
int br_flags = 0;
|
145
274
|
char tmp[32];
|
146
275
|
void *ptr[NR_BUFS];
|
276
|
+
char *inc_index;
|
147
277
|
|
148
278
|
p.flags = IORING_SETUP_CQSIZE;
|
149
279
|
if (!overflow)
|
@@ -156,14 +286,19 @@ static int test(int first_good, int async, int overflow)
|
|
156
286
|
return 1;
|
157
287
|
}
|
158
288
|
|
159
|
-
if (
|
160
|
-
|
161
|
-
|
289
|
+
if (incremental) {
|
290
|
+
if (no_buf_ring_inc)
|
291
|
+
return 0;
|
292
|
+
br_flags |= IOU_PBUF_RING_INC;
|
162
293
|
}
|
163
294
|
|
164
|
-
br = io_uring_setup_buf_ring(&ring, NR_BUFS, BUF_BGID,
|
295
|
+
br = io_uring_setup_buf_ring(&ring, NR_BUFS, BUF_BGID, br_flags, &ret);
|
165
296
|
if (!br) {
|
166
297
|
if (ret == -EINVAL) {
|
298
|
+
if (incremental) {
|
299
|
+
no_buf_ring_inc = 1;
|
300
|
+
return 0;
|
301
|
+
}
|
167
302
|
no_buf_ring = 1;
|
168
303
|
return 0;
|
169
304
|
}
|
@@ -171,17 +306,30 @@ static int test(int first_good, int async, int overflow)
|
|
171
306
|
return 1;
|
172
307
|
}
|
173
308
|
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
309
|
+
if (pipe(fds) < 0) {
|
310
|
+
perror("pipe");
|
311
|
+
return 1;
|
312
|
+
}
|
313
|
+
|
314
|
+
if (!incremental) {
|
315
|
+
for (i = 0; i < NR_BUFS; i++) {
|
316
|
+
unsigned size = i <= 1 ? BUF_SIZE_FIRST : BUF_SIZE;
|
317
|
+
ptr[i] = malloc(size);
|
318
|
+
if (!ptr[i])
|
319
|
+
return 1;
|
320
|
+
io_uring_buf_ring_add(br, ptr[i], size, i + 1, BR_MASK, i);
|
321
|
+
}
|
322
|
+
inc_index = NULL;
|
323
|
+
io_uring_buf_ring_advance(br, NR_BUFS);
|
324
|
+
} else {
|
325
|
+
inc_index = ptr[0] = malloc(NR_BUFS * BUF_SIZE);
|
326
|
+
memset(inc_index, 0, NR_BUFS * BUF_SIZE);
|
327
|
+
io_uring_buf_ring_add(br, ptr[0], NR_BUFS * BUF_SIZE, 1, BR_MASK, 0);
|
328
|
+
io_uring_buf_ring_advance(br, 1);
|
180
329
|
}
|
181
|
-
io_uring_buf_ring_advance(br, NR_BUFS);
|
182
330
|
|
183
331
|
if (first_good) {
|
184
|
-
sprintf(tmp, "this is buffer %d\n",
|
332
|
+
sprintf(tmp, "this is buffer %d\n", start_msg++);
|
185
333
|
ret = write(fds[1], tmp, strlen(tmp));
|
186
334
|
}
|
187
335
|
|
@@ -201,7 +349,7 @@ static int test(int first_good, int async, int overflow)
|
|
201
349
|
for (i = 0; i < NR_BUFS + !first_good; i++) {
|
202
350
|
/* prevent pipe buffer merging */
|
203
351
|
usleep(1000);
|
204
|
-
sprintf(tmp, "this is buffer %d\n", i +
|
352
|
+
sprintf(tmp, "this is buffer %d\n", i + start_msg);
|
205
353
|
ret = write(fds[1], tmp, strlen(tmp));
|
206
354
|
if (ret != strlen(tmp)) {
|
207
355
|
fprintf(stderr, "write ret %d\n", ret);
|
@@ -210,6 +358,8 @@ static int test(int first_good, int async, int overflow)
|
|
210
358
|
}
|
211
359
|
|
212
360
|
for (i = 0; i < NR_BUFS + 1; i++) {
|
361
|
+
int bid;
|
362
|
+
|
213
363
|
ret = io_uring_wait_cqe(&ring, &cqe);
|
214
364
|
if (ret) {
|
215
365
|
fprintf(stderr, "wait cqe failed %d\n", ret);
|
@@ -234,6 +384,18 @@ static int test(int first_good, int async, int overflow)
|
|
234
384
|
fprintf(stderr, "no buffer selected\n");
|
235
385
|
return 1;
|
236
386
|
}
|
387
|
+
bid = cqe->flags >> IORING_CQE_BUFFER_SHIFT;
|
388
|
+
if (incremental && bid != 1) {
|
389
|
+
fprintf(stderr, "bid %d for incremental\n", bid);
|
390
|
+
return 1;
|
391
|
+
}
|
392
|
+
if (incremental && !first_good) {
|
393
|
+
char out_buf[64];
|
394
|
+
sprintf(out_buf, "this is buffer %d\n", i + start_msg);
|
395
|
+
if (strncmp(inc_index, out_buf, strlen(out_buf)))
|
396
|
+
return 1;
|
397
|
+
inc_index += cqe->res;
|
398
|
+
}
|
237
399
|
if (!(cqe->flags & IORING_CQE_F_MORE)) {
|
238
400
|
/* we expect this on overflow */
|
239
401
|
if (overflow && i >= NR_OVERFLOW)
|
@@ -249,9 +411,15 @@ static int test(int first_good, int async, int overflow)
|
|
249
411
|
io_uring_cqe_seen(&ring, cqe);
|
250
412
|
}
|
251
413
|
|
414
|
+
|
415
|
+
io_uring_free_buf_ring(&ring, br, NR_BUFS, BUF_BGID);
|
252
416
|
io_uring_queue_exit(&ring);
|
253
|
-
|
254
|
-
free(ptr[
|
417
|
+
if (incremental) {
|
418
|
+
free(ptr[0]);
|
419
|
+
} else {
|
420
|
+
for (i = 0; i < NR_BUFS; i++)
|
421
|
+
free(ptr[i]);
|
422
|
+
}
|
255
423
|
return 0;
|
256
424
|
}
|
257
425
|
|
@@ -320,6 +488,7 @@ static int test_invalid(int async)
|
|
320
488
|
}
|
321
489
|
|
322
490
|
io_uring_cqe_seen(&ring, cqe);
|
491
|
+
io_uring_free_buf_ring(&ring, br, 1, BUF_BGID);
|
323
492
|
io_uring_queue_exit(&ring);
|
324
493
|
free(buf);
|
325
494
|
return 0;
|
@@ -332,56 +501,106 @@ int main(int argc, char *argv[])
|
|
332
501
|
if (argc > 1)
|
333
502
|
return T_EXIT_SKIP;
|
334
503
|
|
335
|
-
ret = test(0, 0, 0);
|
504
|
+
ret = test(0, 0, 0, 0);
|
336
505
|
if (ret) {
|
337
506
|
fprintf(stderr, "test 0 0 0 failed\n");
|
338
507
|
return T_EXIT_FAIL;
|
339
508
|
}
|
340
|
-
if (no_buf_ring || no_read_mshot)
|
509
|
+
if (no_buf_ring || no_read_mshot) {
|
510
|
+
printf("skip\n");
|
341
511
|
return T_EXIT_SKIP;
|
512
|
+
}
|
342
513
|
|
343
|
-
ret = test(0, 1, 0);
|
514
|
+
ret = test(0, 1, 0, 0);
|
344
515
|
if (ret) {
|
345
516
|
fprintf(stderr, "test 0 1 0, failed\n");
|
346
517
|
return T_EXIT_FAIL;
|
347
518
|
}
|
348
519
|
|
349
|
-
ret = test(1, 0, 0);
|
520
|
+
ret = test(1, 0, 0, 0);
|
350
521
|
if (ret) {
|
351
522
|
fprintf(stderr, "test 1 0 0 failed\n");
|
352
523
|
return T_EXIT_FAIL;
|
353
524
|
}
|
354
525
|
|
355
|
-
ret = test(0, 0, 1);
|
526
|
+
ret = test(0, 0, 1, 0);
|
356
527
|
if (ret) {
|
357
528
|
fprintf(stderr, "test 0 0 1 failed\n");
|
358
529
|
return T_EXIT_FAIL;
|
359
530
|
}
|
360
531
|
|
361
|
-
ret = test(0, 1, 1);
|
532
|
+
ret = test(0, 1, 1, 0);
|
362
533
|
if (ret) {
|
363
534
|
fprintf(stderr, "test 0 1 1 failed\n");
|
364
535
|
return T_EXIT_FAIL;
|
365
536
|
}
|
366
537
|
|
367
|
-
ret = test(1, 0, 1);
|
538
|
+
ret = test(1, 0, 1, 0);
|
368
539
|
if (ret) {
|
369
540
|
fprintf(stderr, "test 1 0 1, failed\n");
|
370
541
|
return T_EXIT_FAIL;
|
371
542
|
}
|
372
543
|
|
373
|
-
ret = test(1, 0, 1);
|
544
|
+
ret = test(1, 0, 1, 0);
|
374
545
|
if (ret) {
|
375
546
|
fprintf(stderr, "test 1 0 1 failed\n");
|
376
547
|
return T_EXIT_FAIL;
|
377
548
|
}
|
378
549
|
|
379
|
-
ret = test(1, 1, 1);
|
550
|
+
ret = test(1, 1, 1, 0);
|
380
551
|
if (ret) {
|
381
552
|
fprintf(stderr, "test 1 1 1 failed\n");
|
382
553
|
return T_EXIT_FAIL;
|
383
554
|
}
|
384
555
|
|
556
|
+
ret = test(0, 0, 0, 1);
|
557
|
+
if (ret) {
|
558
|
+
fprintf(stderr, "test 0 0 0 1 failed\n");
|
559
|
+
return T_EXIT_FAIL;
|
560
|
+
}
|
561
|
+
|
562
|
+
ret = test(0, 0, 1, 1);
|
563
|
+
if (ret) {
|
564
|
+
fprintf(stderr, "test 0 0 1 1 failed\n");
|
565
|
+
return T_EXIT_FAIL;
|
566
|
+
}
|
567
|
+
|
568
|
+
ret = test(0, 1, 0, 1);
|
569
|
+
if (ret) {
|
570
|
+
fprintf(stderr, "test 0 1 0 1 failed\n");
|
571
|
+
return T_EXIT_FAIL;
|
572
|
+
}
|
573
|
+
|
574
|
+
ret = test(0, 1, 1, 1);
|
575
|
+
if (ret) {
|
576
|
+
fprintf(stderr, "test 0 1 1 1 failed\n");
|
577
|
+
return T_EXIT_FAIL;
|
578
|
+
}
|
579
|
+
|
580
|
+
ret = test(1, 0, 0, 1);
|
581
|
+
if (ret) {
|
582
|
+
fprintf(stderr, "test 1 0 0 1 failed\n");
|
583
|
+
return T_EXIT_FAIL;
|
584
|
+
}
|
585
|
+
|
586
|
+
ret = test(1, 0, 1, 1);
|
587
|
+
if (ret) {
|
588
|
+
fprintf(stderr, "test 1 0 1 1 failed\n");
|
589
|
+
return T_EXIT_FAIL;
|
590
|
+
}
|
591
|
+
|
592
|
+
ret = test(1, 1, 0, 1);
|
593
|
+
if (ret) {
|
594
|
+
fprintf(stderr, "test 1 1 0 1 failed\n");
|
595
|
+
return T_EXIT_FAIL;
|
596
|
+
}
|
597
|
+
|
598
|
+
ret = test(1, 1, 1, 1);
|
599
|
+
if (ret) {
|
600
|
+
fprintf(stderr, "test 1 1 1 1 failed\n");
|
601
|
+
return T_EXIT_FAIL;
|
602
|
+
}
|
603
|
+
|
385
604
|
ret = test_invalid(0);
|
386
605
|
if (ret) {
|
387
606
|
fprintf(stderr, "test_invalid 0 failed\n");
|
@@ -400,5 +619,41 @@ int main(int argc, char *argv[])
|
|
400
619
|
return T_EXIT_FAIL;
|
401
620
|
}
|
402
621
|
|
622
|
+
ret = test_inc(0, 0);
|
623
|
+
if (ret) {
|
624
|
+
fprintf(stderr, "test_inc 0 0 failed\n");
|
625
|
+
return T_EXIT_FAIL;
|
626
|
+
}
|
627
|
+
|
628
|
+
ret = test_inc(0, IORING_SETUP_SQPOLL);
|
629
|
+
if (ret) {
|
630
|
+
fprintf(stderr, "test_inc 0 sqpoll failed\n");
|
631
|
+
return T_EXIT_FAIL;
|
632
|
+
}
|
633
|
+
|
634
|
+
ret = test_inc(0, IORING_SETUP_SINGLE_ISSUER | IORING_SETUP_DEFER_TASKRUN);
|
635
|
+
if (ret) {
|
636
|
+
fprintf(stderr, "test_inc 0 defer failed\n");
|
637
|
+
return T_EXIT_FAIL;
|
638
|
+
}
|
639
|
+
|
640
|
+
ret = test_inc(1, 0);
|
641
|
+
if (ret) {
|
642
|
+
fprintf(stderr, "test_inc 1 0 failed\n");
|
643
|
+
return T_EXIT_FAIL;
|
644
|
+
}
|
645
|
+
|
646
|
+
ret = test_inc(1, IORING_SETUP_SQPOLL);
|
647
|
+
if (ret) {
|
648
|
+
fprintf(stderr, "test_inc 1 sqpoll failed\n");
|
649
|
+
return T_EXIT_FAIL;
|
650
|
+
}
|
651
|
+
|
652
|
+
ret = test_inc(1, IORING_SETUP_SINGLE_ISSUER | IORING_SETUP_DEFER_TASKRUN);
|
653
|
+
if (ret) {
|
654
|
+
fprintf(stderr, "test_inc 1 defer failed\n");
|
655
|
+
return T_EXIT_FAIL;
|
656
|
+
}
|
657
|
+
|
403
658
|
return T_EXIT_PASS;
|
404
659
|
}
|
@@ -15,6 +15,7 @@
|
|
15
15
|
|
16
16
|
#include "helpers.h"
|
17
17
|
#include "liburing.h"
|
18
|
+
#include "../src/syscall.h"
|
18
19
|
|
19
20
|
#define FILE_SIZE (256 * 1024)
|
20
21
|
#define BS 8192
|
@@ -23,6 +24,7 @@
|
|
23
24
|
static struct iovec *vecs;
|
24
25
|
static int no_read;
|
25
26
|
static int no_buf_select;
|
27
|
+
static int no_buf_copy;
|
26
28
|
static int warned;
|
27
29
|
|
28
30
|
static int create_nonaligned_buffers(void)
|
@@ -42,9 +44,9 @@ static int create_nonaligned_buffers(void)
|
|
42
44
|
return 0;
|
43
45
|
}
|
44
46
|
|
45
|
-
static int
|
46
|
-
|
47
|
-
|
47
|
+
static int _test_io(const char *file, struct io_uring *ring, int write,
|
48
|
+
int buffered, int sqthread, int fixed, int nonvec,
|
49
|
+
int buf_select, int seq, int exp_len)
|
48
50
|
{
|
49
51
|
struct io_uring_sqe *sqe;
|
50
52
|
struct io_uring_cqe *cqe;
|
@@ -64,7 +66,7 @@ static int __test_io(const char *file, struct io_uring *ring, int write,
|
|
64
66
|
if (!buffered)
|
65
67
|
open_flags |= O_DIRECT;
|
66
68
|
|
67
|
-
if (fixed) {
|
69
|
+
if (fixed == 1) {
|
68
70
|
ret = t_register_buffers(ring, vecs, BUFFERS);
|
69
71
|
if (ret == T_SETUP_SKIP)
|
70
72
|
return 0;
|
@@ -76,7 +78,7 @@ static int __test_io(const char *file, struct io_uring *ring, int write,
|
|
76
78
|
|
77
79
|
fd = open(file, open_flags);
|
78
80
|
if (fd < 0) {
|
79
|
-
if (errno == EINVAL)
|
81
|
+
if (errno == EINVAL || errno == EPERM || errno == EACCES)
|
80
82
|
return 0;
|
81
83
|
perror("file open");
|
82
84
|
goto err;
|
@@ -201,13 +203,6 @@ static int __test_io(const char *file, struct io_uring *ring, int write,
|
|
201
203
|
io_uring_cqe_seen(ring, cqe);
|
202
204
|
}
|
203
205
|
|
204
|
-
if (fixed) {
|
205
|
-
ret = io_uring_unregister_buffers(ring);
|
206
|
-
if (ret) {
|
207
|
-
fprintf(stderr, "buffer unreg failed: %d\n", ret);
|
208
|
-
goto err;
|
209
|
-
}
|
210
|
-
}
|
211
206
|
if (sqthread) {
|
212
207
|
ret = io_uring_unregister_files(ring);
|
213
208
|
if (ret) {
|
@@ -229,6 +224,65 @@ err:
|
|
229
224
|
close(fd);
|
230
225
|
return 1;
|
231
226
|
}
|
227
|
+
|
228
|
+
static int __test_io(const char *file, struct io_uring *ring, int write,
|
229
|
+
int buffered, int sqthread, int fixed, int nonvec,
|
230
|
+
int buf_select, int seq, int exp_len)
|
231
|
+
{
|
232
|
+
int ret;
|
233
|
+
|
234
|
+
ret = _test_io(file, ring, write, buffered, sqthread, fixed, nonvec,
|
235
|
+
buf_select, seq, exp_len);
|
236
|
+
if (ret)
|
237
|
+
return ret;
|
238
|
+
|
239
|
+
if (fixed) {
|
240
|
+
struct io_uring ring2;
|
241
|
+
int ring_flags = 0;
|
242
|
+
|
243
|
+
if (no_buf_copy)
|
244
|
+
return 0;
|
245
|
+
if (sqthread)
|
246
|
+
ring_flags = IORING_SETUP_SQPOLL;
|
247
|
+
ret = t_create_ring(64, &ring2, ring_flags);
|
248
|
+
if (ret == T_SETUP_SKIP)
|
249
|
+
return 0;
|
250
|
+
if (ret != T_SETUP_OK) {
|
251
|
+
fprintf(stderr, "ring create failed: %d\n", ret);
|
252
|
+
return 1;
|
253
|
+
}
|
254
|
+
|
255
|
+
ret = io_uring_clone_buffers(&ring2, ring);
|
256
|
+
if (ret) {
|
257
|
+
if (ret == -EINVAL) {
|
258
|
+
no_buf_copy = 1;
|
259
|
+
io_uring_queue_exit(&ring2);
|
260
|
+
return 0;
|
261
|
+
}
|
262
|
+
fprintf(stderr, "copy buffers: %d\n", ret);
|
263
|
+
return ret;
|
264
|
+
}
|
265
|
+
ret = _test_io(file, &ring2, write, buffered, sqthread, 2,
|
266
|
+
nonvec, buf_select, seq, exp_len);
|
267
|
+
if (ret)
|
268
|
+
return ret;
|
269
|
+
|
270
|
+
ret = io_uring_unregister_buffers(ring);
|
271
|
+
if (ret) {
|
272
|
+
fprintf(stderr, "buffer unreg failed: %d\n", ret);
|
273
|
+
return ret;
|
274
|
+
}
|
275
|
+
ret = io_uring_unregister_buffers(&ring2);
|
276
|
+
if (ret) {
|
277
|
+
fprintf(stderr, "buffer copy unreg failed: %d\n", ret);
|
278
|
+
return ret;
|
279
|
+
}
|
280
|
+
io_uring_queue_exit(&ring2);
|
281
|
+
}
|
282
|
+
|
283
|
+
return ret;
|
284
|
+
}
|
285
|
+
|
232
286
|
static int test_io(const char *file, int write, int buffered, int sqthread,
|
233
287
|
int fixed, int nonvec, int exp_len)
|
234
288
|
{
|
@@ -266,6 +320,8 @@ static int read_poll_link(const char *file)
|
|
266
320
|
|
267
321
|
fd = open(file, O_WRONLY);
|
268
322
|
if (fd < 0) {
|
323
|
+
if (errno == EACCES || errno == EPERM)
|
324
|
+
return T_EXIT_SKIP;
|
269
325
|
perror("open");
|
270
326
|
return 1;
|
271
327
|
}
|
@@ -338,6 +394,7 @@ out:
|
|
338
394
|
if (!(p->ops[IORING_OP_READ].flags & IO_URING_OP_SUPPORTED))
|
339
395
|
goto out;
|
340
396
|
io_uring_queue_exit(&ring);
|
397
|
+
free(p);
|
341
398
|
return 1;
|
342
399
|
}
|
343
400
|
|
@@ -696,6 +753,8 @@ static int test_io_link(const char *file)
|
|
696
753
|
|
697
754
|
fd = open(file, O_WRONLY);
|
698
755
|
if (fd < 0) {
|
756
|
+
if (errno == EPERM || errno == EACCES)
|
757
|
+
return 0;
|
699
758
|
perror("file open");
|
700
759
|
goto err;
|
701
760
|
}
|
@@ -929,7 +988,7 @@ int main(int argc, char *argv[])
|
|
929
988
|
}
|
930
989
|
|
931
990
|
ret = read_poll_link(fname);
|
932
|
-
if (ret) {
|
991
|
+
if (ret == T_EXIT_FAIL) {
|
933
992
|
fprintf(stderr, "read_poll_link failed\n");
|
934
993
|
goto err;
|
935
994
|
}
|
@@ -970,6 +1029,12 @@ int main(int argc, char *argv[])
|
|
970
1029
|
goto err;
|
971
1030
|
}
|
972
1031
|
|
1032
|
+
if(vecs != NULL) {
|
1033
|
+
for (i = 0; i < BUFFERS; i++)
|
1034
|
+
free(vecs[i].iov_base);
|
1035
|
+
}
|
1036
|
+
free(vecs);
|
1037
|
+
|
973
1038
|
srand((unsigned)time(NULL));
|
974
1039
|
if (create_nonaligned_buffers()) {
|
975
1040
|
fprintf(stderr, "file creation failed\n");
|
@@ -317,6 +317,7 @@ static int do_send(struct recv_data *rd)
|
|
317
317
|
if (cqe->res == -EINVAL) {
|
318
318
|
fprintf(stdout, "send not supported, skipping\n");
|
319
319
|
close(sockfd);
|
320
|
+
free(buf);
|
320
321
|
return 0;
|
321
322
|
}
|
322
323
|
if (cqe->res != iov.iov_len) {
|
@@ -328,10 +329,12 @@ static int do_send(struct recv_data *rd)
|
|
328
329
|
|
329
330
|
shutdown(sockfd, SHUT_RDWR);
|
330
331
|
close(sockfd);
|
332
|
+
free(buf);
|
331
333
|
return 0;
|
332
334
|
err:
|
333
335
|
shutdown(sockfd, SHUT_RDWR);
|
334
336
|
close(sockfd);
|
337
|
+
free(buf);
|
335
338
|
return 1;
|
336
339
|
}
|
337
340
|
|
@@ -171,12 +171,14 @@ static int do_send(void)
|
|
171
171
|
sockfd = socket(AF_INET, SOCK_DGRAM, 0);
|
172
172
|
if (sockfd < 0) {
|
173
173
|
perror("socket");
|
174
|
+
free(buf);
|
174
175
|
return 1;
|
175
176
|
}
|
176
177
|
|
177
178
|
ret = connect(sockfd, (struct sockaddr *)&saddr, sizeof(saddr));
|
178
179
|
if (ret < 0) {
|
179
180
|
perror("connect");
|
181
|
+
free(buf);
|
180
182
|
return 1;
|
181
183
|
}
|
182
184
|
|
@@ -201,6 +203,7 @@ static int do_send(void)
|
|
201
203
|
if (cqe->res == -EINVAL) {
|
202
204
|
fprintf(stdout, "send not supported, skipping\n");
|
203
205
|
close(sockfd);
|
206
|
+
free(buf);
|
204
207
|
return 0;
|
205
208
|
}
|
206
209
|
if (cqe->res != iov.iov_len) {
|
@@ -211,9 +214,11 @@ static int do_send(void)
|
|
211
214
|
}
|
212
215
|
|
213
216
|
close(sockfd);
|
217
|
+
free(buf);
|
214
218
|
return 0;
|
215
219
|
err:
|
216
220
|
close(sockfd);
|
221
|
+
free(buf);
|
217
222
|
return 1;
|
218
223
|
}
|
219
224
|
|