| 230 | } |
| 231 | |
| 232 | static int __test_io(const char *file, struct io_uring *ring, int write, |
| 233 | int buffered, int sqthread, int fixed, int nonvec, |
| 234 | int buf_select, int seq, int exp_len, bool worker_offload) |
| 235 | { |
| 236 | int ret; |
| 237 | |
| 238 | ret = _test_io(file, ring, write, buffered, sqthread, fixed, nonvec, |
| 239 | buf_select, seq, exp_len, worker_offload); |
| 240 | if (ret) |
| 241 | return ret; |
| 242 | |
| 243 | if (fixed) { |
| 244 | struct io_uring ring2; |
| 245 | int ring_flags = 0; |
| 246 | |
| 247 | if (no_buf_copy) |
| 248 | return 0; |
| 249 | if (sqthread) |
| 250 | ring_flags = IORING_SETUP_SQPOLL; |
| 251 | ret = t_create_ring(64, &ring2, ring_flags); |
| 252 | if (ret == T_SETUP_SKIP) |
| 253 | return 0; |
| 254 | if (ret != T_SETUP_OK) { |
| 255 | fprintf(stderr, "ring create failed: %d\n", ret); |
| 256 | return 1; |
| 257 | } |
| 258 | |
| 259 | ret = io_uring_clone_buffers(&ring2, ring); |
| 260 | if (ret) { |
| 261 | if (ret == -EINVAL) { |
| 262 | no_buf_copy = 1; |
| 263 | io_uring_queue_exit(&ring2); |
| 264 | return 0; |
| 265 | } |
| 266 | fprintf(stderr, "copy buffers: %d\n", ret); |
| 267 | return ret; |
| 268 | } |
| 269 | ret = _test_io(file, &ring2, write, buffered, sqthread, 2, |
| 270 | nonvec, buf_select, seq, exp_len, worker_offload); |
| 271 | if (ret) |
| 272 | return ret; |
| 273 | |
| 274 | ret = io_uring_unregister_buffers(ring); |
| 275 | if (ret) { |
| 276 | fprintf(stderr, "buffer unreg failed: %d\n", ret); |
| 277 | return ret; |
| 278 | } |
| 279 | ret = io_uring_unregister_buffers(&ring2); |
| 280 | if (ret) { |
| 281 | fprintf(stderr, "buffer copy unreg failed: %d\n", ret); |
| 282 | return ret; |
| 283 | } |
| 284 | io_uring_queue_exit(&ring2); |
| 285 | } |
| 286 | |
| 287 | return ret; |
| 288 | } |
| 289 | |