/* SPDX-License-Identifier: MIT */ /* * Description: test that the app can always get a new sqe after having * called io_uring_sqring_wait(). * */ #include #include #include #include "liburing.h" #include "helpers.h" #define NR_IOS 10000 #define INFLIGHT 256 #define FILE_SIZE (256 * 1024 * 1024) static int inflight; static int reap(struct io_uring *ring) { struct io_uring_cqe *cqe; int ret; while (inflight >= INFLIGHT / 2) { ret = io_uring_wait_cqe(ring, &cqe); if (ret < 0) { fprintf(stderr, "wait=%d\n", ret); return 1; } if (cqe->res < 0) { printf("cqe res %d\n", cqe->res); return 1; } io_uring_cqe_seen(ring, cqe); inflight--; } return 0; } int main(int argc, char *argv[]) { struct io_uring_sqe *sqe; struct io_uring ring; int fd = -1, i, iov_off, ret, fret; struct iovec iovs[INFLIGHT]; const char *fname; char buf[256]; loff_t off; if (argc > 1) { fname = argv[1]; } else { srand((unsigned)time(NULL)); snprintf(buf, sizeof(buf), ".sqwait-%u-%u", (unsigned)rand(), (unsigned)getpid()); fname = buf; t_create_file(fname, FILE_SIZE); } fret = T_EXIT_SKIP; ret = io_uring_queue_init(8, &ring, IORING_SETUP_SQPOLL); if (ret < 0) { if (errno == EINVAL || errno == EPERM) goto err; fprintf(stderr, "queue init %d\n", ret); fret = T_EXIT_FAIL; goto err; } fd = open(fname, O_RDONLY | O_DIRECT); if (fd < 0) { if (errno == EACCES || errno == EPERM || errno == EINVAL) return T_EXIT_SKIP; perror("open"); fret = T_EXIT_FAIL; goto err; } for (i = 0; i < INFLIGHT; i++) { if (posix_memalign(&iovs[i].iov_base, 4096, 4096)) goto err; iovs[i].iov_len = 4096; } iov_off = off = 0; for (i = 0; i < NR_IOS; i++) { struct iovec *iov = &iovs[iov_off]; sqe = io_uring_get_sqe(&ring); if (!sqe) { ret = io_uring_sqring_wait(&ring); if (ret < 0) { if (ret == -EINVAL) return T_EXIT_SKIP; fprintf(stderr, "sqwait=%d\n", ret); fret = T_EXIT_FAIL; goto err; } sqe = io_uring_get_sqe(&ring); if (!sqe) { fprintf(stderr, "No sqe post wait\n"); fret = T_EXIT_FAIL; goto err; } } io_uring_prep_read(sqe, fd, iov->iov_base, iov->iov_len, 0); io_uring_submit(&ring); inflight++; iov_off++; if (iov_off == INFLIGHT) iov_off = 0; off += 8192; if (off > FILE_SIZE - 8192) off = 0; if (reap(&ring)) { fret = T_EXIT_FAIL; goto err; } } if (fd != -1) close(fd); if (fname != argv[1]) unlink(fname); io_uring_queue_exit(&ring); return T_EXIT_PASS; err: if (fd != -1) close(fd); if (fname != argv[1]) unlink(fname); return fret; }