[PATCH] Support for hugetlb backed shared memory
authorJens Axboe <jens.axboe@oracle.com>
Tue, 19 Dec 2006 14:18:14 +0000 (15:18 +0100)
committerJens Axboe <jens.axboe@oracle.com>
Tue, 19 Dec 2006 14:18:14 +0000 (15:18 +0100)
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
HOWTO
fio.c
fio.h
init.c
memory.c
os-linux.h
os.h

diff --git a/HOWTO b/HOWTO
index a5caea3db7a6201d74311b50a5d5d56bbbb77311..6ac744cd3d436124f8474ff135c7a842fb92136b 100644 (file)
--- a/HOWTO
+++ b/HOWTO
@@ -357,6 +357,8 @@ mem=str             Fio can use various types of memory as the io unit buffer.
                        shm     Use shared memory as the buffers. Allocated
                                through shmget(2).
 
                        shm     Use shared memory as the buffers. Allocated
                                through shmget(2).
 
+                       shmhuge Same as shm, but use huge pages as backing.
+
                        mmap    Use anonymous memory maps as the buffers.
                                Allocated through mmap(2).
 
                        mmap    Use anonymous memory maps as the buffers.
                                Allocated through mmap(2).
 
diff --git a/fio.c b/fio.c
index 3ffe1e17a601eebc54debbb1f51580a969b56bc1..87136141b0e34770851dbab53a942d9774eb6f48 100644 (file)
--- a/fio.c
+++ b/fio.c
@@ -507,7 +507,12 @@ static int init_io_u(struct thread_data *td)
                max_units = td->iodepth;
 
        max_bs = max(td->max_bs[DDIR_READ], td->max_bs[DDIR_WRITE]);
                max_units = td->iodepth;
 
        max_bs = max(td->max_bs[DDIR_READ], td->max_bs[DDIR_WRITE]);
-       td->orig_buffer_size = max_bs * max_units + MASK;
+       td->orig_buffer_size = max_bs * max_units;
+
+       if (td->mem_type == MEM_SHMHUGE)
+               td->orig_buffer_size = (td->orig_buffer_size + FIO_HUGE_PAGE - 1) & ~FIO_HUGE_PAGE;
+       else
+               td->orig_buffer_size += MASK;
 
        if (allocate_io_mem(td))
                return 1;
 
        if (allocate_io_mem(td))
                return 1;
diff --git a/fio.h b/fio.h
index f0b4e6a1d72630c64f4768fe99da6b64527ef730..c4facfbe995b2f0ed20e88353fb645a528721ec9 100644 (file)
--- a/fio.h
+++ b/fio.h
@@ -123,6 +123,7 @@ struct group_run_stats {
 enum fio_memtype {
        MEM_MALLOC = 0, /* ordinary malloc */
        MEM_SHM,        /* use shared memory segments */
 enum fio_memtype {
        MEM_MALLOC = 0, /* ordinary malloc */
        MEM_SHM,        /* use shared memory segments */
+       MEM_SHMHUGE,    /* use shared memory segments with huge pages */
        MEM_MMAP,       /* use anonynomous mmap */
 };
 
        MEM_MMAP,       /* use anonynomous mmap */
 };
 
diff --git a/init.c b/init.c
index ae960302f70a5695b08854198776a6553f1a609b..bfe698106b3bf02fe529990c19aa204267ef273b 100644 (file)
--- a/init.c
+++ b/init.c
@@ -833,9 +833,17 @@ static int str_mem_cb(void *data, const char *mem)
        } else if (!strncmp(mem, "mmap", 4)) {
                td->mem_type = MEM_MMAP;
                return 0;
        } else if (!strncmp(mem, "mmap", 4)) {
                td->mem_type = MEM_MMAP;
                return 0;
+       } else if (!strncmp(mem, "shmhuge", 7)) {
+#ifdef FIO_HAVE_HUGETLB
+               td->mem_type = MEM_SHMHUGE;
+               return 0;
+#else
+               log_err("fio: shmhuge not available\n");
+               return 1;
+#endif
        }
 
        }
 
-       log_err("fio: mem type: malloc, shm, mmap\n");
+       log_err("fio: mem type: malloc, shm, mmap, shmhuge\n");
        return 1;
 }
 
        return 1;
 }
 
index 39dc250c52ba052800eeea1ed9815282b427a006..a7bf82a88fbafd276be899e769e29348c1682757 100644 (file)
--- a/memory.c
+++ b/memory.c
@@ -61,8 +61,13 @@ int allocate_io_mem(struct thread_data *td)
 {
        if (td->mem_type == MEM_MALLOC)
                td->orig_buffer = malloc(td->orig_buffer_size);
 {
        if (td->mem_type == MEM_MALLOC)
                td->orig_buffer = malloc(td->orig_buffer_size);
-       else if (td->mem_type == MEM_SHM) {
-               td->shm_id = shmget(IPC_PRIVATE, td->orig_buffer_size, IPC_CREAT | 0600);
+       else if (td->mem_type == MEM_SHM || td->mem_type == MEM_SHMHUGE) {
+               int flags = IPC_CREAT | SHM_R | SHM_W;
+
+               if (td->mem_type == MEM_SHMHUGE)
+                       flags |= SHM_HUGETLB;
+
+               td->shm_id = shmget(IPC_PRIVATE, td->orig_buffer_size, flags);
                if (td->shm_id < 0) {
                        td_verror(td, errno);
                        perror("shmget");
                if (td->shm_id < 0) {
                        td_verror(td, errno);
                        perror("shmget");
index 752d17e1e84db3af75726560574aaa20b712a8e1..e456ebcaea22204ffbcbf562377e8f6b6312d16c 100644 (file)
@@ -18,6 +18,7 @@
 #define FIO_HAVE_SPLICE
 #define FIO_HAVE_IOSCHED_SWITCH
 #define FIO_HAVE_ODIRECT
 #define FIO_HAVE_SPLICE
 #define FIO_HAVE_IOSCHED_SWITCH
 #define FIO_HAVE_ODIRECT
+#define FIO_HAVE_HUGETLB
 
 #define OS_MAP_ANON            (MAP_ANONYMOUS)
 
 
 #define OS_MAP_ANON            (MAP_ANONYMOUS)
 
diff --git a/os.h b/os.h
index b44d34c6b5ef07dea4c5c7fe2c05be09c5abbe9e..b5f43e593e6251efb179dc2dd22ca1ecdb59e3e3 100644 (file)
--- a/os.h
+++ b/os.h
 #define OS_O_DIRECT                    O_DIRECT
 #endif
 
 #define OS_O_DIRECT                    O_DIRECT
 #endif
 
+#ifndef FIO_HAVE_HUGETLB
+#define SHM_HUGETLB                    0
+#define FIO_HUGE_PAGE                  0
+#else
+#define FIO_HUGE_PAGE                  (2048 * 1024)
+#endif
+
 #endif
 #endif