polyphony 0.98 → 0.99

Sign up to get free protection for your applications and to get access to all the features.
Files changed (182) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +7 -0
  3. data/examples/io/https_server_sni_2.rb +14 -8
  4. data/ext/polyphony/extconf.rb +6 -5
  5. data/ext/polyphony/libev.h +0 -2
  6. data/lib/polyphony/core/sync.rb +53 -0
  7. data/lib/polyphony/extensions/io.rb +37 -14
  8. data/lib/polyphony/extensions/openssl.rb +1 -1
  9. data/lib/polyphony/version.rb +1 -1
  10. data/test/test_io.rb +6 -7
  11. data/test/test_socket.rb +61 -0
  12. data/test/test_sync.rb +42 -1
  13. data/vendor/liburing/.github/workflows/build.yml +7 -16
  14. data/vendor/liburing/.gitignore +5 -0
  15. data/vendor/liburing/CHANGELOG +23 -1
  16. data/vendor/liburing/Makefile +4 -3
  17. data/vendor/liburing/Makefile.common +1 -0
  18. data/vendor/liburing/README +48 -0
  19. data/vendor/liburing/configure +76 -6
  20. data/vendor/liburing/debian/changelog +11 -0
  21. data/vendor/liburing/debian/control +7 -16
  22. data/vendor/liburing/debian/liburing-dev.manpages +3 -6
  23. data/vendor/liburing/debian/liburing2.install +1 -0
  24. data/vendor/liburing/debian/liburing2.symbols +56 -0
  25. data/vendor/liburing/debian/rules +15 -68
  26. data/vendor/liburing/examples/Makefile +4 -0
  27. data/vendor/liburing/examples/io_uring-close-test.c +123 -0
  28. data/vendor/liburing/examples/io_uring-udp.c +1 -1
  29. data/vendor/liburing/examples/send-zerocopy.c +315 -56
  30. data/vendor/liburing/examples/ucontext-cp.c +2 -17
  31. data/vendor/liburing/liburing-ffi.pc.in +12 -0
  32. data/vendor/liburing/liburing.pc.in +1 -1
  33. data/vendor/liburing/liburing.spec +1 -1
  34. data/vendor/liburing/make-debs.sh +3 -3
  35. data/vendor/liburing/man/IO_URING_CHECK_VERSION.3 +1 -0
  36. data/vendor/liburing/man/IO_URING_VERSION_MAJOR.3 +1 -0
  37. data/vendor/liburing/man/IO_URING_VERSION_MINOR.3 +1 -0
  38. data/vendor/liburing/man/io_uring_buf_ring_add.3 +6 -6
  39. data/vendor/liburing/man/io_uring_check_version.3 +72 -0
  40. data/vendor/liburing/man/io_uring_close_ring_fd.3 +43 -0
  41. data/vendor/liburing/man/io_uring_major_version.3 +1 -0
  42. data/vendor/liburing/man/io_uring_minor_version.3 +1 -0
  43. data/vendor/liburing/man/io_uring_prep_accept.3 +1 -1
  44. data/vendor/liburing/man/io_uring_prep_fgetxattr.3 +1 -0
  45. data/vendor/liburing/man/io_uring_prep_fsetxattr.3 +1 -0
  46. data/vendor/liburing/man/io_uring_prep_getxattr.3 +61 -0
  47. data/vendor/liburing/man/io_uring_prep_link_timeout.3 +94 -0
  48. data/vendor/liburing/man/io_uring_prep_msg_ring.3 +22 -2
  49. data/vendor/liburing/man/io_uring_prep_msg_ring_cqe_flags.3 +1 -0
  50. data/vendor/liburing/man/io_uring_prep_poll_add.3 +1 -1
  51. data/vendor/liburing/man/io_uring_prep_provide_buffers.3 +18 -9
  52. data/vendor/liburing/man/io_uring_prep_readv.3 +3 -3
  53. data/vendor/liburing/man/io_uring_prep_readv2.3 +3 -3
  54. data/vendor/liburing/man/io_uring_prep_recv.3 +5 -5
  55. data/vendor/liburing/man/io_uring_prep_recvmsg.3 +4 -4
  56. data/vendor/liburing/man/io_uring_prep_send.3 +9 -0
  57. data/vendor/liburing/man/io_uring_prep_send_set_addr.3 +38 -0
  58. data/vendor/liburing/man/io_uring_prep_send_zc.3 +39 -7
  59. data/vendor/liburing/man/io_uring_prep_send_zc_fixed.3 +1 -0
  60. data/vendor/liburing/man/io_uring_prep_sendmsg.3 +20 -0
  61. data/vendor/liburing/man/io_uring_prep_sendmsg_zc.3 +1 -0
  62. data/vendor/liburing/man/io_uring_prep_setxattr.3 +64 -0
  63. data/vendor/liburing/man/io_uring_prep_splice.3 +40 -0
  64. data/vendor/liburing/man/io_uring_prep_writev.3 +2 -2
  65. data/vendor/liburing/man/io_uring_prep_writev2.3 +2 -2
  66. data/vendor/liburing/man/io_uring_recvmsg_out.3 +13 -9
  67. data/vendor/liburing/man/io_uring_register.2 +15 -9
  68. data/vendor/liburing/man/io_uring_register_buf_ring.3 +4 -4
  69. data/vendor/liburing/man/io_uring_register_buffers.3 +49 -6
  70. data/vendor/liburing/man/io_uring_register_buffers_sparse.3 +1 -0
  71. data/vendor/liburing/man/io_uring_register_buffers_tags.3 +1 -0
  72. data/vendor/liburing/man/io_uring_register_buffers_update_tag.3 +1 -0
  73. data/vendor/liburing/man/io_uring_register_files.3 +60 -5
  74. data/vendor/liburing/man/io_uring_register_files_tags.3 +1 -0
  75. data/vendor/liburing/man/io_uring_register_files_update.3 +1 -0
  76. data/vendor/liburing/man/io_uring_register_files_update_tag.3 +1 -0
  77. data/vendor/liburing/man/io_uring_setup.2 +31 -2
  78. data/vendor/liburing/man/io_uring_wait_cqe_timeout.3 +1 -1
  79. data/vendor/liburing/src/Makefile +25 -3
  80. data/vendor/liburing/src/ffi.c +15 -0
  81. data/vendor/liburing/src/include/liburing/io_uring.h +30 -7
  82. data/vendor/liburing/src/include/liburing.h +190 -148
  83. data/vendor/liburing/src/int_flags.h +1 -0
  84. data/vendor/liburing/src/lib.h +5 -16
  85. data/vendor/liburing/src/liburing-ffi.map +172 -0
  86. data/vendor/liburing/src/liburing.map +11 -0
  87. data/vendor/liburing/src/nolibc.c +9 -2
  88. data/vendor/liburing/src/queue.c +2 -2
  89. data/vendor/liburing/src/register.c +66 -96
  90. data/vendor/liburing/src/setup.c +5 -4
  91. data/vendor/liburing/src/version.c +21 -0
  92. data/vendor/liburing/test/232c93d07b74.c +3 -3
  93. data/vendor/liburing/test/35fa71a030ca.c +3 -3
  94. data/vendor/liburing/test/500f9fbadef8.c +2 -0
  95. data/vendor/liburing/test/917257daa0fe.c +1 -1
  96. data/vendor/liburing/test/Makefile +27 -7
  97. data/vendor/liburing/test/a0908ae19763.c +2 -2
  98. data/vendor/liburing/test/a4c0b3decb33.c +2 -2
  99. data/vendor/liburing/test/accept-link.c +4 -4
  100. data/vendor/liburing/test/accept-reuse.c +5 -7
  101. data/vendor/liburing/test/accept.c +34 -31
  102. data/vendor/liburing/test/b19062a56726.c +1 -1
  103. data/vendor/liburing/test/buf-ring.c +58 -4
  104. data/vendor/liburing/test/ce593a6c480a.c +2 -2
  105. data/vendor/liburing/test/close-opath.c +2 -1
  106. data/vendor/liburing/test/connect.c +8 -0
  107. data/vendor/liburing/test/cq-overflow.c +14 -8
  108. data/vendor/liburing/test/d4ae271dfaae.c +1 -1
  109. data/vendor/liburing/test/defer-taskrun.c +64 -9
  110. data/vendor/liburing/test/defer.c +1 -1
  111. data/vendor/liburing/test/double-poll-crash.c +3 -3
  112. data/vendor/liburing/test/eeed8b54e0df.c +8 -3
  113. data/vendor/liburing/test/eploop.c +74 -0
  114. data/vendor/liburing/test/eventfd-ring.c +1 -1
  115. data/vendor/liburing/test/eventfd.c +1 -1
  116. data/vendor/liburing/test/evloop.c +73 -0
  117. data/vendor/liburing/test/exit-no-cleanup.c +1 -1
  118. data/vendor/liburing/test/fadvise.c +1 -1
  119. data/vendor/liburing/test/fc2a85cb02ef.c +3 -3
  120. data/vendor/liburing/test/fd-pass.c +35 -16
  121. data/vendor/liburing/test/file-register.c +61 -0
  122. data/vendor/liburing/test/file-verify.c +2 -2
  123. data/vendor/liburing/test/files-exit-hang-timeout.c +2 -2
  124. data/vendor/liburing/test/fixed-link.c +1 -1
  125. data/vendor/liburing/test/fsnotify.c +118 -0
  126. data/vendor/liburing/test/hardlink.c +1 -1
  127. data/vendor/liburing/test/helpers.c +54 -2
  128. data/vendor/liburing/test/helpers.h +4 -0
  129. data/vendor/liburing/test/io-cancel.c +3 -1
  130. data/vendor/liburing/test/io_uring_passthrough.c +39 -8
  131. data/vendor/liburing/test/io_uring_setup.c +3 -80
  132. data/vendor/liburing/test/iopoll-overflow.c +118 -0
  133. data/vendor/liburing/test/iopoll.c +90 -4
  134. data/vendor/liburing/test/lfs-openat-write.c +7 -9
  135. data/vendor/liburing/test/lfs-openat.c +6 -8
  136. data/vendor/liburing/test/link_drain.c +31 -5
  137. data/vendor/liburing/test/madvise.c +1 -1
  138. data/vendor/liburing/test/msg-ring-flags.c +192 -0
  139. data/vendor/liburing/test/msg-ring-overflow.c +159 -0
  140. data/vendor/liburing/test/msg-ring.c +173 -13
  141. data/vendor/liburing/test/multicqes_drain.c +22 -19
  142. data/vendor/liburing/test/nvme.h +4 -3
  143. data/vendor/liburing/test/pipe-bug.c +95 -0
  144. data/vendor/liburing/test/poll-link.c +3 -3
  145. data/vendor/liburing/test/poll-many.c +41 -19
  146. data/vendor/liburing/test/poll-mshot-overflow.c +105 -2
  147. data/vendor/liburing/test/poll-race-mshot.c +292 -0
  148. data/vendor/liburing/test/poll-race.c +105 -0
  149. data/vendor/liburing/test/poll.c +244 -26
  150. data/vendor/liburing/test/pollfree.c +5 -5
  151. data/vendor/liburing/test/read-before-exit.c +20 -3
  152. data/vendor/liburing/test/read-write.c +2 -0
  153. data/vendor/liburing/test/recv-multishot.c +96 -3
  154. data/vendor/liburing/test/reg-reg-ring.c +90 -0
  155. data/vendor/liburing/test/rename.c +1 -1
  156. data/vendor/liburing/test/ring-leak.c +0 -1
  157. data/vendor/liburing/test/ring-leak2.c +1 -1
  158. data/vendor/liburing/test/ringbuf-read.c +10 -6
  159. data/vendor/liburing/test/send-zerocopy.c +273 -103
  160. data/vendor/liburing/test/send_recv.c +7 -4
  161. data/vendor/liburing/test/sendmsg_fs_cve.c +2 -2
  162. data/vendor/liburing/test/single-issuer.c +7 -9
  163. data/vendor/liburing/test/skip-cqe.c +3 -4
  164. data/vendor/liburing/test/socket.c +0 -1
  165. data/vendor/liburing/test/sq-poll-dup.c +10 -3
  166. data/vendor/liburing/test/sq-poll-kthread.c +1 -1
  167. data/vendor/liburing/test/sq-poll-share.c +3 -2
  168. data/vendor/liburing/test/sqpoll-cancel-hang.c +17 -6
  169. data/vendor/liburing/test/sqpoll-disable-exit.c +4 -4
  170. data/vendor/liburing/test/symlink.c +2 -1
  171. data/vendor/liburing/test/test.h +2 -1
  172. data/vendor/liburing/test/timeout-new.c +11 -7
  173. data/vendor/liburing/test/timeout.c +1 -2
  174. data/vendor/liburing/test/unlink.c +1 -1
  175. data/vendor/liburing/test/version.c +25 -0
  176. data/vendor/liburing/test/wakeup-hang.c +1 -1
  177. data/vendor/liburing/test/xattr.c +8 -4
  178. metadata +42 -6
  179. data/vendor/liburing/debian/compat +0 -1
  180. data/vendor/liburing/debian/liburing1-udeb.install +0 -1
  181. data/vendor/liburing/debian/liburing1.install +0 -1
  182. data/vendor/liburing/debian/liburing1.symbols +0 -32
