1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
|
/* SPDX-License-Identifier: MIT */
/*
* Description: test SQPOLL with IORING_SETUP_ATTACH_WQ
*/
#include <errno.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/types.h>
#include <poll.h>
#include <sys/eventfd.h>
#include <sys/resource.h>
#include "helpers.h"
#include "liburing.h"
#define FILE_SIZE (128 * 1024 * 1024)
#define BS 4096
#define BUFFERS 64
#define NR_RINGS 4
static struct iovec *vecs;
static int wait_io(struct io_uring *ring, int nr_ios)
{
struct io_uring_cqe *cqe;
while (nr_ios) {
int ret = io_uring_wait_cqe(ring, &cqe);
if (ret == -EAGAIN) {
continue;
} else if (ret) {
fprintf(stderr, "io_uring_wait_cqe failed %i\n", ret);
return 1;
}
if (cqe->res != BS) {
fprintf(stderr, "Unexpected ret %d\n", cqe->res);
return 1;
}
io_uring_cqe_seen(ring, cqe);
nr_ios--;
}
return 0;
}
static int queue_io(struct io_uring *ring, int fd, int nr_ios)
{
unsigned long off;
int i;
i = 0;
off = 0;
while (nr_ios) {
struct io_uring_sqe *sqe;
sqe = io_uring_get_sqe(ring);
if (!sqe)
break;
io_uring_prep_read(sqe, fd, vecs[i].iov_base, vecs[i].iov_len, off);
nr_ios--;
i++;
off += BS;
}
io_uring_submit(ring);
return i;
}
int main(int argc, char *argv[])
{
struct io_uring rings[NR_RINGS];
int rets[NR_RINGS];
unsigned long ios;
int i, ret, fd;
char *fname;
if (argc > 1) {
fname = argv[1];
} else {
fname = ".basic-rw-poll-share";
t_create_file(fname, FILE_SIZE);
}
vecs = t_create_buffers(BUFFERS, BS);
fd = open(fname, O_RDONLY | O_DIRECT);
if (fd < 0) {
if (errno == EPERM || errno == EACCES || errno == EINVAL)
return T_EXIT_SKIP;
perror("open");
return -1;
}
if (fname != argv[1])
unlink(fname);
for (i = 0; i < NR_RINGS; i++) {
struct io_uring_params p = { };
p.flags = IORING_SETUP_SQPOLL;
if (i) {
p.wq_fd = rings[0].ring_fd;
p.flags |= IORING_SETUP_ATTACH_WQ;
}
ret = io_uring_queue_init_params(BUFFERS, &rings[i], &p);
if (ret) {
fprintf(stderr, "queue_init: %d/%d\n", ret, i);
goto err;
}
/* no sharing for non-fixed either */
if (!(p.features & IORING_FEAT_SQPOLL_NONFIXED)) {
fprintf(stdout, "No SQPOLL sharing, skipping\n");
return 0;
}
}
ios = 0;
while (ios < (FILE_SIZE / BS)) {
for (i = 0; i < NR_RINGS; i++) {
ret = queue_io(&rings[i], fd, BUFFERS);
if (ret < 0)
goto err;
rets[i] = ret;
}
for (i = 0; i < NR_RINGS; i++) {
if (wait_io(&rings[i], rets[i]))
goto err;
}
ios += BUFFERS;
}
return 0;
err:
return 1;
}
|