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).
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;
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 */
};
} 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;
}
{
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");
#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_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