@@ -87,6 +87,8 @@ static int __test_io(const char *file, struct io_uring *ring, int write, int sqt
87
87
  }
88
88
  fd = open(file, open_flags);
89
89
  if (fd < 0) {
90
+ if (errno == EINVAL)
91
+ return 0;
90
92
  perror("file open");
91
93
  goto err;
92
94
  }
@@ -201,7 +203,80 @@ err:
201
203
  return 1;
202
204
  }
203
205
 
204
- extern unsigned __io_uring_flush_sq(struct io_uring *ring);
206
+ static void sig_alrm(int sig)
207
+ {
208
+ fprintf(stderr, "Ran out of time for peek test!\n");
209
+ exit(T_EXIT_FAIL);
210
+ }
211
+
212
+ /*
213
+ * if we are polling, io_uring_cqe_peek() always needs to enter the kernel
214
+ */
215
+ static int test_io_uring_cqe_peek(const char *file)
216
+ {
217
+ struct io_uring_cqe *cqe;
218
+ struct io_uring ring;
219
+ struct sigaction act;
220
+ int fd, i, ret = T_EXIT_FAIL;
221
+
222
+ if (no_iopoll)
223
+ return 0;
224
+
225
+ ret = io_uring_queue_init(64, &ring, IORING_SETUP_IOPOLL);
226
+ if (ret) {
227
+ fprintf(stderr, "ring create failed: %d\n", ret);
228
+ return 1;
229
+ }
230
+
231
+ fd = open(file, O_RDONLY | O_DIRECT);
232
+ if (fd < 0) {
233
+ if (errno == EINVAL) {
234
+ io_uring_queue_exit(&ring);
235
+ return T_EXIT_SKIP;
236
+ }
237
+ perror("file open");
238
+ goto err;
239
+ }
240
+
241
+ for (i = 0; i < BUFFERS; i++) {
242
+ struct io_uring_sqe *sqe;
243
+ off_t offset = BS * (rand() % BUFFERS);
244
+
245
+ sqe = io_uring_get_sqe(&ring);
246
+ io_uring_prep_readv(sqe, fd, &vecs[i], 1, offset);
247
+ sqe->user_data = 1;
248
+ }
249
+
250
+ /*
251
+ * Set alarm for 5 seconds, we should be done way before that
252
+ */
253
+ memset(&act, 0, sizeof(act));
254
+ act.sa_handler = sig_alrm;
255
+ sigaction(SIGALRM, &act, NULL);
256
+ alarm(5);
257
+
258
+ ret = io_uring_submit(&ring);
259
+ if (ret != BUFFERS) {
260
+ fprintf(stderr, "submit=%d\n", ret);
261
+ goto err;
262
+ }
263
+
264
+ ret = T_EXIT_PASS;
265
+ i = 0;
266
+ do {
267
+ ret = io_uring_peek_cqe(&ring, &cqe);
268
+ if (ret)
269
+ continue;
270
+ io_uring_cqe_seen(&ring, cqe);
271
+ i++;
272
+ } while (i < BUFFERS);
273
+
274
+ err:
275
+ if (fd != -1)
276
+ close(fd);
277
+ io_uring_queue_exit(&ring);
278
+ return ret;
279
+ }
205
280
 
