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.
Files changed (138) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +9 -0
  3. data/README.md +85 -0
  4. data/TODO.md +5 -0
  5. data/examples/echo_server.rb +18 -40
  6. data/examples/inout.rb +19 -0
  7. data/examples/nc.rb +36 -0
  8. data/ext/um/extconf.rb +6 -15
  9. data/ext/um/um.c +245 -53
  10. data/ext/um/um.h +21 -9
  11. data/ext/um/um_class.c +74 -87
  12. data/ext/um/um_const.c +184 -0
  13. data/ext/um/um_op.c +10 -13
  14. data/ext/um/um_utils.c +48 -3
  15. data/lib/uringmachine/version.rb +1 -1
  16. data/lib/uringmachine.rb +12 -0
  17. data/test/helper.rb +8 -0
  18. data/test/test_um.rb +227 -7
  19. data/vendor/liburing/.github/workflows/build.yml +29 -1
  20. data/vendor/liburing/.gitignore +1 -0
  21. data/vendor/liburing/CHANGELOG +15 -0
  22. data/vendor/liburing/CONTRIBUTING.md +165 -0
  23. data/vendor/liburing/configure +32 -0
  24. data/vendor/liburing/examples/Makefile +8 -1
  25. data/vendor/liburing/examples/kdigest.c +405 -0
  26. data/vendor/liburing/examples/proxy.c +75 -8
  27. data/vendor/liburing/liburing.pc.in +1 -1
  28. data/vendor/liburing/src/Makefile +16 -2
  29. data/vendor/liburing/src/include/liburing/io_uring.h +31 -0
  30. data/vendor/liburing/src/include/liburing/sanitize.h +39 -0
  31. data/vendor/liburing/src/include/liburing.h +31 -4
  32. data/vendor/liburing/src/liburing-ffi.map +5 -0
  33. data/vendor/liburing/src/liburing.map +1 -0
  34. data/vendor/liburing/src/queue.c +3 -0
  35. data/vendor/liburing/src/register.c +36 -0
  36. data/vendor/liburing/src/sanitize.c +176 -0
  37. data/vendor/liburing/src/setup.c +1 -1
  38. data/vendor/liburing/test/35fa71a030ca.c +7 -0
  39. data/vendor/liburing/test/500f9fbadef8.c +2 -0
  40. data/vendor/liburing/test/7ad0e4b2f83c.c +0 -25
  41. data/vendor/liburing/test/917257daa0fe.c +7 -0
  42. data/vendor/liburing/test/Makefile +31 -4
  43. data/vendor/liburing/test/a0908ae19763.c +7 -0
  44. data/vendor/liburing/test/a4c0b3decb33.c +7 -0
  45. data/vendor/liburing/test/accept.c +14 -4
  46. data/vendor/liburing/test/b19062a56726.c +7 -0
  47. data/vendor/liburing/test/bind-listen.c +2 -2
  48. data/vendor/liburing/test/buf-ring-nommap.c +10 -3
  49. data/vendor/liburing/test/buf-ring.c +2 -0
  50. data/vendor/liburing/test/coredump.c +7 -0
  51. data/vendor/liburing/test/cq-overflow.c +13 -1
  52. data/vendor/liburing/test/d4ae271dfaae.c +11 -3
  53. data/vendor/liburing/test/defer-taskrun.c +2 -2
  54. data/vendor/liburing/test/defer-tw-timeout.c +4 -1
  55. data/vendor/liburing/test/defer.c +2 -2
  56. data/vendor/liburing/test/double-poll-crash.c +1 -1
  57. data/vendor/liburing/test/eeed8b54e0df.c +2 -0
  58. data/vendor/liburing/test/eventfd.c +0 -1
  59. data/vendor/liburing/test/exit-no-cleanup.c +11 -0
  60. data/vendor/liburing/test/fadvise.c +9 -26
  61. data/vendor/liburing/test/fdinfo.c +9 -1
  62. data/vendor/liburing/test/file-register.c +14 -2
  63. data/vendor/liburing/test/file-update.c +1 -1
  64. data/vendor/liburing/test/file-verify.c +27 -16
  65. data/vendor/liburing/test/files-exit-hang-timeout.c +1 -2
  66. data/vendor/liburing/test/fixed-buf-iter.c +3 -1
  67. data/vendor/liburing/test/fixed-hugepage.c +12 -1
  68. data/vendor/liburing/test/fsnotify.c +1 -0
  69. data/vendor/liburing/test/futex.c +16 -4
  70. data/vendor/liburing/test/helpers.c +47 -0
  71. data/vendor/liburing/test/helpers.h +6 -0
  72. data/vendor/liburing/test/init-mem.c +5 -3
  73. data/vendor/liburing/test/io-cancel.c +0 -24
  74. data/vendor/liburing/test/io_uring_passthrough.c +2 -0
  75. data/vendor/liburing/test/io_uring_register.c +25 -6
  76. data/vendor/liburing/test/iopoll-leak.c +4 -0
  77. data/vendor/liburing/test/iopoll-overflow.c +1 -1
  78. data/vendor/liburing/test/iopoll.c +3 -3
  79. data/vendor/liburing/test/kallsyms.c +203 -0
  80. data/vendor/liburing/test/link-timeout.c +159 -0
  81. data/vendor/liburing/test/linked-defer-close.c +224 -0
  82. data/vendor/liburing/test/madvise.c +12 -25
  83. data/vendor/liburing/test/min-timeout-wait.c +0 -25
  84. data/vendor/liburing/test/min-timeout.c +0 -25
  85. data/vendor/liburing/test/mkdir.c +6 -0
  86. data/vendor/liburing/test/msg-ring.c +8 -2
  87. data/vendor/liburing/test/napi-test.c +15 -2
  88. data/vendor/liburing/test/no-mmap-inval.c +2 -0
  89. data/vendor/liburing/test/nop.c +44 -0
  90. data/vendor/liburing/test/ooo-file-unreg.c +1 -1
  91. data/vendor/liburing/test/open-close.c +40 -0
  92. data/vendor/liburing/test/openat2.c +37 -14
  93. data/vendor/liburing/test/poll-many.c +13 -7
  94. data/vendor/liburing/test/poll-mshot-update.c +17 -10
  95. data/vendor/liburing/test/poll-v-poll.c +6 -3
  96. data/vendor/liburing/test/pollfree.c +148 -0
  97. data/vendor/liburing/test/read-mshot-empty.c +156 -153
  98. data/vendor/liburing/test/read-mshot.c +276 -27
  99. data/vendor/liburing/test/read-write.c +78 -13
  100. data/vendor/liburing/test/recv-msgall-stream.c +3 -0
  101. data/vendor/liburing/test/recv-msgall.c +5 -0
  102. data/vendor/liburing/test/recvsend_bundle-inc.c +680 -0
  103. data/vendor/liburing/test/recvsend_bundle.c +92 -29
  104. data/vendor/liburing/test/reg-fd-only.c +14 -4
  105. data/vendor/liburing/test/regbuf-clone.c +187 -0
  106. data/vendor/liburing/test/regbuf-merge.c +7 -0
  107. data/vendor/liburing/test/register-restrictions.c +86 -85
  108. data/vendor/liburing/test/rename.c +59 -1
  109. data/vendor/liburing/test/ringbuf-read.c +5 -0
  110. data/vendor/liburing/test/ringbuf-status.c +5 -1
  111. data/vendor/liburing/test/runtests.sh +16 -1
  112. data/vendor/liburing/test/send-zerocopy.c +59 -0
  113. data/vendor/liburing/test/short-read.c +1 -0
  114. data/vendor/liburing/test/socket.c +43 -0
  115. data/vendor/liburing/test/splice.c +3 -1
  116. data/vendor/liburing/test/sq-poll-dup.c +1 -1
  117. data/vendor/liburing/test/sq-poll-share.c +2 -0
  118. data/vendor/liburing/test/sqpoll-disable-exit.c +8 -0
  119. data/vendor/liburing/test/sqpoll-exit-hang.c +1 -25
  120. data/vendor/liburing/test/sqpoll-sleep.c +1 -25
  121. data/vendor/liburing/test/statx.c +89 -0
  122. data/vendor/liburing/test/stdout.c +2 -0
  123. data/vendor/liburing/test/submit-and-wait.c +1 -25
  124. data/vendor/liburing/test/submit-reuse.c +4 -26
  125. data/vendor/liburing/test/symlink.c +12 -1
  126. data/vendor/liburing/test/sync-cancel.c +48 -21
  127. data/vendor/liburing/test/thread-exit.c +5 -0
  128. data/vendor/liburing/test/timeout-new.c +1 -26
  129. data/vendor/liburing/test/timeout.c +12 -26
  130. data/vendor/liburing/test/unlink.c +94 -1
  131. data/vendor/liburing/test/uring_cmd_ublk.c +1252 -0
  132. data/vendor/liburing/test/waitid.c +62 -8
  133. data/vendor/liburing/test/wq-aff.c +35 -0
  134. data/vendor/liburing/test/xfail_prep_link_timeout_out_of_scope.c +46 -0
  135. data/vendor/liburing/test/xfail_register_buffers_out_of_scope.c +51 -0
  136. metadata +17 -4
  137. data/examples/event_loop.rb +0 -69
  138. 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 (pipe(fds) < 0) {
160
- perror("pipe");
161
- return 1;
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, 0, &ret);
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
- for (i = 0; i < NR_BUFS; i++) {
175
- unsigned size = i <= 1 ? BUF_SIZE_FIRST : BUF_SIZE;
176
- ptr[i] = malloc(size);
177
- if (!ptr[i])
178
- return 1;
179
- io_uring_buf_ring_add(br, ptr[i], size, i + 1, BR_MASK, i);
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", 0);
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 + 1);
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
- for (i = 0; i < NR_BUFS; i++)
254
- free(ptr[i]);
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 __test_io(const char *file, struct io_uring *ring, int write,
46
- int buffered, int sqthread, int fixed, int nonvec,
47
- int buf_select, int seq, int exp_len)
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