fio: enable cross-thread overlap checking with processes
authorVincent Fu <vincent.fu@wdc.com>
Wed, 17 Oct 2018 16:03:23 +0000 (12:03 -0400)
committerJens Axboe <axboe@kernel.dk>
Fri, 19 Oct 2018 17:09:17 +0000 (11:09 -0600)
Overlap checking with io_submit_mode=offload requires relevant jobs to
access each other's io_u's and io_u_all members. This patch modifies the
fio_memalign and io_u_queue helpers to include an indicator signifying
whether operations should use the shared memory pool. When fio is
carrying out cross-job overlap checking in offload submission mode,
these variables will be allocated from shared memory so that processes
can be used and threads will no longer be required.

Signed-off-by: Jens Axboe <axboe@kernel.dk>
backend.c
io_u_queue.c
io_u_queue.h
lib/memalign.c
lib/memalign.h
t/dedupe.c

index f0a45bc82bee24ab40321d880a7f790f18a4f3e2..1c60138c50b5a957b35378368734b83e906baf92 100644 (file)
--- a/backend.c
+++ b/backend.c
@@ -1189,14 +1189,14 @@ static void cleanup_io_u(struct thread_data *td)
                if (td->io_ops->io_u_free)
                        td->io_ops->io_u_free(td, io_u);
 
-               fio_memfree(io_u, sizeof(*io_u));
+               fio_memfree(io_u, sizeof(*io_u), td_offload_overlap(td));
        }
 
        free_io_mem(td);
 
        io_u_rexit(&td->io_u_requeues);
-       io_u_qexit(&td->io_u_freelist);
-       io_u_qexit(&td->io_u_all);
+       io_u_qexit(&td->io_u_freelist, false);
+       io_u_qexit(&td->io_u_all, td_offload_overlap(td));
 
        free_file_completion_logging(td);
 }
@@ -1211,8 +1211,8 @@ static int init_io_u(struct thread_data *td)
 
        err = 0;
        err += !io_u_rinit(&td->io_u_requeues, td->o.iodepth);
