uringmachine 0.3 → 0.4
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/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
|
@@ -23,7 +23,132 @@
|
|
|
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
|
+
free(ptr);
|
|
148
|
+
close(fds[0]);
|
|
149
|
+
close(fds[1]);
|
|
150
|
+
return 0;
|
|
151
|
+
}
|
|
27
152
|
|
|
28
153
|
static int test_clamp(void)
|
|
29
154
|
{
|
|
@@ -134,16 +259,18 @@ static int test_clamp(void)
|
|
|
134
259
|
return 0;
|
|
135
260
|
}
|
|
136
261
|
|
|
137
|
-
static int test(int first_good, int async, int overflow)
|
|
262
|
+
static int test(int first_good, int async, int overflow, int incremental)
|
|
138
263
|
{
|
|
139
264
|
struct io_uring_buf_ring *br;
|
|
140
265
|
struct io_uring_params p = { };
|
|
141
266
|
struct io_uring_sqe *sqe;
|
|
142
267
|
struct io_uring_cqe *cqe;
|
|
143
268
|
struct io_uring ring;
|
|
144
|
-
int ret, fds[2], i;
|
|
269
|
+
int ret, fds[2], i, start_msg = 0;
|
|
270
|
+
int br_flags = 0;
|
|
145
271
|
char tmp[32];
|
|
146
272
|
void *ptr[NR_BUFS];
|
|
273
|
+
char *inc_index;
|
|
147
274
|
|
|
148
275
|
p.flags = IORING_SETUP_CQSIZE;
|
|
149
276
|
if (!overflow)
|
|
@@ -156,14 +283,19 @@ static int test(int first_good, int async, int overflow)
|
|
|
156
283
|
return 1;
|
|
157
284
|
}
|
|
158
285
|
|
|
159
|
-
if (
|
|
160
|
-
|
|
161
|
-
|
|
286
|
+
if (incremental) {
|
|
287
|
+
if (no_buf_ring_inc)
|
|
288
|
+
return 0;
|
|
289
|
+
br_flags |= IOU_PBUF_RING_INC;
|
|
162
290
|
}
|
|
163
291
|
|
|
164
|
-
br = io_uring_setup_buf_ring(&ring, NR_BUFS, BUF_BGID,
|
|
292
|
+
br = io_uring_setup_buf_ring(&ring, NR_BUFS, BUF_BGID, br_flags, &ret);
|
|
165
293
|
if (!br) {
|
|
166
294
|
if (ret == -EINVAL) {
|
|
295
|
+
if (incremental) {
|
|
296
|
+
no_buf_ring_inc = 1;
|
|
297
|
+
return 0;
|
|
298
|
+
}
|
|
167
299
|
no_buf_ring = 1;
|
|
168
300
|
return 0;
|
|
169
301
|
}
|
|
@@ -171,17 +303,30 @@ static int test(int first_good, int async, int overflow)
|
|
|
171
303
|
return 1;
|
|
172
304
|
}
|
|
173
305
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
306
|
+
if (pipe(fds) < 0) {
|
|
307
|
+
perror("pipe");
|
|
308
|
+
return 1;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
if (!incremental) {
|
|
312
|
+
for (i = 0; i < NR_BUFS; i++) {
|
|
313
|
+
unsigned size = i <= 1 ? BUF_SIZE_FIRST : BUF_SIZE;
|
|
314
|
+
ptr[i] = malloc(size);
|
|
315
|
+
if (!ptr[i])
|
|
316
|
+
return 1;
|
|
317
|
+
io_uring_buf_ring_add(br, ptr[i], size, i + 1, BR_MASK, i);
|
|
318
|
+
}
|
|
319
|
+
inc_index = NULL;
|
|
320
|
+
io_uring_buf_ring_advance(br, NR_BUFS);
|
|
321
|
+
} else {
|
|
322
|
+
inc_index = ptr[0] = malloc(NR_BUFS * BUF_SIZE);
|
|
323
|
+
memset(inc_index, 0, NR_BUFS * BUF_SIZE);
|
|
324
|
+
io_uring_buf_ring_add(br, ptr[0], NR_BUFS * BUF_SIZE, 1, BR_MASK, 0);
|
|
325
|
+
io_uring_buf_ring_advance(br, 1);
|
|
180
326
|
}
|
|
181
|
-
io_uring_buf_ring_advance(br, NR_BUFS);
|
|
182
327
|
|
|
183
328
|
if (first_good) {
|
|
184
|
-
sprintf(tmp, "this is buffer %d\n",
|
|
329
|
+
sprintf(tmp, "this is buffer %d\n", start_msg++);
|
|
185
330
|
ret = write(fds[1], tmp, strlen(tmp));
|
|
186
331
|
}
|
|
187
332
|
|
|
@@ -201,7 +346,7 @@ static int test(int first_good, int async, int overflow)
|
|
|
201
346
|
for (i = 0; i < NR_BUFS + !first_good; i++) {
|
|
202
347
|
/* prevent pipe buffer merging */
|
|
203
348
|
usleep(1000);
|
|
204
|
-
sprintf(tmp, "this is buffer %d\n", i +
|
|
349
|
+
sprintf(tmp, "this is buffer %d\n", i + start_msg);
|
|
205
350
|
ret = write(fds[1], tmp, strlen(tmp));
|
|
206
351
|
if (ret != strlen(tmp)) {
|
|
207
352
|
fprintf(stderr, "write ret %d\n", ret);
|
|
@@ -210,6 +355,8 @@ static int test(int first_good, int async, int overflow)
|
|
|
210
355
|
}
|
|
211
356
|
|
|
212
357
|
for (i = 0; i < NR_BUFS + 1; i++) {
|
|
358
|
+
int bid;
|
|
359
|
+
|
|
213
360
|
ret = io_uring_wait_cqe(&ring, &cqe);
|
|
214
361
|
if (ret) {
|
|
215
362
|
fprintf(stderr, "wait cqe failed %d\n", ret);
|
|
@@ -234,6 +381,18 @@ static int test(int first_good, int async, int overflow)
|
|
|
234
381
|
fprintf(stderr, "no buffer selected\n");
|
|
235
382
|
return 1;
|
|
236
383
|
}
|
|
384
|
+
bid = cqe->flags >> IORING_CQE_BUFFER_SHIFT;
|
|
385
|
+
if (incremental && bid != 1) {
|
|
386
|
+
fprintf(stderr, "bid %d for incremental\n", bid);
|
|
387
|
+
return 1;
|
|
388
|
+
}
|
|
389
|
+
if (incremental && !first_good) {
|
|
390
|
+
char out_buf[64];
|
|
391
|
+
sprintf(out_buf, "this is buffer %d\n", i + start_msg);
|
|
392
|
+
if (strncmp(inc_index, out_buf, strlen(out_buf)))
|
|
393
|
+
return 1;
|
|
394
|
+
inc_index += cqe->res;
|
|
395
|
+
}
|
|
237
396
|
if (!(cqe->flags & IORING_CQE_F_MORE)) {
|
|
238
397
|
/* we expect this on overflow */
|
|
239
398
|
if (overflow && i >= NR_OVERFLOW)
|
|
@@ -250,8 +409,12 @@ static int test(int first_good, int async, int overflow)
|
|
|
250
409
|
}
|
|
251
410
|
|
|
252
411
|
io_uring_queue_exit(&ring);
|
|
253
|
-
|
|
254
|
-
free(ptr[
|
|
412
|
+
if (incremental) {
|
|
413
|
+
free(ptr[0]);
|
|
414
|
+
} else {
|
|
415
|
+
for (i = 0; i < NR_BUFS; i++)
|
|
416
|
+
free(ptr[i]);
|
|
417
|
+
}
|
|
255
418
|
return 0;
|
|
256
419
|
}
|
|
257
420
|
|
|
@@ -332,56 +495,106 @@ int main(int argc, char *argv[])
|
|
|
332
495
|
if (argc > 1)
|
|
333
496
|
return T_EXIT_SKIP;
|
|
334
497
|
|
|
335
|
-
ret = test(0, 0, 0);
|
|
498
|
+
ret = test(0, 0, 0, 0);
|
|
336
499
|
if (ret) {
|
|
337
500
|
fprintf(stderr, "test 0 0 0 failed\n");
|
|
338
501
|
return T_EXIT_FAIL;
|
|
339
502
|
}
|
|
340
|
-
if (no_buf_ring || no_read_mshot)
|
|
503
|
+
if (no_buf_ring || no_read_mshot) {
|
|
504
|
+
printf("skip\n");
|
|
341
505
|
return T_EXIT_SKIP;
|
|
506
|
+
}
|
|
342
507
|
|
|
343
|
-
ret = test(0, 1, 0);
|
|
508
|
+
ret = test(0, 1, 0, 0);
|
|
344
509
|
if (ret) {
|
|
345
510
|
fprintf(stderr, "test 0 1 0, failed\n");
|
|
346
511
|
return T_EXIT_FAIL;
|
|
347
512
|
}
|
|
348
513
|
|
|
349
|
-
ret = test(1, 0, 0);
|
|
514
|
+
ret = test(1, 0, 0, 0);
|
|
350
515
|
if (ret) {
|
|
351
516
|
fprintf(stderr, "test 1 0 0 failed\n");
|
|
352
517
|
return T_EXIT_FAIL;
|
|
353
518
|
}
|
|
354
519
|
|
|
355
|
-
ret = test(0, 0, 1);
|
|
520
|
+
ret = test(0, 0, 1, 0);
|
|
356
521
|
if (ret) {
|
|
357
522
|
fprintf(stderr, "test 0 0 1 failed\n");
|
|
358
523
|
return T_EXIT_FAIL;
|
|
359
524
|
}
|
|
360
525
|
|
|
361
|
-
ret = test(0, 1, 1);
|
|
526
|
+
ret = test(0, 1, 1, 0);
|
|
362
527
|
if (ret) {
|
|
363
528
|
fprintf(stderr, "test 0 1 1 failed\n");
|
|
364
529
|
return T_EXIT_FAIL;
|
|
365
530
|
}
|
|
366
531
|
|
|
367
|
-
ret = test(1, 0, 1);
|
|
532
|
+
ret = test(1, 0, 1, 0);
|
|
368
533
|
if (ret) {
|
|
369
534
|
fprintf(stderr, "test 1 0 1, failed\n");
|
|
370
535
|
return T_EXIT_FAIL;
|
|
371
536
|
}
|
|
372
537
|
|
|
373
|
-
ret = test(1, 0, 1);
|
|
538
|
+
ret = test(1, 0, 1, 0);
|
|
374
539
|
if (ret) {
|
|
375
540
|
fprintf(stderr, "test 1 0 1 failed\n");
|
|
376
541
|
return T_EXIT_FAIL;
|
|
377
542
|
}
|
|
378
543
|
|
|
379
|
-
ret = test(1, 1, 1);
|
|
544
|
+
ret = test(1, 1, 1, 0);
|
|
380
545
|
if (ret) {
|
|
381
546
|
fprintf(stderr, "test 1 1 1 failed\n");
|
|
382
547
|
return T_EXIT_FAIL;
|
|
383
548
|
}
|
|
384
549
|
|
|
550
|
+
ret = test(0, 0, 0, 1);
|
|
551
|
+
if (ret) {
|
|
552
|
+
fprintf(stderr, "test 0 0 0 1 failed\n");
|
|
553
|
+
return T_EXIT_FAIL;
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
ret = test(0, 0, 1, 1);
|
|
557
|
+
if (ret) {
|
|
558
|
+
fprintf(stderr, "test 0 0 1 1 failed\n");
|
|
559
|
+
return T_EXIT_FAIL;
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
ret = test(0, 1, 0, 1);
|
|
563
|
+
if (ret) {
|
|
564
|
+
fprintf(stderr, "test 0 1 0 1 failed\n");
|
|
565
|
+
return T_EXIT_FAIL;
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
ret = test(0, 1, 1, 1);
|
|
569
|
+
if (ret) {
|
|
570
|
+
fprintf(stderr, "test 0 1 1 1 failed\n");
|
|
571
|
+
return T_EXIT_FAIL;
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
ret = test(1, 0, 0, 1);
|
|
575
|
+
if (ret) {
|
|
576
|
+
fprintf(stderr, "test 1 0 0 1 failed\n");
|
|
577
|
+
return T_EXIT_FAIL;
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
ret = test(1, 0, 1, 1);
|
|
581
|
+
if (ret) {
|
|
582
|
+
fprintf(stderr, "test 1 0 1 1 failed\n");
|
|
583
|
+
return T_EXIT_FAIL;
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
ret = test(1, 1, 0, 1);
|
|
587
|
+
if (ret) {
|
|
588
|
+
fprintf(stderr, "test 1 1 0 1 failed\n");
|
|
589
|
+
return T_EXIT_FAIL;
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
ret = test(1, 1, 1, 1);
|
|
593
|
+
if (ret) {
|
|
594
|
+
fprintf(stderr, "test 1 1 1 1 failed\n");
|
|
595
|
+
return T_EXIT_FAIL;
|
|
596
|
+
}
|
|
597
|
+
|
|
385
598
|
ret = test_invalid(0);
|
|
386
599
|
if (ret) {
|
|
387
600
|
fprintf(stderr, "test_invalid 0 failed\n");
|
|
@@ -400,5 +613,41 @@ int main(int argc, char *argv[])
|
|
|
400
613
|
return T_EXIT_FAIL;
|
|
401
614
|
}
|
|
402
615
|
|
|
616
|
+
ret = test_inc(0, 0);
|
|
617
|
+
if (ret) {
|
|
618
|
+
fprintf(stderr, "test_inc 0 0 failed\n");
|
|
619
|
+
return T_EXIT_FAIL;
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
ret = test_inc(0, IORING_SETUP_SQPOLL);
|
|
623
|
+
if (ret) {
|
|
624
|
+
fprintf(stderr, "test_inc 0 sqpoll failed\n");
|
|
625
|
+
return T_EXIT_FAIL;
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
ret = test_inc(0, IORING_SETUP_SINGLE_ISSUER | IORING_SETUP_DEFER_TASKRUN);
|
|
629
|
+
if (ret) {
|
|
630
|
+
fprintf(stderr, "test_inc 0 defer failed\n");
|
|
631
|
+
return T_EXIT_FAIL;
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
ret = test_inc(1, 0);
|
|
635
|
+
if (ret) {
|
|
636
|
+
fprintf(stderr, "test_inc 1 0 failed\n");
|
|
637
|
+
return T_EXIT_FAIL;
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
ret = test_inc(1, IORING_SETUP_SQPOLL);
|
|
641
|
+
if (ret) {
|
|
642
|
+
fprintf(stderr, "test_inc 1 sqpoll failed\n");
|
|
643
|
+
return T_EXIT_FAIL;
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
ret = test_inc(1, IORING_SETUP_SINGLE_ISSUER | IORING_SETUP_DEFER_TASKRUN);
|
|
647
|
+
if (ret) {
|
|
648
|
+
fprintf(stderr, "test_inc 1 defer failed\n");
|
|
649
|
+
return T_EXIT_FAIL;
|
|
650
|
+
}
|
|
651
|
+
|
|
403
652
|
return T_EXIT_PASS;
|
|
404
653
|
}
|
|
@@ -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
|
|