206
281
  /*
207
282
  * if we are polling io_uring_submit needs to always enter the
@@ -227,6 +302,8 @@ static int test_io_uring_submit_enters(const char *file)
227
302
  open_flags = O_WRONLY | O_DIRECT;
228
303
  fd = open(file, open_flags);
229
304
  if (fd < 0) {
305
+ if (errno == EINVAL)
306
+ return T_EXIT_SKIP;
230
307
  perror("file open");
231
308
  goto err;
232
309
  }
@@ -364,9 +441,18 @@ int main(int argc, char *argv[])
364
441
  }
365
442
 
366
443
  ret = test_io_uring_submit_enters(fname);
367
- if (ret) {
368
- fprintf(stderr, "test_io_uring_submit_enters failed\n");
369
- goto err;
444
+ if (ret == T_EXIT_FAIL) {
445
+ fprintf(stderr, "test_io_uring_submit_enters failed\n");
446
+ goto err;
447
+ }
448
+
449
+ /*
450
+ * Keep this last, it exits on failure
451
+ */
452
+ ret = test_io_uring_cqe_peek(fname);
453
+ if (ret == T_EXIT_FAIL) {
454
+ fprintf(stderr, "test_io_uring_cqe_peek failed\n");
455
+ goto err;
370
456
  }