-       err += !io_u_qinit(&td->io_u_freelist, td->o.iodepth);
-       err += !io_u_qinit(&td->io_u_all, td->o.iodepth);
+       err += !io_u_qinit(&td->io_u_freelist, td->o.iodepth, false);
+       err += !io_u_qinit(&td->io_u_all, td->o.iodepth, td_offload_overlap(td));
 
        if (err) {
                log_err("fio: failed setting up IO queues\n");
@@ -1227,7 +1227,7 @@ static int init_io_u(struct thread_data *td)
                if (td->terminate)
                        return 1;
 
-               ptr = fio_memalign(cl_align, sizeof(*io_u));
+               ptr = fio_memalign(cl_align, sizeof(*io_u), td_offload_overlap(td));
                if (!ptr) {
                        log_err("fio: unable to allocate aligned memory\n");
                        break;
index 8cf4c8c3d702234a1cc0b0ba5ffee83ef3a4687a..41f98bc4fa1036496539b50ea84eb6fa51cda390 100644 (file)
@@ -1,9 +1,15 @@
 #include <stdlib.h>
+#include <string.h>
 #include "io_u_queue.h"
+#include "smalloc.h"
 
-bool io_u_qinit(struct io_u_queue *q, unsigned int nr)
+bool io_u_qinit(struct io_u_queue *q, unsigned int nr, bool shared)
 {
-       q->io_us = calloc(nr, sizeof(struct io_u *));
+       if (shared)
+               q->io_us = smalloc(nr * sizeof(struct io_u *));
+       else
+               q->io_us = calloc(nr, sizeof(struct io_u *));
+
        if (!q->io_us)
                return false;
 
@@ -12,9 +18,12 @@ bool io_u_qinit(struct io_u_queue *q, unsigned int nr)
        return true;
 }
 
-void io_u_qexit(struct io_u_queue *q)
+void io_u_qexit(struct io_u_queue *q, bool shared)
 {
-       free(q->io_us);
+       if (shared)
+               sfree(q->io_us);
+       else
+               free(q->io_us);
 }
 
 bool io_u_rinit(struct io_u_ring *ring, unsigned int nr)
index 545e2c41fa5f3db673ceb6e4289d43413a1c6bbf..87de894a525a8e19cfd270fa94c8b1ff4141a7b5 100644 (file)
@@ -45,8 +45,8 @@ static inline int io_u_qempty(const struct io_u_queue *q)
 #define io_u_qiter(q, io_u, i) \
        for (i = 0; i < (q)->nr && (io_u = (q)->io_us[i]); i++)
 
-bool io_u_qinit(struct io_u_queue *q, unsigned int nr);
-void io_u_qexit(struct io_u_queue *q);
+bool io_u_qinit(struct io_u_queue *q, unsigned int nr, bool shared);
+void io_u_qexit(struct io_u_queue *q, bool shared);
 
 struct io_u_ring {
        unsigned int head;
index e774c19c3ebe9980008b38afacc4c29c475ca666..537bb9fb1b92930e862426156f7b7b46c4cee8f9 100644 (file)
@@ -2,6 +2,7 @@
 #include <stdlib.h>
 
 #include "memalign.h"
+#include "smalloc.h"
 
 #define PTR_ALIGN(ptr, mask)   \
        (char *)((uintptr_t)((ptr) + (mask)) & ~(mask))
@@ -10,14 +11,18 @@ struct align_footer {
        unsigned int offset;
 };
 
-void *fio_memalign(size_t alignment, size_t size)
+void *fio_memalign(size_t alignment, size_t size, bool shared)
 {
        struct align_footer *f;
        void *ptr, *ret = NULL;
 
        assert(!(alignment & (alignment - 1)));
 
-       ptr = malloc(size + alignment + sizeof(*f) - 1);
+       if (shared)
+               ptr = smalloc(size + alignment + sizeof(*f) - 1);
+       else
+               ptr = malloc(size + alignment + sizeof(*f) - 1);
+
        if (ptr) {
                ret = PTR_ALIGN(ptr, alignment - 1);
                f = ret + size;
@@ -27,9 +32,12 @@ void *fio_memalign(size_t alignment, size_t size)
        return ret;
 }
 
-void fio_memfree(void *ptr, size_t size)
+void fio_memfree(void *ptr, size_t size, bool shared)
 {
        struct align_footer *f = ptr + size;
 
-       free(ptr - f->offset);
+       if (shared)
+               sfree(ptr - f->offset);
+       else
+               free(ptr - f->offset);
 }
index c2eb17027d8b10041a73fc069a6f15d93c0328a4..d70308705b40872b4b9a920c369dbee09d472a7c 100644 (file)
@@ -2,8 +2,9 @@
 #define FIO_MEMALIGN_H
 
 #include <inttypes.h>
+#include <stdbool.h>
 
-extern void *fio_memalign(size_t alignment, size_t size);
-extern void fio_memfree(void *ptr, size_t size);
+extern void *fio_memalign(size_t alignment, size_t size, bool shared);
+extern void fio_memfree(void *ptr, size_t size, bool shared);
 
 #endif
index 37120e1895063e7270c6e48382ad661f33395fc3..2ef8dc539809884cc0372597ef1a260385ee9165 100644 (file)
@@ -158,8 +158,8 @@ static int col_check(struct chunk *c, struct item *i)
        char *cbuf, *ibuf;
        int ret = 1;
 
-       cbuf = fio_memalign(blocksize, blocksize);
-       ibuf = fio_memalign(blocksize, blocksize);
+       cbuf = fio_memalign(blocksize, blocksize, false);
+       ibuf = fio_memalign(blocksize, blocksize, false);
 
        e = flist_entry(c->extent_list[0].next, struct extent, list);
        if (read_block(file.fd, cbuf, e->offset))
@@ -170,8 +170,8 @@ static int col_check(struct chunk *c, struct item *i)
 
        ret = memcmp(ibuf, cbuf, blocksize);
 out:
-       fio_memfree(cbuf, blocksize);
-       fio_memfree(ibuf, blocksize);
+       fio_memfree(cbuf, blocksize, false);
+       fio_memfree(ibuf, blocksize, false);
        return ret;
 }
 
@@ -309,7 +309,7 @@ static void *thread_fn(void *data)
        struct worker_thread *thread = data;
        void *buf;
 
-       buf = fio_memalign(blocksize, chunk_size);
+       buf = fio_memalign(blocksize, chunk_size, false);
 
        do {
                if (get_work(&thread->cur_offset, &thread->size)) {
@@ -323,7 +323,7 @@ static void *thread_fn(void *data)
        } while (1);
 
        thread->done = 1;
-       fio_memfree(buf, chunk_size);
+       fio_memfree(buf, chunk_size, false);
        return NULL;
 }