"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "stress-io-uring.c" between
stress-ng-0.12.09.tar.xz and stress-ng-0.12.10.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.12.09.tar.xz):stress-io-uring.c  (stress-ng-0.12.10.tar.xz)
skipping to change at line 44 skipping to change at line 44
#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_FSYNC) || \ defined(HAVE_IORING_OP_FSYNC) || \
defined(HAVE_IORING_OP_NOP)) defined(HAVE_IORING_OP_NOP) || \
defined(HAVE_IORING_FALLOCATE))
/* /*
* 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 96 skipping to change at line 97
stress_uring_io_cq_ring_t cq_ring; stress_uring_io_cq_ring_t cq_ring;
struct io_uring_sqe *sqes_mmap; struct io_uring_sqe *sqes_mmap;
void *sq_mmap; void *sq_mmap;
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);
/* /*
* 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);
} }
/* /*
skipping to change at line 161 skipping to change at line 164
const stress_args_t *args, const stress_args_t *args,
stress_io_uring_submit_t *submit) stress_io_uring_submit_t *submit)
{ {
stress_uring_io_sq_ring_t *sring = &submit->sq_ring; stress_uring_io_sq_ring_t *sring = &submit->sq_ring;
stress_uring_io_cq_ring_t *cring = &submit->cq_ring; stress_uring_io_cq_ring_t *cring = &submit->cq_ring;
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) {
pr_inf("%s: io-uring not supported by the kernel, skippin
g stressor\n",
args->name);
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 252 skipping to change at line 260
(void)munmap(submit->cq_mmap, submit->cq_size); (void)munmap(submit->cq_mmap, submit->cq_size);
submit->cq_mmap = NULL; submit->cq_mmap = NULL;
} }
if (submit->sq_mmap) { if (submit->sq_mmap) {
(void)munmap(submit->sq_mmap, submit->sq_size); (void)munmap(submit->sq_mmap, submit->sq_size);
submit->sq_mmap = NULL; submit->sq_mmap = NULL;
} }
} }
static int stress_io_uring_submit( /*
* stress_io_uring_complete()
* handle pending I/Os to 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 int opcode) const uint8_t opcode)
{ {
int ret; stress_uring_io_cq_ring_t *cring = &submit->cq_ring;
struct io_uring_cqe *cqe;
unsigned head = *cring->head;
int ret = EXIT_SUCCESS;
ret = shim_io_uring_enter(submit->io_uring_fd, 1, for (;;) {
1, IORING_ENTER_GETEVENTS); shim_mb();
if (ret < 0) {
pr_fail("%s: io_uring_enter failed, opcode=%d, errno=%d (%s)\n", /* Empty? */
args->name, opcode, errno, strerror(errno)); if (head == *cring->tail)
return EXIT_FAILURE; break;
cqe = &cring->cqes[head & *submit->cq_ring.ring_mask];
if ((cqe->res < 0) && (opcode != IORING_OP_FALLOCATE)) {
const int err = abs(cqe->res);
pr_err("%s: completion uring io error, opcode=%d: %d (%s)
\n",
args->name, opcode, err, strerror(err));
ret = EXIT_FAILURE;
}
head++;
} }
return EXIT_SUCCESS;
*cring->head = head;
shim_mb();
if (ret == EXIT_SUCCESS)
inc_counter(args);
return ret;
} }
#if defined(HAVE_IORING_OP_READV) || \
defined(HAVE_IORING_OP_WRITEV)
/* /*
* stress_io_uring_iovec_submit() * stress_io_uring_submit()
* perform a iovec submit over io_uring * submit an io-uring opcode
*/ */
static int stress_io_uring_iovec_submit( static int stress_io_uring_submit(
const stress_args_t *args, const stress_args_t *args,
stress_io_uring_submit_t *submit, stress_io_uring_setup setup_func,
stress_io_uring_file_t *io_uring_file, stress_io_uring_file_t *io_uring_file,
const uint8_t opcode) stress_io_uring_submit_t *submit)
{ {
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;
uint8_t opcode;
next_tail = tail = *sring->tail; next_tail = tail = *sring->tail;
next_tail++; next_tail++;
shim_mb(); shim_mb();
index = tail & *submit->sq_ring.ring_mask; index = tail & *submit->sq_ring.ring_mask;
sqe = &submit->sqes_mmap[index]; sqe = &submit->sqes_mmap[index];
(void)memset(sqe, 0, sizeof(*sqe)); (void)memset(sqe, 0, sizeof(*sqe));
sqe->fd = io_uring_file->fd; setup_func(io_uring_file, sqe);
sqe->flags = 0; opcode = sqe->opcode;
sqe->opcode = opcode;
sqe->addr = (uintptr_t)io_uring_file->iovecs;
sqe->len = io_uring_file->blocks;
sqe->off = 0;
sqe->user_data = (uintptr_t)io_uring_file;
sring->array[index] = index; sring->array[index] = index;
tail = next_tail; tail = next_tail;
if (*sring->tail != tail) { if (*sring->tail != tail) {
*sring->tail = tail; *sring->tail = tail;
shim_mb(); shim_mb();
} }
return stress_io_uring_submit(args, submit, opcode); ret = shim_io_uring_enter(submit->io_uring_fd, 1,
1, IORING_ENTER_GETEVENTS);
if (ret < 0) {
pr_fail("%s: io_uring_enter failed, opcode=%d, errno=%d (%s)\n",
args->name, opcode, errno, strerror(errno));
return EXIT_FAILURE;
}
return stress_io_uring_complete(args, submit, opcode);
}
#if defined(HAVE_IORING_OP_READV)
/*
* stress_io_uring_readv_setup()
* setup readv submit over io_uring
*/
static void stress_io_uring_readv_setup(
stress_io_uring_file_t *io_uring_file,
struct io_uring_sqe *sqe)
{
sqe->fd = io_uring_file->fd;
sqe->flags = 0;
sqe->opcode = IORING_OP_READV;
sqe->addr = (uintptr_t)io_uring_file->iovecs;
sqe->len = io_uring_file->blocks;
sqe->off = stress_mwc8() * io_uring_file->blocks;
sqe->user_data = (uintptr_t)io_uring_file;
} }
#endif #endif
#if defined(HAVE_IORING_OP_FSYNC) #if defined(HAVE_IORING_OP_WRITEV)
/* /*
* stress_io_uring_fsync_submit() * stress_io_uring_writev_setup()
* perform a fsync submit over io_uring * setup writev submit over io_uring
*/ */
static int stress_io_uring_fsync_submit( static void stress_io_uring_writev_setup(
const stress_args_t *args, stress_io_uring_file_t *io_uring_file,
stress_io_uring_submit_t *submit, struct io_uring_sqe *sqe)
stress_io_uring_file_t *io_uring_file)
{ {
stress_uring_io_sq_ring_t *sring = &submit->sq_ring; sqe->fd = io_uring_file->fd;
unsigned index = 0, tail = 0, next_tail = 0; sqe->flags = 0;
struct io_uring_sqe *sqe; sqe->opcode = IORING_OP_WRITEV;
sqe->addr = (uintptr_t)io_uring_file->iovecs;
sqe->len = io_uring_file->blocks;
sqe->off = stress_mwc8() * io_uring_file->blocks;
sqe->user_data = (uintptr_t)io_uring_file;
}
#endif
next_tail = tail = *sring->tail; #if defined(HAVE_IORING_OP_READ)
next_tail++; /*
shim_mb(); * stress_io_uring_read_setup()
index = tail & *submit->sq_ring.ring_mask; * setup read submit over io_uring
sqe = &submit->sqes_mmap[index]; */
(void)memset(sqe, 0, sizeof(*sqe)); static void stress_io_uring_read_setup(
stress_io_uring_file_t *io_uring_file,
struct io_uring_sqe *sqe)
{
sqe->fd = io_uring_file->fd;
sqe->flags = 0;
sqe->opcode = IORING_OP_READ;
sqe->addr = (uintptr_t)io_uring_file->iovecs[0].iov_base;
sqe->len = io_uring_file->iovecs[0].iov_len;
sqe->off = stress_mwc8() * io_uring_file->blocks;
sqe->user_data = (uintptr_t)io_uring_file;
}
#endif
#if defined(HAVE_IORING_OP_WRITE)
/*
* stress_io_uring_write_setup()
* setup write submit over io_uring
*/
static void stress_io_uring_write_setup(
stress_io_uring_file_t *io_uring_file,
struct io_uring_sqe *sqe)
{
sqe->fd = io_uring_file->fd;
sqe->flags = 0;
sqe->opcode = IORING_OP_WRITE;
sqe->addr = (uintptr_t)io_uring_file->iovecs[0].iov_base;
sqe->len = io_uring_file->iovecs[0].iov_len;
sqe->off = stress_mwc8() * io_uring_file->blocks;
sqe->user_data = (uintptr_t)io_uring_file;
}
#endif
#if defined(HAVE_IORING_OP_FSYNC)
/*
* stress_io_uring_fsync_setup()
* setup fsync submit over io_uring
*/
static void stress_io_uring_fsync_setup(
stress_io_uring_file_t *io_uring_file,
struct io_uring_sqe *sqe)
{
sqe->fd = io_uring_file->fd; sqe->fd = io_uring_file->fd;
sqe->opcode = IORING_OP_FSYNC; sqe->opcode = IORING_OP_FSYNC;
sqe->len = 512; sqe->len = 512;
sqe->off = 0; sqe->off = 0;
sqe->user_data = (uintptr_t)io_uring_file; sqe->user_data = (uintptr_t)io_uring_file;
sring->array[index] = index; sqe->ioprio = 0;
tail = next_tail; sqe->buf_index = 0;
sqe->rw_flags = 0;
if (*sring->tail != tail) {
*sring->tail = tail;
shim_mb();
}
return stress_io_uring_submit(args, submit, IORING_OP_FSYNC);
} }
#endif #endif
#if defined(HAVE_IORING_OP_NOP) #if defined(HAVE_IORING_OP_NOP)
/* /*
* stress_io_uring_nop_submit() * stress_io_uring_nop_setup()
* perform a nop submit over io_uring * setup nop submit over io_uring
*/ */
static int stress_io_uring_nop_submit( static void stress_io_uring_nop_setup(
const stress_args_t *args, stress_io_uring_file_t *io_uring_file,
stress_io_uring_submit_t *submit, struct io_uring_sqe *sqe)
stress_io_uring_file_t *io_uring_file)
{ {
stress_uring_io_sq_ring_t *sring = &submit->sq_ring;
unsigned index = 0, tail = 0, next_tail = 0;
struct io_uring_sqe *sqe;
next_tail = tail = *sring->tail;
next_tail++;
shim_mb();
index = tail & *submit->sq_ring.ring_mask;
sqe = &submit->sqes_mmap[index];
(void)memset(sqe, 0, sizeof(*sqe));
(void)io_uring_file; (void)io_uring_file;
sqe->opcode = IORING_OP_NOP; sqe->opcode = IORING_OP_NOP;
sring->array[index] = index;
tail = next_tail;
if (*sring->tail != tail) {
*sring->tail = tail;
shim_mb();
}
return stress_io_uring_submit(args, submit, IORING_OP_NOP);
} }
#endif #endif
#if defined(HAVE_IORING_OP_FALLOCATE)
/* /*
* stress_io_uring_iovec_complete() * stress_io_uring_fallocate_setup()
* handle pending iovec I/Os to complete * setup fallocate submit over io_uring
*/ */
static int stress_io_uring_iovec_complete( static void stress_io_uring_fallocate_setup(
const stress_args_t *args, stress_io_uring_file_t *io_uring_file,
stress_io_uring_submit_t *submit) struct io_uring_sqe *sqe)
{ {
stress_uring_io_cq_ring_t *cring = &submit->cq_ring; sqe->fd = io_uring_file->fd;
struct io_uring_cqe *cqe; sqe->opcode = IORING_OP_FALLOCATE;
unsigned head = *cring->head; sqe->off = 0; /* offset */
int ret = EXIT_SUCCESS; sqe->addr = stress_mwc16(); /* length */
sqe->len = 0; /* mode */
for (;;) { sqe->ioprio = 0;
shim_mb(); sqe->buf_index = 0;
sqe->rw_flags = 0;
/* Empty? */ }
if (head == *cring->tail) #endif
break;
cqe = &cring->cqes[head & *submit->cq_ring.ring_mask]; #if defined(HAVE_IORING_OP_FADVISE)
if (cqe->res < 0) { /*
const int err = abs(cqe->res); * stress_io_uring_fadvise_setup ()
* setup fadvise submit over io_uring
*/
static void stress_io_uring_fadvise_setup(
stress_io_uring_file_t *io_uring_file,
struct io_uring_sqe *sqe)
{
sqe->fd = io_uring_file->fd;
sqe->opcode = IORING_OP_FADVISE;
sqe->off = 0; /* offset */
sqe->len = stress_mwc16(); /* length */
#if defined(POSIX_FADV_NORMAL)
sqe->fadvise_advice = POSIX_FADV_NORMAL;
#else
sqe->fadvise_advice = 0;
#endif
sqe->ioprio = 0;
sqe->buf_index = 0;
sqe->addr = 0;
}
#endif
pr_err("%s: completion uring io error: %d (%s)\n", #if defined(HAVE_IORING_OP_CLOSE)
args->name, err, strerror(err)); /*
ret = EXIT_FAILURE; * stress_io_uring_close_setup ()
} * setup close submit over io_uring
head++; */
} static void stress_io_uring_close_setup(
stress_io_uring_file_t *io_uring_file,
struct io_uring_sqe *sqe)
{
(void)io_uring_file;
*cring->head = head; /* don't worry about bad fd if dup fails */
shim_mb(); sqe->fd = dup(fileno(stdin));
sqe->opcode = IORING_OP_CLOSE;
sqe->ioprio = 0;
sqe->off = 0;
sqe->addr = 0;
sqe->len = 0;
sqe->rw_flags = 0;
sqe->buf_index = 0;
}
#endif
return ret; #if defined(HAVE_IORING_OP_MADVISE)
/*
* stress_io_uring_madvise_setup ()
* setup madvise submit over io_uring
*/
static void stress_io_uring_madvise_setup(
stress_io_uring_file_t *io_uring_file,
struct io_uring_sqe *sqe)
{
sqe->fd = io_uring_file->fd;
sqe->opcode = IORING_OP_MADVISE;
sqe->addr = (uintptr_t)io_uring_file->iovecs[0].iov_base;
sqe->len = 4096;
#if defined(MADV_NORMAL)
sqe->fadvise_advice = MADV_NORMAL;
#else
sqe->fadvise_advice = 0;
#endif
sqe->ioprio = 0;
sqe->buf_index = 0;
sqe->off = 0;
} }
#endif
static const stress_io_uring_setup stress_io_uring_setups[] = {
#if defined(HAVE_IORING_OP_READV)
stress_io_uring_readv_setup,
#endif
#if defined(HAVE_IORING_OP_WRITEV)
stress_io_uring_writev_setup,
#endif
#if defined(HAVE_IORING_OP_READ)
stress_io_uring_read_setup,
#endif
#if defined(HAVE_IORING_OP_WRITE)
stress_io_uring_write_setup,
#endif
#if defined(HAVE_IORING_OP_FSYNC)
stress_io_uring_fsync_setup,
#endif
#if defined(HAVE_IORING_OP_NOP)
stress_io_uring_nop_setup,
#endif
#if defined(HAVE_IORING_OP_FALLOCATE)
stress_io_uring_fallocate_setup,
#endif
#if defined(HAVE_IORING_OP_FADVISE)
stress_io_uring_fadvise_setup,
#endif
#if defined(HAVE_IORING_OP_CLOSE)
stress_io_uring_close_setup,
#endif
#if defined(HAVE_IORING_OP_MADVISE)
stress_io_uring_madvise_setup,
#endif
};
/* /*
* 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;
skipping to change at line 494 skipping to change at line 654
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);
rc = EXIT_SUCCESS; rc = EXIT_SUCCESS;
i = 0; i = 0;
do { do {
#if defined(HAVE_IORING_OP_WRITEV) size_t j;
rc = stress_io_uring_iovec_submit(args, &submit, &io_uring_file,
IORING_OP_WRITEV);
if (rc != EXIT_SUCCESS)
break;
rc = stress_io_uring_iovec_complete(args, &submit);
if (rc != EXIT_SUCCESS)
break;
#endif
if (!keep_stressing(args))
break;
#if defined(HAVE_IORING_OP_READV) for (j = 0; j < SIZEOF_ARRAY(stress_io_uring_setups); j++) {
rc = stress_io_uring_iovec_submit(args, &submit, &io_uring_file, rc = stress_io_uring_submit(args, stress_io_uring_setups[
IORING_OP_READV); j], &io_uring_file, &submit);
if (rc != EXIT_SUCCESS) if ((rc != EXIT_SUCCESS) || !keep_stressing(args))
break; break;
rc = stress_io_uring_iovec_complete(args, &submit); }
if (rc != EXIT_SUCCESS)
break;
#endif
if (!keep_stressing(args))
break;
#if defined(HAVE_IORING_OP_NOP)
rc = stress_io_uring_nop_submit(args, &submit, &io_uring_file);
if (rc != EXIT_SUCCESS)
break;
rc = stress_io_uring_iovec_complete(args, &submit);
if (rc != EXIT_SUCCESS)
break;
#endif
if (!keep_stressing(args))
break;
/* /*
* occasional sync and fdinfo reads * occasional sync and fdinfo reads
*/ */
if (i++ > 1024) { if (i++ > 1024) {
i = 0; i = 0;
#if defined(HAVE_IORING_OP_FSYNC) #if defined(HAVE_IORING_OP_FSYNC)
rc = stress_io_uring_fsync_submit(args, &submit, &io_urin rc = stress_io_uring_submit(args, stress_io_uring_fsync_s
g_file); etup, &io_uring_file, &submit);
if (rc != EXIT_SUCCESS) if ((rc != EXIT_SUCCESS) || !keep_stressing(args))
break;
rc = stress_io_uring_iovec_complete(args, &submit);
if (rc != EXIT_SUCCESS)
break; break;
#endif #endif
(void)stress_read_fdinfo(self, submit.io_uring_fd); (void)stress_read_fdinfo(self, submit.io_uring_fd);
} }
inc_counter(args);
} 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);
(void)stress_temp_dir_rm_args(args); (void)stress_temp_dir_rm_args(args);
return rc; return rc;
 End of changes. 43 change blocks. 
143 lines changed or deleted 276 lines changed or added

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