371
457
 
372
458
  if (fname != argv[1])
@@ -1,9 +1,5 @@
1
1
  /* SPDX-License-Identifier: MIT */
2
2
 
3
- #define _LARGEFILE_SOURCE
4
- #define _FILE_OFFSET_BITS 64
5
-
6
- #include <liburing.h>
7
3
  #include <string.h>
8
4
  #include <stdio.h>
9
5
  #include <stdlib.h>
@@ -14,16 +10,18 @@
14
10
  #include <sys/resource.h>
15
11
  #include <unistd.h>
16
12
 
13
+ #include "liburing.h"
17
14
  #include "helpers.h"
18
15
 
19
16
  static const int RSIZE = 2;
20
- static const int OPEN_FLAGS = O_RDWR | O_CREAT;
17
+ static const int OPEN_FLAGS = O_RDWR | O_CREAT | O_LARGEFILE;
21
18
  static const mode_t OPEN_MODE = S_IRUSR | S_IWUSR;
22
19
 
23
- #define DIE(...) do {\
24
- fprintf(stderr, __VA_ARGS__);\
25
- abort();\
26
- } while(0);
20
+ #define DIE(...) \
21
+ do { \
22
+ fprintf(stderr, __VA_ARGS__); \
23
+ abort(); \
24
+ } while(0)
27
25
 
