[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.
 
 
                        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
 
                        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;
        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;
        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;
 }
 
        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;
 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
                return 0;
        } else if (!strncmp(mem, "mmaphuge", 8)) {
 #ifdef FIO_HAVE_HUGETLB
-               char *hugefile;
-
                /*
                 * mmaphuge must be appended with the actual file
                 */
                /*
                 * 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;
                }
 
                        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
                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)) {
                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)) {
                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;
 
        } 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);
                                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 = 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->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;
                }
                                
                        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);
                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);
                }
        } else
                log_err("Bad memory type %u\n", td->mem_type);