From 313cb206ffc6e50c089314d322ebf1c523f37531 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Thu, 21 Dec 2006 09:50:00 +0100 Subject: [PATCH] [PATCH] Allow mem=mmap to also use a file backing 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 --- HOWTO | 6 ++++-- fio.h | 4 ++-- init.c | 31 +++++++++++++++++++++++-------- memory.c | 26 ++++++++++++++------------ 4 files changed, 43 insertions(+), 24 deletions(-) diff --git a/HOWTO b/HOWTO index 6a7f58ed..19182019 100644 --- 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 df36f14e..d55a1e31 100644 --- 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 4ca5ee6f..925da6ae 100644 --- 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)) { diff --git a/memory.c b/memory.c index 909baf7d..079c0760 100644 --- 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); -- 2.25.1