28
26
  static int do_write(struct io_uring *ring, int fd, off_t offset)
29
27
  {
@@ -1,8 +1,5 @@
1
1
  /* SPDX-License-Identifier: MIT */
2
2
 
3
- #define _LARGEFILE_SOURCE
4
- #define _FILE_OFFSET_BITS 64
5
-
6
3
  #include <string.h>
7
4
  #include <stdio.h>
8
5
  #include <stdlib.h>
@@ -15,13 +12,14 @@
15
12
 
16
13
  #include "liburing.h"
17
14
 
18
- #define DIE(...) do {\
19
- fprintf(stderr, __VA_ARGS__);\
20
- abort();\
21
- } while(0);
15
+ #define DIE(...) \
16
+ do { \
17
+ fprintf(stderr, __VA_ARGS__); \
18
+ abort(); \
19
+ } while(0)
22
20
 
23
21
  static const int RSIZE = 2;
24
- static const int OPEN_FLAGS = O_RDWR | O_CREAT;
22
+ static const int OPEN_FLAGS = O_RDWR | O_CREAT | O_LARGEFILE;
25
23
  static const mode_t OPEN_MODE = S_IRUSR | S_IWUSR;
26
24
 
27
25
  static int open_io_uring(struct io_uring *ring, int dfd, const char *fn)
@@ -96,7 +96,7 @@ err:
96
96
  return 1;
97
97
  }
98
98
 
99
- int test_link_drain_multi(struct io_uring *ring)
99
+ static int test_link_drain_multi(struct io_uring *ring)
100
100
  {
101
101
  struct io_uring_cqe *cqe;
102
102
  struct io_uring_sqe *sqe[9];
@@ -198,15 +198,17 @@ err:
198
198
 
199
199
  }
200
200
 
201
- int main(int argc, char *argv[])
201
+ static int test_drain(bool defer)
202
202
  {
203
203
  struct io_uring ring;
204
204
  int i, ret;
205
+ unsigned int flags = 0;
205
206
 
206
- if (argc > 1)
207
- return 0;
207
+ if (defer)
208
+ flags = IORING_SETUP_SINGLE_ISSUER |
209
+ IORING_SETUP_DEFER_TASKRUN;
208
210
 
209
- ret = io_uring_queue_init(100, &ring, 0);
211
+ ret = io_uring_queue_init(100, &ring, flags);
210
212
  if (ret) {
211
213
  printf("ring setup failed\n");
212
214
  return 1;
@@ -227,3 +229,27 @@ int main(int argc, char *argv[])
227
229
 
228
230
  return ret;
229
231
  }
232
+
233
+ int main(int argc, char *argv[])
234
+ {
235
+ int ret;
236
+
237
+ if (argc > 1)
238
+ return T_EXIT_SKIP;
239
+
240
+ ret = test_drain(false);
241
+ if (ret) {
242
+ fprintf(stderr, "test_drain(false) failed\n");
243
+ return T_EXIT_FAIL;
244
+ }
245
+
246
+ if (t_probe_defer_taskrun()) {
247
+ ret = test_drain(true);
248
+ if (ret) {
249
+ fprintf(stderr, "test_drain(true) failed\n");
250
+ return T_EXIT_FAIL;
251
+ }
252
+ }
253
+
254
+ return T_EXIT_PASS;
255
+ }
@@ -182,7 +182,7 @@ int main(int argc, char *argv[])
182
182
  }
