[PATCH] Allow mem=mmap to also use a file backing
authorJens Axboe <jens.axboe@oracle.com>
Thu, 21 Dec 2006 08:50:00 +0000 (09:50 +0100)
committerJens Axboe <jens.axboe@oracle.com>
Thu, 21 Dec 2006 08:50:00 +0000 (09:50 +0100)
We have the stuff in place for huge page backed memory, so it's little
extra code to support io buffers inside mmap file backed memory.

Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
HOWTO
fio.h
init.c
memory.c

diff --git a/HOWTO b/HOWTO
index 6a7f58ed92d8fcc9e7a041e22b8a393c5786c425..19182019f7020389e6e5e48391e8f2b6f58b5871 100644 (file)
--- a/HOWTO
+++ b/HOWTO
@@ -359,8 +359,10 @@ mem=str            Fio can use various types of memory as the io unit buffer.
 
                        shmhuge Same as shm, but use huge pages as backing.
 
-                       mmap    Use anonymous memory maps as the buffers.
-                               Allocated through mmap(2).
+                       mmap    Use mmap to allocate buffers. May either be
+                               anonymous memory, or can be file backed if
+                               a filename is given after the option. The
+                               format is mem=mmap:/path/to/file.
 
                        mmaphuge Use a memory mapped huge file as the buffer
                                backing. Append filename after mmaphuge, ala
diff --git a/fio.h b/fio.h
index df36f14e6e895d74d8712e7cdd77ca7f842f304c..d55a1e31c292b9f40dd57f8c1d72308f72e3f665 100644 (file)
--- a/fio.h
+++ b/fio.h
@@ -226,8 +226,8 @@ struct thread_data {
        unsigned long long zone_size;
        unsigned long long zone_skip;
        enum fio_memtype mem_type;
-       char *hugefile;
-       int hugefd;
+       char *mmapfile;
+       int mmapfd;
        unsigned int stonewall;
        unsigned int numjobs;
        unsigned int iodepth;
diff --git a/init.c b/init.c
index 4ca5ee6f8f9e41df678ad56a0569187775eed47f..925da6aea27519abe5bcd78c9e45324fe5c07e00 100644 (file)
--- a/init.c
+++ b/init.c
@@ -832,6 +832,22 @@ static int str_verify_cb(void *data, const char *mem)
        return 1;
 }
 
+/*
+ * Check if mmap/mmaphuge has a :/foo/bar/file at the end. If so, return that.
+ */
+static char *get_mmap_file(const char *str)
+{
+       char *p = strstr(str, ":");
+
+       if (!p)
+               return NULL;
+
+       p++;
+       strip_blank_front(&p);
+       strip_blank_end(p);
+       return strdup(p);
+}
+
 static int str_mem_cb(void *data, const char *mem)
 {
        struct thread_data *td = data;
@@ -841,21 +857,15 @@ static int str_mem_cb(void *data, const char *mem)
                return 0;
        } else if (!strncmp(mem, "mmaphuge", 8)) {
 #ifdef FIO_HAVE_HUGETLB
-               char *hugefile;
-
                /*
                 * mmaphuge must be appended with the actual file
                 */
-               hugefile = strstr(mem, ":");
-               if (!hugefile) {
+               td->mmapfile = get_mmap_file(mem);
+               if (!td->mmapfile) {
                        log_err("fio: mmaphuge:/path/to/file\n");
                        return 1;
                }
 
-               hugefile++;
-               strip_blank_front(&hugefile);
-               strip_blank_end(hugefile);
-               td->hugefile = strdup(hugefile);
                td->mem_type = MEM_MMAPHUGE;
                return 0;
 #else
@@ -863,6 +873,11 @@ static int str_mem_cb(void *data, const char *mem)
                return 1;
 #endif
        } else if (!strncmp(mem, "mmap", 4)) {
+               /*
+                * Check if the user wants file backed memory. It's ok
+                * if there's no file given, we'll just use anon mamp then.
+                */
+               td->mmapfile = get_mmap_file(mem);
                td->mem_type = MEM_MMAP;
                return 0;
        } else if (!strncmp(mem, "shmhuge", 7)) {
index 909baf7d51f19b15f1553679eeb5c7d5f9535e7a..079c0760f0993d22baee775c43561e11d90c7bb1 100644 (file)
--- a/memory.c
+++ b/memory.c
@@ -84,27 +84,29 @@ int allocate_io_mem(struct thread_data *td)
        } else if (td->mem_type == MEM_MMAP || td->mem_type == MEM_MMAPHUGE) {
                int flags = MAP_PRIVATE;
 
-               td->hugefd = 0;
+               td->mmapfd = 0;
 
-               if (td->mem_type == MEM_MMAPHUGE) {
-                       td->hugefd = open(td->hugefile, O_RDWR|O_CREAT, 0644);
+               if (td->mmapfile) {
+                       td->mmapfd = open(td->mmapfile, O_RDWR|O_CREAT, 0644);
 
-                       if (td->hugefd < 0) {
+                       if (td->mmapfd < 0) {
                                td_verror(td, errno);
-                               perror("open huge file");
+                               perror("open mmap file");
                                td->orig_buffer = NULL;
                                return 1;
                        }
                } else
                        flags |= OS_MAP_ANON;
 
-               td->orig_buffer = mmap(NULL, td->orig_buffer_size, PROT_READ | PROT_WRITE, flags, td->hugefd, 0);
+               td->orig_buffer = mmap(NULL, td->orig_buffer_size, PROT_READ | PROT_WRITE, flags, td->mmapfd, 0);
                if (td->orig_buffer == MAP_FAILED) {
                        td_verror(td, errno);
                        perror("mmap");
                        td->orig_buffer = NULL;
-                       if (td->hugefd)
-                               close(td->hugefd);
+                       if (td->mmapfd) {
+                               close(td->mmapfd);
+                               unlink(td->mmapfile);
+                       }
                                
                        return 1;
                }
@@ -124,10 +126,10 @@ void free_io_mem(struct thread_data *td)
                shmctl(td->shm_id, IPC_RMID, &sbuf);
        } else if (td->mem_type == MEM_MMAP || td->mem_type == MEM_MMAPHUGE) {
                munmap(td->orig_buffer, td->orig_buffer_size);
-               if (td->mem_type == MEM_MMAPHUGE) {
-                       close(td->hugefd);
-                       unlink(td->hugefile);
-                       free(td->hugefile);
+               if (td->mmapfile) {
+                       close(td->mmapfd);
+                       unlink(td->mmapfile);
+                       free(td->mmapfile);
                }
        } else
                log_err("Bad memory type %u\n", td->mem_type);