summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJens Axboe <axboe@kernel.dk>2019-12-26 10:52:51 -0700
committerJens Axboe <axboe@kernel.dk>2019-12-26 10:52:51 -0700
commite1761cb817726ad75489686ce8cf2ae1dc2c18f7 (patch)
tree5c54d2e59fc675b83186a623728bb2b464ac93b3
parentebba24243ae7b1a20a25655a88522e3f8283700b (diff)
downloadliburing-e1761cb817726ad75489686ce8cf2ae1dc2c18f7.tar.gz
liburing-e1761cb817726ad75489686ce8cf2ae1dc2c18f7.tar.bz2
Add basic madvise test case
Signed-off-by: Jens Axboe <axboe@kernel.dk>
-rw-r--r--test/Makefile5
-rw-r--r--test/madvise.c204
2 files changed, 207 insertions, 2 deletions
diff --git a/test/Makefile b/test/Makefile
index c9e0140..2d7aa8e 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -18,7 +18,7 @@ all_targets += poll poll-cancel ring-leak fsync io_uring_setup io_uring_register
poll-link accept-link fixed-link poll-cancel-ton teardowns \
poll-many b5837bd5311d-test accept-test d77a67ed5f27-test \
connect 7ad0e4b2f83c-test submit-reuse fallocate open-close \
- file-update statx accept-reuse poll-v-poll fadvise
+ file-update statx accept-reuse poll-v-poll fadvise madvise
include ../Makefile.quiet
@@ -43,7 +43,8 @@ test_srcs := poll.c poll-cancel.c ring-leak.c fsync.c io_uring_setup.c \
accept-link.c fixed-link.c poll-cancel-ton.c teardowns.c poll-many.c \
b5837bd5311d-test.c accept-test.c d77a67ed5f27-test.c connect.c \
7ad0e4b2f83c-test.c submit-reuse.c fallocate.c open-close.c \
- file-update.c statx.c accept-reuse.c poll-v-poll.c fadvise.c
+ file-update.c statx.c accept-reuse.c poll-v-poll.c fadvise.c \
+ madvise.c
test_objs := $(patsubst %.c,%.ol,$(test_srcs))
diff --git a/test/madvise.c b/test/madvise.c
new file mode 100644
index 0000000..bab0aab
--- /dev/null
+++ b/test/madvise.c
@@ -0,0 +1,204 @@
+/*
+ * Description: basic madvise test
+ */
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/mman.h>
+
+#include "liburing.h"
+
+#define FILE_SIZE (128 * 1024)
+
+#define LOOPS 100
+
+static unsigned long long utime_since(const struct timeval *s,
+ const struct timeval *e)
+{
+ long long sec, usec;
+
+ sec = e->tv_sec - s->tv_sec;
+ usec = (e->tv_usec - s->tv_usec);
+ if (sec > 0 && usec < 0) {
+ sec--;
+ usec += 1000000;
+ }
+
+ sec *= 1000000;
+ return sec + usec;
+}
+
+static unsigned long long utime_since_now(struct timeval *tv)
+{
+ struct timeval end;
+
+ gettimeofday(&end, NULL);
+ return utime_since(tv, &end);
+}
+
+static int create_file(const char *file)
+{
+ ssize_t ret;
+ char *buf;
+ int fd;
+
+ buf = malloc(FILE_SIZE);
+ memset(buf, 0xaa, FILE_SIZE);
+
+ fd = open(file, O_WRONLY | O_CREAT, 0644);
+ if (fd < 0) {
+ perror("open file");
+ return 1;
+ }
+ ret = write(fd, buf, FILE_SIZE);
+ fsync(fd);
+ close(fd);
+ return ret != FILE_SIZE;
+}
+
+static int do_madvise(struct io_uring *ring, void *addr, off_t len, int advice)
+{
+ struct io_uring_sqe *sqe;
+ struct io_uring_cqe *cqe;
+ int ret;
+
+ sqe = io_uring_get_sqe(ring);
+ if (!sqe) {
+ fprintf(stderr, "failed to get sqe\n");
+ return 1;
+ }
+
+ io_uring_prep_madvise(sqe, addr, len, advice);
+ sqe->user_data = advice;
+ ret = io_uring_submit_and_wait(ring, 1);
+ if (ret != 1) {
+ fprintf(stderr, "submit: %d\n", ret);
+ return 1;
+ }
+
+ ret = io_uring_wait_cqe(ring, &cqe);
+ if (ret) {
+ fprintf(stderr, "wait: %d\n", ret);
+ return 1;
+ }
+
+ ret = cqe->res;
+ if (ret == -EINVAL) {
+ fprintf(stdout, "Madvise not supported, skipping\n");
+ exit(0);
+ } else if (ret) {
+ fprintf(stderr, "cqe->res=%d\n", cqe->res);
+ }
+ io_uring_cqe_seen(ring, cqe);
+ return ret;
+}
+
+static long do_copy(int fd, char *buf, void *ptr)
+{
+ struct timeval tv;
+
+ gettimeofday(&tv, NULL);
+ memcpy(buf, ptr, FILE_SIZE);
+ return utime_since_now(&tv);
+}
+
+static int test_madvise(struct io_uring *ring, const char *filename)
+{
+ unsigned long cached_read, uncached_read, cached_read2;
+ int fd, ret;
+ char *buf;
+ void *ptr;
+
+ fd = open(filename, O_RDONLY);
+ if (fd < 0) {
+ perror("open");
+ return 1;
+ }
+
+ buf = malloc(FILE_SIZE);
+
+ ptr = mmap(NULL, FILE_SIZE, PROT_READ, MAP_PRIVATE, fd, 0);
+ if (ptr == MAP_FAILED) {
+ perror("mmap");
+ return 1;
+ }
+
+ cached_read = do_copy(fd, buf, ptr);
+ if (cached_read == -1)
+ return 1;
+
+ cached_read = do_copy(fd, buf, ptr);
+ if (cached_read == -1)
+ return 1;
+
+ ret = do_madvise(ring, ptr, FILE_SIZE, MADV_DONTNEED);
+ if (ret)
+ return 1;
+
+ uncached_read = do_copy(fd, buf, ptr);
+ if (uncached_read == -1)
+ return 1;
+
+ ret = do_madvise(ring, ptr, FILE_SIZE, MADV_DONTNEED);
+ if (ret)
+ return 1;
+
+ ret = do_madvise(ring, ptr, FILE_SIZE, MADV_WILLNEED);
+ if (ret)
+ return 1;
+
+ msync(ptr, FILE_SIZE, MS_SYNC);
+
+ cached_read2 = do_copy(fd, buf, ptr);
+ if (cached_read2 == -1)
+ return 1;
+
+ if (cached_read < uncached_read &&
+ cached_read2 < uncached_read)
+ return 0;
+
+ return 2;
+}
+
+int main(int argc, char *argv[])
+{
+ struct io_uring ring;
+ int ret, i, good, bad;
+
+ if (create_file(".madvise.tmp")) {
+ fprintf(stderr, "file creation failed\n");
+ goto err;
+ }
+ if (io_uring_queue_init(8, &ring, 0)) {
+ fprintf(stderr, "ring creation failed\n");
+ goto err;
+ }
+
+ good = bad = 0;
+ for (i = 0; i < LOOPS; i++) {
+ ret = test_madvise(&ring, ".madvise.tmp");
+ if (ret == 1) {
+ fprintf(stderr, "test_madvise failed\n");
+ goto err;
+ } else if (!ret)
+ good++;
+ else if (ret == 2)
+ bad++;
+ }
+
+ if (bad > good) {
+ fprintf(stderr, "Suspicious timings\n");
+ goto err;
+ }
+ unlink(".madvise.tmp");
+ io_uring_queue_exit(&ring);
+ return 0;
+err:
+ unlink(".madvise.tmp");
+ return 1;
+}