memory.c revision 9b33b4794b621b28347e8ca8fb425b918052434c
1/* 2 * Memory helpers 3 */ 4#include <unistd.h> 5#include <sys/shm.h> 6#include <sys/mman.h> 7 8#include "fio.h" 9#include "os.h" 10 11static void *pinned_mem; 12 13void fio_unpin_memory(void) 14{ 15 if (pinned_mem) { 16 if (munlock(pinned_mem, mlock_size) < 0) 17 perror("munlock"); 18 munmap(pinned_mem, mlock_size); 19 pinned_mem = NULL; 20 } 21} 22 23int fio_pin_memory(void) 24{ 25 unsigned long long phys_mem; 26 27 if (!mlock_size) 28 return 0; 29 30 /* 31 * Don't allow mlock of more than real_mem-128MB 32 */ 33 phys_mem = os_phys_mem(); 34 if (phys_mem) { 35 if ((mlock_size + 128 * 1024 * 1024) > phys_mem) { 36 mlock_size = phys_mem - 128 * 1024 * 1024; 37 log_info("fio: limiting mlocked memory to %lluMiB\n", mlock_size >> 20); 38 } 39 } 40 41 pinned_mem = mmap(NULL, mlock_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | OS_MAP_ANON, 0, 0); 42 if (pinned_mem == MAP_FAILED) { 43 perror("malloc locked mem"); 44 pinned_mem = NULL; 45 return 1; 46 } 47 if (mlock(pinned_mem, mlock_size) < 0) { 48 perror("mlock"); 49 munmap(pinned_mem, mlock_size); 50 pinned_mem = NULL; 51 return 1; 52 } 53 54 return 0; 55} 56 57/* 58 * Setup the buffer area we need for io. 59 */ 60int allocate_io_mem(struct thread_data *td) 61{ 62 if (td->o.mem_type == MEM_MALLOC) 63 td->orig_buffer = malloc(td->orig_buffer_size); 64 else if (td->o.mem_type == MEM_SHM || td->o.mem_type == MEM_SHMHUGE) { 65 int flags = IPC_CREAT | SHM_R | SHM_W; 66 67 if (td->o.mem_type == MEM_SHMHUGE) 68 flags |= SHM_HUGETLB; 69 70 td->shm_id = shmget(IPC_PRIVATE, td->orig_buffer_size, flags); 71 if (td->shm_id < 0) { 72 td_verror(td, errno, "shmget"); 73 return 1; 74 } 75 76 td->orig_buffer = shmat(td->shm_id, NULL, 0); 77 if (td->orig_buffer == (void *) -1) { 78 td_verror(td, errno, "shmat"); 79 td->orig_buffer = NULL; 80 return 1; 81 } 82 } else if (td->o.mem_type == MEM_MMAP || 83 td->o.mem_type == MEM_MMAPHUGE) { 84 int flags = MAP_PRIVATE; 85 86 td->mmapfd = 0; 87 88 if (td->mmapfile) { 89 td->mmapfd = open(td->mmapfile, O_RDWR|O_CREAT, 0644); 90 91 if (td->mmapfd < 0) { 92 td_verror(td, errno, "open mmap file"); 93 td->orig_buffer = NULL; 94 return 1; 95 } 96 } else 97 flags |= OS_MAP_ANON; 98 99 td->orig_buffer = mmap(NULL, td->orig_buffer_size, PROT_READ | PROT_WRITE, flags, td->mmapfd, 0); 100 if (td->orig_buffer == MAP_FAILED) { 101 td_verror(td, errno, "mmap"); 102 td->orig_buffer = NULL; 103 if (td->mmapfd) { 104 close(td->mmapfd); 105 unlink(td->mmapfile); 106 } 107 108 return 1; 109 } 110 } 111 112 return 0; 113} 114 115void free_io_mem(struct thread_data *td) 116{ 117 if (td->o.mem_type == MEM_MALLOC) 118 free(td->orig_buffer); 119 else if (td->o.mem_type == MEM_SHM || td->o.mem_type == MEM_SHMHUGE) { 120 struct shmid_ds sbuf; 121 122 shmdt(td->orig_buffer); 123 shmctl(td->shm_id, IPC_RMID, &sbuf); 124 } else if (td->o.mem_type == MEM_MMAP || 125 td->o.mem_type == MEM_MMAPHUGE) { 126 munmap(td->orig_buffer, td->orig_buffer_size); 127 if (td->mmapfile) { 128 close(td->mmapfd); 129 unlink(td->mmapfile); 130 free(td->mmapfile); 131 } 132 } else 133 log_err("Bad memory type %u\n", td->o.mem_type); 134 135 td->orig_buffer = NULL; 136} 137