uringmachine 0.3 → 0.4

Sign up to get free protection for your applications and to get access to all the features.
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