"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "stress-io-uring.c" between
stress-ng-0.13.04.tar.xz and stress-ng-0.13.05.tar.xz

About: stress-ng will stress test a computer system in various selectable ways. It was designed to exercise various physical subsystems of a computer as well as the various operating system kernel interfaces.

stress-io-uring.c  (stress-ng-0.13.04.tar.xz):stress-io-uring.c  (stress-ng-0.13.05.tar.xz)
skipping to change at line 43 skipping to change at line 43
#if defined(HAVE_LINUX_IO_URING_H) && \ #if defined(HAVE_LINUX_IO_URING_H) && \
defined(__NR_io_uring_enter) && \ defined(__NR_io_uring_enter) && \
defined(__NR_io_uring_setup) && \ defined(__NR_io_uring_setup) && \
defined(IORING_OFF_SQ_RING) && \ defined(IORING_OFF_SQ_RING) && \
defined(IORING_OFF_CQ_RING) && \ defined(IORING_OFF_CQ_RING) && \
defined(IORING_OFF_SQES) && \ defined(IORING_OFF_SQES) && \
defined(HAVE_POSIX_MEMALIGN) && \ defined(HAVE_POSIX_MEMALIGN) && \
(defined(HAVE_IORING_OP_WRITEV) || \ (defined(HAVE_IORING_OP_WRITEV) || \
defined(HAVE_IORING_OP_READV) || \ defined(HAVE_IORING_OP_READV) || \
defined(HAVE_IORING_OP_WRITE) || \
defined(HAVE_IORING_OP_READ) || \
defined(HAVE_IORING_OP_FSYNC) || \ defined(HAVE_IORING_OP_FSYNC) || \
defined(HAVE_IORING_OP_NOP) || \ defined(HAVE_IORING_OP_NOP) || \
defined(HAVE_IORING_FALLOCATE)) defined(HAVE_IORING_OP_FALLOCATE) || \
defined(HAVE_IORING_OP_FADVISE) || \
defined(HAVE_IORING_OP_CLOSE) || \
defined(HAVE_IORING_OP_MADVISE) || \
defined(HAVE_IORING_OP_STATX) || \
defined(HAVE_IORING_OP_SYNC_FILE_RANGE))
/* /*
* io uring file info * io uring file info
*/ */
typedef struct { typedef struct {
int fd; /* file descriptor */ int fd; /* file descriptor */
struct iovec *iovecs; /* iovecs array 1 per block to submit */ struct iovec *iovecs; /* iovecs array 1 per block to submit */
size_t iovecs_sz; /* size of iovecs allocation */ size_t iovecs_sz; /* size of iovecs allocation */
off_t file_size; /* size of the file (bytes) */ off_t file_size; /* size of the file (bytes) */
uint32_t blocks; /* number of blocks to action */ uint32_t blocks; /* number of blocks to action */
skipping to change at line 100 skipping to change at line 107
void *cq_mmap; void *cq_mmap;
int io_uring_fd; int io_uring_fd;
size_t sq_size; size_t sq_size;
size_t cq_size; size_t cq_size;
size_t sqes_size; size_t sqes_size;
} stress_io_uring_submit_t; } stress_io_uring_submit_t;
typedef void (*stress_io_uring_setup)(stress_io_uring_file_t *io_uring_file, str uct io_uring_sqe *sqe); typedef void (*stress_io_uring_setup)(stress_io_uring_file_t *io_uring_file, str uct io_uring_sqe *sqe);
/* /*
* opcode to human readable name lookup
*/
typedef struct {
const uint8_t opcode; /* opcode */
const char *name; /* stringified opcode name */
const stress_io_uring_setup setup_func; /* setup function */
} stress_io_uring_setup_info_t;
static const char *stress_io_uring_opcode_name(const uint8_t opcode);
/*
* shim_io_uring_setup * shim_io_uring_setup
* wrapper for io_uring_setup() * wrapper for io_uring_setup()
*/ */
static int shim_io_uring_setup(unsigned entries, struct io_uring_params *p) static int shim_io_uring_setup(unsigned entries, struct io_uring_params *p)
{ {
return (int)syscall(__NR_io_uring_setup, entries, p); return (int)syscall(__NR_io_uring_setup, entries, p);
} }
/* /*
* shim_io_uring_enter * shim_io_uring_enter
skipping to change at line 169 skipping to change at line 187
struct io_uring_params p; struct io_uring_params p;
(void)memset(&p, 0, sizeof(p)); (void)memset(&p, 0, sizeof(p));
submit->io_uring_fd = shim_io_uring_setup(1, &p); submit->io_uring_fd = shim_io_uring_setup(1, &p);
if (submit->io_uring_fd < 0) { if (submit->io_uring_fd < 0) {
if (errno == ENOSYS) { if (errno == ENOSYS) {
pr_inf_skip("%s: io-uring not supported by the kernel, sk ipping stressor\n", pr_inf_skip("%s: io-uring not supported by the kernel, sk ipping stressor\n",
args->name); args->name);
return EXIT_NOT_IMPLEMENTED; return EXIT_NOT_IMPLEMENTED;
} }
pr_err("%s: io_uring_setup failed: errno=%d (%s)\n", pr_err("%s: io_uring_setup failed, errno=%d (%s)\n",
args->name, errno, strerror(errno)); args->name, errno, strerror(errno));
return EXIT_FAILURE; return EXIT_FAILURE;
} }
submit->sq_size = p.sq_off.array + p.sq_entries * sizeof(unsigned); submit->sq_size = p.sq_off.array + p.sq_entries * sizeof(unsigned);
submit->cq_size = p.cq_off.cqes + p.cq_entries * sizeof(struct io_uring_c qe); submit->cq_size = p.cq_off.cqes + p.cq_entries * sizeof(struct io_uring_c qe);
if (p.features & IORING_FEAT_SINGLE_MMAP) { if (p.features & IORING_FEAT_SINGLE_MMAP) {
if (submit->cq_size > submit->sq_size) if (submit->cq_size > submit->sq_size)
submit->sq_size = submit->cq_size; submit->sq_size = submit->cq_size;
submit->cq_size = submit->sq_size; submit->cq_size = submit->sq_size;
} }
skipping to change at line 267 skipping to change at line 285
} }
} }
/* /*
* stress_io_uring_complete() * stress_io_uring_complete()
* handle pending I/Os to complete * handle pending I/Os to complete
*/ */
static inline int stress_io_uring_complete( static inline int stress_io_uring_complete(
const stress_args_t *args, const stress_args_t *args,
stress_io_uring_submit_t *submit, stress_io_uring_submit_t *submit,
const uint8_t opcode) const uint8_t opcode,
bool *supported)
{ {
stress_uring_io_cq_ring_t *cring = &submit->cq_ring; stress_uring_io_cq_ring_t *cring = &submit->cq_ring;
struct io_uring_cqe *cqe; struct io_uring_cqe *cqe;
unsigned head = *cring->head; unsigned head = *cring->head;
int ret = EXIT_SUCCESS; int ret = EXIT_SUCCESS;
for (;;) { for (;;) {
shim_mb(); shim_mb();
/* Empty? */ /* Empty? */
if (head == *cring->tail) if (head == *cring->tail)
break; break;
cqe = &cring->cqes[head & *submit->cq_ring.ring_mask]; cqe = &cring->cqes[head & *submit->cq_ring.ring_mask];
if ((cqe->res < 0) && (opcode != IORING_OP_FALLOCATE)) { if ((cqe->res < 0) && (opcode != IORING_OP_FALLOCATE)) {
const int err = abs(cqe->res); const int err = abs(cqe->res);
pr_err("%s: completion uring io error, opcode=%d: %d (%s) /* Silently ignore EOPNOTSUPP completion errors */
\n", if (errno == EOPNOTSUPP) {
args->name, opcode, err, strerror(err)); *supported = false;
ret = EXIT_FAILURE; } else {
pr_err("%s: completion opcode=%d (%s), error=%d (
%s)\n",
args->name, opcode,
stress_io_uring_opcode_name(opcode),
err, strerror(err));
ret = EXIT_FAILURE;
}
} }
head++; head++;
} }
*cring->head = head; *cring->head = head;
shim_mb(); shim_mb();
if (ret == EXIT_SUCCESS) if (ret == EXIT_SUCCESS)
inc_counter(args); inc_counter(args);
return ret; return ret;
} }
/* /*
* stress_io_uring_submit() * stress_io_uring_submit()
* submit an io-uring opcode * submit an io-uring opcode
*/ */
static int stress_io_uring_submit( static int stress_io_uring_submit(
const stress_args_t *args, const stress_args_t *args,
stress_io_uring_setup setup_func, stress_io_uring_setup setup_func,
stress_io_uring_file_t *io_uring_file, stress_io_uring_file_t *io_uring_file,
stress_io_uring_submit_t *submit) stress_io_uring_submit_t *submit,
bool *supported)
{ {
stress_uring_io_sq_ring_t *sring = &submit->sq_ring; stress_uring_io_sq_ring_t *sring = &submit->sq_ring;
unsigned index = 0, tail = 0, next_tail = 0; unsigned index = 0, tail = 0, next_tail = 0;
struct io_uring_sqe *sqe; struct io_uring_sqe *sqe;
int ret; int ret;
uint8_t opcode; uint8_t opcode;
next_tail = tail = *sring->tail; next_tail = tail = *sring->tail;
next_tail++; next_tail++;
shim_mb(); shim_mb();
skipping to change at line 339 skipping to change at line 366
*sring->tail = tail; *sring->tail = tail;
shim_mb(); shim_mb();
} }
ret = shim_io_uring_enter(submit->io_uring_fd, 1, ret = shim_io_uring_enter(submit->io_uring_fd, 1,
1, IORING_ENTER_GETEVENTS); 1, IORING_ENTER_GETEVENTS);
if (ret < 0) { if (ret < 0) {
/* Silently ignore ENOSPC failures */ /* Silently ignore ENOSPC failures */
if (errno == ENOSPC) if (errno == ENOSPC)
return EXIT_SUCCESS; return EXIT_SUCCESS;
pr_fail("%s: io_uring_enter failed, opcode=%d, errno=%d (%s)\n", pr_fail("%s: io_uring_enter failed, opcode=%d (%s), errno=%d (%s)
args->name, opcode, errno, strerror(errno)); \n",
args->name, opcode,
stress_io_uring_opcode_name(opcode),
errno, strerror(errno));
if (errno == EOPNOTSUPP)
*supported = false;
return EXIT_FAILURE; return EXIT_FAILURE;
} }
return stress_io_uring_complete(args, submit, opcode); return stress_io_uring_complete(args, submit, opcode, supported);
} }
#if defined(HAVE_IORING_OP_READV) #if defined(HAVE_IORING_OP_READV)
/* /*
* stress_io_uring_readv_setup() * stress_io_uring_readv_setup()
* setup readv submit over io_uring * setup readv submit over io_uring
*/ */
static void stress_io_uring_readv_setup( static void stress_io_uring_readv_setup(
stress_io_uring_file_t *io_uring_file, stress_io_uring_file_t *io_uring_file,
struct io_uring_sqe *sqe) struct io_uring_sqe *sqe)
skipping to change at line 549 skipping to change at line 580
sqe->fadvise_advice = MADV_NORMAL; sqe->fadvise_advice = MADV_NORMAL;
#else #else
sqe->fadvise_advice = 0; sqe->fadvise_advice = 0;
#endif #endif
sqe->ioprio = 0; sqe->ioprio = 0;
sqe->buf_index = 0; sqe->buf_index = 0;
sqe->off = 0; sqe->off = 0;
} }
#endif #endif
static const stress_io_uring_setup stress_io_uring_setups[] = { #if defined(HAVE_IORING_OP_STATX)
/*
* stress_io_uring_statx_setup()
* setup statx submit over io_uring
*/
static void stress_io_uring_statx_setup(
stress_io_uring_file_t *io_uring_file,
struct io_uring_sqe *sqe)
{
static const char *pathname = "";
struct shim_statx statxbuf;
sqe->opcode = IORING_OP_STATX;
sqe->fd = io_uring_file->fd;
sqe->addr = (uintptr_t)pathname;
sqe->addr2 = (uintptr_t)&statxbuf;
sqe->statx_flags = AT_EMPTY_PATH;
sqe->ioprio = 0;
sqe->buf_index = 0;
sqe->flags = 0;
}
#endif
#if defined(HAVE_IORING_OP_SYNC_FILE_RANGE)
/*
* stress_io_uring_sync_file_range_setup()
* setup sync_file_range submit over io_uring
*/
static void stress_io_uring_sync_file_range_setup(
stress_io_uring_file_t *io_uring_file,
struct io_uring_sqe *sqe)
{
sqe->opcode = IORING_OP_SYNC_FILE_RANGE;
sqe->fd = io_uring_file->fd;
sqe->off = stress_mwc16() & ~511UL;
sqe->len = stress_mwc32() & ~511UL;
sqe->flags = 0;
sqe->addr = 0;
sqe->ioprio = 0;
sqe->buf_index = 0;
}
#endif
static const stress_io_uring_setup_info_t stress_io_uring_setups[] = {
#if defined(HAVE_IORING_OP_READV) #if defined(HAVE_IORING_OP_READV)
stress_io_uring_readv_setup, { IORING_OP_READV, "IORING_OP_READV", stress_io_uring_readv_set up },
#endif #endif
#if defined(HAVE_IORING_OP_WRITEV) #if defined(HAVE_IORING_OP_WRITEV)
stress_io_uring_writev_setup, { IORING_OP_WRITEV, "IORING_OP_WRITEV", stress_io_uring_writev_se tup },
#endif #endif
#if defined(HAVE_IORING_OP_READ) #if defined(HAVE_IORING_OP_READ)
stress_io_uring_read_setup, { IORING_OP_READ, "IORING_OP_READ", stress_io_uring_read_setu p },
#endif #endif
#if defined(HAVE_IORING_OP_WRITE) #if defined(HAVE_IORING_OP_WRITE)
stress_io_uring_write_setup, { IORING_OP_WRITE, "IORING_OP_WRITE", stress_io_uring_write_set up },
#endif #endif
#if defined(HAVE_IORING_OP_FSYNC) #if defined(HAVE_IORING_OP_FSYNC)
stress_io_uring_fsync_setup, { IORING_OP_FSYNC, "IORING_OP_FSYNC", stress_io_uring_fsync_set up },
#endif #endif
#if defined(HAVE_IORING_OP_NOP) #if defined(HAVE_IORING_OP_NOP)
stress_io_uring_nop_setup, { IORING_OP_NOP, "IORING_OP_NOP", stress_io_uring_nop_setup },
#endif #endif
#if defined(HAVE_IORING_OP_FALLOCATE) #if defined(HAVE_IORING_OP_FALLOCATE)
stress_io_uring_fallocate_setup, { IORING_OP_FALLOCATE, "IORING_OP_FALLOCATE", stress_io_uring_fallocate _setup },
#endif #endif
#if defined(HAVE_IORING_OP_FADVISE) #if defined(HAVE_IORING_OP_FADVISE)
stress_io_uring_fadvise_setup, { IORING_OP_FADVISE, "IORING_OP_FADVISE", stress_io_uring_fadvise_s etup },
#endif #endif
#if defined(HAVE_IORING_OP_CLOSE) #if defined(HAVE_IORING_OP_CLOSE)
stress_io_uring_close_setup, { IORING_OP_CLOSE, "IORING_OP_CLOSE", stress_io_uring_close_set up },
#endif #endif
#if defined(HAVE_IORING_OP_MADVISE) #if defined(HAVE_IORING_OP_MADVISE)
stress_io_uring_madvise_setup, { IORING_OP_MADVISE, "IORING_OP_MADVISE", stress_io_uring_madvise_s
etup },
#endif
#if defined(HAVE_IORING_OP_STATX)
{ IORING_OP_STATX, "IORING_OP_STATX", stress_io_uring_statx_set
up },
#endif
#if defined(HAVE_IORING_OP_SYNC_FILE_RANGE)
{ IORING_OP_SYNC_FILE_RANGE, "IORING_OP_SYNC_FILE_RANGE", stress_io_uring
_sync_file_range_setup },
#endif #endif
}; };
/* /*
* stress_io_uring_opcode_name()
* lookup opcode -> name
*/
static const char *stress_io_uring_opcode_name(const uint8_t opcode)
{
size_t i;
for (i = 0; i < SIZEOF_ARRAY(stress_io_uring_setups); i++) {
if (stress_io_uring_setups[i].opcode == opcode)
return stress_io_uring_setups[i].name;
}
return "unknown";
}
/*
* stress_io_uring * stress_io_uring
* stress asynchronous I/O * stress asynchronous I/O
*/ */
static int stress_io_uring(const stress_args_t *args) static int stress_io_uring(const stress_args_t *args)
{ {
int ret, rc; int ret, rc;
char filename[PATH_MAX]; char filename[PATH_MAX];
stress_io_uring_file_t io_uring_file; stress_io_uring_file_t io_uring_file;
size_t i; size_t i, j;
const size_t blocks = 1024; const size_t blocks = 1024;
const size_t block_size = 512; const size_t block_size = 512;
off_t file_size = (off_t)blocks * block_size; off_t file_size = (off_t)blocks * block_size;
stress_io_uring_submit_t submit; stress_io_uring_submit_t submit;
const pid_t self = getpid(); const pid_t self = getpid();
bool supported[SIZEOF_ARRAY(stress_io_uring_setups)];
(void)memset(&submit, 0, sizeof(submit)); (void)memset(&submit, 0, sizeof(submit));
(void)memset(&io_uring_file, 0, sizeof(io_uring_file)); (void)memset(&io_uring_file, 0, sizeof(io_uring_file));
io_uring_file.file_size = file_size; io_uring_file.file_size = file_size;
io_uring_file.blocks = blocks; io_uring_file.blocks = blocks;
io_uring_file.block_size = block_size; io_uring_file.block_size = block_size;
io_uring_file.iovecs_sz = blocks * sizeof(*io_uring_file.iovecs); io_uring_file.iovecs_sz = blocks * sizeof(*io_uring_file.iovecs);
io_uring_file.iovecs = io_uring_file.iovecs =
mmap(NULL, io_uring_file.iovecs_sz, mmap(NULL, io_uring_file.iovecs_sz,
skipping to change at line 654 skipping to change at line 750
if ((io_uring_file.fd = open(filename, O_CREAT | O_RDWR, S_IRUSR | S_IWUS R)) < 0) { if ((io_uring_file.fd = open(filename, O_CREAT | O_RDWR, S_IRUSR | S_IWUS R)) < 0) {
rc = exit_status(errno); rc = exit_status(errno);
pr_fail("%s: open on %s failed, errno=%d (%s)\n", pr_fail("%s: open on %s failed, errno=%d (%s)\n",
args->name, filename, errno, strerror(errno)); args->name, filename, errno, strerror(errno));
goto clean; goto clean;
} }
(void)unlink(filename); (void)unlink(filename);
stress_set_proc_state(args->name, STRESS_STATE_RUN); stress_set_proc_state(args->name, STRESS_STATE_RUN);
/*
* Assume all opcodes are supported
*/
for (j = 0; j < SIZEOF_ARRAY(stress_io_uring_setups); j++) {
supported[i] = true;
}
rc = EXIT_SUCCESS; rc = EXIT_SUCCESS;
i = 0; i = 0;
do { do {
size_t j;
for (j = 0; j < SIZEOF_ARRAY(stress_io_uring_setups); j++) { for (j = 0; j < SIZEOF_ARRAY(stress_io_uring_setups); j++) {
rc = stress_io_uring_submit(args, stress_io_uring_setups[ if (supported[j]) {
j], &io_uring_file, &submit); rc = stress_io_uring_submit(args,
if ((rc != EXIT_SUCCESS) || !keep_stressing(args)) stress_io_uring_setups[j].setup_func,
break; &io_uring_file, &submit, &supported[j]);
if ((rc != EXIT_SUCCESS) || !keep_stressing(args)
)
break;
}
} }
/*
* occasional sync and fdinfo reads
*/
if (i++ > 1024) { if (i++ > 1024) {
i = 0; i = 0;
#if defined(HAVE_IORING_OP_FSYNC)
rc = stress_io_uring_submit(args, stress_io_uring_fsync_s
etup, &io_uring_file, &submit);
if ((rc != EXIT_SUCCESS) || !keep_stressing(args))
break;
#endif
(void)stress_read_fdinfo(self, submit.io_uring_fd); (void)stress_read_fdinfo(self, submit.io_uring_fd);
} }
} while (keep_stressing(args)); } while (keep_stressing(args));
stress_set_proc_state(args->name, STRESS_STATE_DEINIT); stress_set_proc_state(args->name, STRESS_STATE_DEINIT);
(void)close(io_uring_file.fd); (void)close(io_uring_file.fd);
clean: clean:
stress_set_proc_state(args->name, STRESS_STATE_DEINIT); stress_set_proc_state(args->name, STRESS_STATE_DEINIT);
stress_close_io_uring(&submit); stress_close_io_uring(&submit);
stress_io_uring_unmap_iovecs(&io_uring_file); stress_io_uring_unmap_iovecs(&io_uring_file);
 End of changes. 28 change blocks. 
38 lines changed or deleted 138 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)