183
183
 
184
184
  /* too hard to reliably test, just ignore */
185
- if (0 && bad > good)
185
+ if ((0) && bad > good)
186
186
  fprintf(stderr, "Suspicious timings (%u > %u)\n", bad, good);
187
187
  if (fname != argv[1])
188
188
  unlink(fname);
@@ -0,0 +1,192 @@
1
+ /* SPDX-License-Identifier: MIT */
2
+ /*
3
+ * Description: test ring messaging with flags command
4
+ *
5
+ */
6
+ #include <errno.h>
7
+ #include <stdio.h>
8
+ #include <unistd.h>
9
+ #include <stdlib.h>
10
+ #include <string.h>
11
+ #include <fcntl.h>
12
+ #include <pthread.h>
13
+
14
+ #include "liburing.h"
15
+ #include "helpers.h"
16
+
17
+ #define CUSTOM_FLAG 0x42
18
+ #define USER_DATA 0x5aa5
19
+ #define LEN 0x20
20
+ #define ID 0x1
21
+
22
+ struct data {
23
+ pthread_barrier_t barrier;
24
+ int fd;
25
+ };
26
+
27
+ static int recv_msg(struct io_uring *ring)
28
+ {
29
+ struct io_uring_cqe *cqe;
30
+ int ret;
31
+
32
+ ret = io_uring_wait_cqe(ring, &cqe);
33
+ if (ret) {
34
+ fprintf(stderr, "wait cqe %d\n", ret);
35
+ return T_EXIT_FAIL;
36
+ }
37
+ if (cqe->user_data != USER_DATA) {
38
+ fprintf(stderr, "user_data %llx\n", (long long) cqe->user_data);
39
+ return T_EXIT_FAIL;
40
+ }
41
+ if (cqe->res != LEN) {
42
+ fprintf(stderr, "len %x\n", cqe->res);
43
+ return T_EXIT_FAIL;
44
+ }
45
+ if (cqe->flags != CUSTOM_FLAG) {
46
+ fprintf(stderr, "flags %x\n", cqe->flags);
47
+ return T_EXIT_FAIL;
48
+ }
49
+
50
+ return T_EXIT_PASS;
51
+ }
52
+
53
+ static int send_msg(struct io_uring *ring, int target_fd)
54
+ {
55
+ struct io_uring_cqe *cqe;
56
+ struct io_uring_sqe *sqe;
57
+ int ret;
58
+
59
+ sqe = io_uring_get_sqe(ring);
60
+ if (!sqe) {
61
+ fprintf(stderr, "get sqe failed\n");
62
+ return T_EXIT_FAIL;
63
+ }
64
+
65
+ io_uring_prep_msg_ring_cqe_flags(sqe, target_fd, LEN, USER_DATA,
66
+ 0, CUSTOM_FLAG);
67
+ sqe->user_data = ID;
68
+
69
+ ret = io_uring_submit(ring);
70
+ if (ret <= 0) {
71
+ if (ret == -EINVAL)
72
+ return T_EXIT_SKIP;
73
+
74
+ fprintf(stderr, "sqe submit failed: %d\n", ret);
75
+ return T_EXIT_FAIL;
76
+ }
77
+
78
+ ret = io_uring_wait_cqe(ring, &cqe);
79
+ if (ret < 0) {
80
+ fprintf(stderr, "wait completion %d\n", ret);
81
+ return T_EXIT_FAIL;
82
+ }
83
+ if (cqe->res != 0) {
84
+ if (cqe->res == -EINVAL)
85
+ return T_EXIT_SKIP;
86
+ fprintf(stderr, "cqe res %d\n", cqe->res);
87
+ return T_EXIT_FAIL;
88
+ }
89
+ if (cqe->user_data != ID) {
90
+ fprintf(stderr, "user_data %llx\n", (long long) cqe->user_data);
91
+ return T_EXIT_FAIL;
92
+ }
93
+
94
+ io_uring_cqe_seen(ring, cqe);
95
+ return T_EXIT_PASS;
96
+ }
97
+
98
+ static void *thread_fn(void *data)
99
+ {
100
+ struct data *d = data;
101
+ struct io_uring ring;
102
+ int ret;
103
+
104
+ ret = io_uring_queue_init(2, &ring, IORING_SETUP_DEFER_TASKRUN | IORING_SETUP_SINGLE_ISSUER);
105
+ if (ret) {
106
+ fprintf(stderr, "ring init failed %d\n", ret);
107
+ pthread_barrier_wait(&d->barrier);
108
+ return NULL;
109
+ }
110
+
111
+ d->fd = ring.ring_fd;
112
+ pthread_barrier_wait(&d->barrier);
113
+
114
+ if (recv_msg(&ring))
115
+ return (void *) 1;
116
+
117
+ return NULL;
118
+ }
119
+
120
+ int main(int argc, char *argv[])
121
+ {
122
+ struct io_uring ring, ring2;
123
+ pthread_t thread;
124
+ struct data d;
125
+ void *ret2;
126
+ int ret, i;
127
+
128
+ if (argc > 1)
129
+ return T_EXIT_SKIP;
130
+
131
+ ret = io_uring_queue_init(2, &ring, 0);
132
+ if (ret) {
133
+ fprintf(stderr, "io_uring_queue_init failed for ring1: %d\n", ret);
134
+ return T_EXIT_FAIL;
135
+ }
136
+
137
+ ret = io_uring_queue_init(2, &ring2, 0);
138
+ if (ret) {
139
+ fprintf(stderr, "io_uring_queue_init failed for ring2: %d\n", ret);
140
+ return T_EXIT_FAIL;
141
+ }
142
+
143
+ ret = send_msg(&ring, ring2.ring_fd);
144
+ if (ret) {
145
+ if (ret != T_EXIT_SKIP)
146
+ fprintf(stderr, "send_msg failed: %d\n", ret);
147
+ return ret;
148
+ }
149
+
150
+ ret = recv_msg(&ring2);
151
+ if (ret) {
152
+ fprintf(stderr, "recv_msg failed: %d\n", ret);
153
+ return ret;
154
+ }
155
+
156
+ for (i = 0; i < 8; i++) {
157
+ ret = send_msg(&ring, ring2.ring_fd);
158
+ if (ret) {
159
+ if (ret != T_EXIT_SKIP)
160
+ fprintf(stderr, "send_msg failed: %d\n", ret);
161
+ return ret;
162
+ }
163
+ }
164
+
165
+ for (i = 0; i < 8; i++) {
166
+ ret = recv_msg(&ring2);
167
+ if (ret) {
168
+ fprintf(stderr, "recv_msg failed: %d\n", ret);
169
+ return ret;
170
+ }
171
+ }
172
+
173
+ pthread_barrier_init(&d.barrier, NULL, 2);
174
+ d.fd = -1;
175
+ pthread_create(&thread, NULL, thread_fn, &d);
176
+ pthread_barrier_wait(&d.barrier);
177
+ if (d.fd == -1)
178
+ return T_EXIT_FAIL;
179
+
180
+ ret = send_msg(&ring, d.fd);
181
+ if (ret) {
182
+ fprintf(stderr, "send msg failed: %d\n", ret);
183
+ return ret;
184
+ }
185
+ pthread_join(thread, &ret2);
186
+ if (ret2) {
187
+ fprintf(stderr, "Remote test failed\n");
188
+ return T_EXIT_FAIL;
189
+ }
190
+
191
+ return T_EXIT_PASS;
192
+ }
@@ -0,0 +1,159 @@
1
+ /* SPDX-License-Identifier: MIT */
2
+ /*
3
+ * Description: test ring messaging command
4
+ *
5
+ */
6
+ #include <errno.h>
7
+ #include <stdio.h>
8
+ #include <unistd.h>
9
+ #include <stdlib.h>
10
+ #include <string.h>
11
+ #include <fcntl.h>
12
+
13
+ #include "liburing.h"
14
+ #include "helpers.h"
15
+
16
+ static int no_msg;
17
+
18
+ static int test(struct io_uring *ring, unsigned dst_flags)
19
+ {
20
+ struct io_uring_params p = { };
21
+ struct io_uring_cqe *cqe;
22
+ struct io_uring_sqe *sqe;
23
+ struct io_uring dst;
24
+ int ret, i, err_ret = T_EXIT_FAIL;
25
+
26
+ p.flags = dst_flags | IORING_SETUP_CQSIZE;
27
+ p.cq_entries = 4;
28
+ ret = io_uring_queue_init_params(4, &dst, &p);
29
+ if (ret) {
30
+ fprintf(stderr, "Destination ring create failed %d\n", ret);
31
+ return T_EXIT_FAIL;
32
+ }
33
+
34
+ for (i = 0; i < 8; i++) {
35
+ sqe = io_uring_get_sqe(ring);
36
+ if (!sqe) {
37
+ fprintf(stderr, "get sqe failed\n");
38
+ goto err;
39
+ }
40
+
41
+ io_uring_prep_msg_ring(sqe, dst.ring_fd, 0x10, 0x1234, 0);
42
+ sqe->user_data = i + 1;
43
+ }
44
+
45
+ ret = io_uring_submit(ring);
46
+ if (ret != 8) {
47
+ /*
48
+ * Likely an old kernel that doesn't support the opcode,
49
+ * just skip the test.
50
+ */
51
+ if (ret == 1) {
52
+ err_ret = T_EXIT_SKIP;
53
+ no_msg = 1;
54
+ goto err;
55
+ }
56
+ fprintf(stderr, "sqe submit failed: %d\n", ret);
57
+ goto err;
58
+ }
59
+
60
+ for (i = 0; i < 8; i++) {
61
+ ret = io_uring_wait_cqe(ring, &cqe);
62
+ if (ret < 0) {
63
+ fprintf(stderr, "wait completion %d\n", ret);
64
+ goto err;
65
+ }
66
+ switch (cqe->user_data) {
67
+ case 1 ... 8:
68
+ if (cqe->res == -EINVAL || cqe->res == -EOPNOTSUPP) {
69
+ no_msg = 1;
70
+ goto out;
71
+ }
72
+ if (cqe->res != 0) {
73
+ fprintf(stderr, "cqe res %d\n", cqe->res);
74
+ goto err;
75
+ }
76
+ break;
77
+ case 0x1234:
78
+ if (cqe->res != 0x10) {
79
+ fprintf(stderr, "invalid len %x\n", cqe->res);
80
+ goto err;
81
+ }
82
+ break;
83
+ default:
84
+ fprintf(stderr, "Invalid user_data\n");
85
+ goto err;
86
+ }
87
+ io_uring_cqe_seen(ring, cqe);
88
+ }
89
+
90
+ for (i = 0; i < 8; i++) {
91
+ ret = io_uring_wait_cqe(&dst, &cqe);
92
+ if (ret < 0) {
93
+ fprintf(stderr, "wait completion %d\n", ret);
94
+ goto err;
95
+ }
96
+ switch (cqe->user_data) {
97
+ case 0x1234:
98
+ if (cqe->res != 0x10) {
99
+ fprintf(stderr, "invalid len %x\n", cqe->res);
100
+ goto err;
101
+ }
102
+ break;
103
+ default:
104
+ fprintf(stderr, "Invalid user_data\n");
105
+ goto err;
106
+ }
107
+ io_uring_cqe_seen(&dst, cqe);
108
+ }
109
+
110
+ out:
111
+ io_uring_queue_exit(&dst);
112
+ return no_msg ? T_EXIT_SKIP : T_EXIT_PASS;
113
+ err:
114
+ io_uring_queue_exit(&dst);
115
+ return err_ret;
116
+ }
117
+
118
+ int main(int argc, char *argv[])
119
+ {
120
+ struct io_uring src;
121
+ int ret;
122
+
123
+ if (argc > 1)
124
+ return T_EXIT_SKIP;
125
+
126
+ ret = io_uring_queue_init(8, &src, 0);
127
+ if (ret) {
128
+ fprintf(stderr, "ring setup failed: %d\n", ret);
129
+ return T_EXIT_FAIL;
130
+ }
131
+
132
+ ret = test(&src, 0);
133
+ if (ret && !no_msg) {
134
+ fprintf(stderr, "test failed\n");
135
+ return ret;
136
+ }
137
+ if (no_msg)
138
+ return T_EXIT_SKIP;
139
+
140
+ ret = test(&src, IORING_SETUP_IOPOLL);
141
+ if (ret) {
142
+ fprintf(stderr, "test IOPOLL failed\n");
143
+ return ret;
144
+ }
145
+
146
+ ret = test(&src, IORING_SETUP_DEFER_TASKRUN | IORING_SETUP_SINGLE_ISSUER);
147
+ if (ret) {
148
+ fprintf(stderr, "test defer failed\n");
149
+ return ret;
150
+ }
151
+
152
+ ret = test(&src, IORING_SETUP_DEFER_TASKRUN | IORING_SETUP_SINGLE_ISSUER | IORING_SETUP_IOPOLL);
153
+ if (ret) {
154
+ fprintf(stderr, "test defer IOPOLL failed\n");
155
+ return ret;
156
+ }
157
+
158
+ return T_EXIT_PASS;
159
+ }