[PATCH] Don't allow mlock of more than real_mem-128MiB
diff --git a/fio.c b/fio.c
index f98cd5b..e48a060 100644
--- a/fio.c
+++ b/fio.c
@@ -2231,32 +2231,67 @@
}
}
+static void fio_unpin_memory(void *pinned)
+{
+ if (pinned) {
+ if (munlock(pinned, mlock_size) < 0)
+ perror("munlock");
+ munmap(pinned, mlock_size);
+ }
+}
+
+static void *fio_pin_memory(void)
+{
+ long pagesize, pages;
+ void *ptr;
+
+ if (!mlock_size)
+ return NULL;
+
+ /*
+ * Don't allow mlock of more than real_mem-128MB
+ */
+ pagesize = sysconf(_SC_PAGESIZE);
+ pages = sysconf(_SC_PHYS_PAGES);
+ if (pages != -1 && pagesize != -1) {
+ unsigned long long real_mem = pages * pagesize;
+
+ if ((mlock_size + 128 * 1024 * 1024) > real_mem) {
+ mlock_size = real_mem - 128 * 1024 * 1024;
+ printf("fio: limiting mlocked memory to %lluMiB\n",
+ mlock_size >> 20);
+ }
+ }
+
+ ptr = mmap(NULL, mlock_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | OS_MAP_ANON, 0, 0);
+ if (!ptr) {
+ perror("malloc locked mem");
+ return NULL;
+ }
+ if (mlock(ptr, mlock_size) < 0) {
+ munmap(ptr, mlock_size);
+ perror("mlock");
+ return NULL;
+ }
+
+ return ptr;
+}
+
static void run_threads(void)
{
struct thread_data *td;
unsigned long spent;
int i, todo, nr_running, m_rate, t_rate, nr_started;
- void *mlocked_mem = NULL;
+ void *mlocked_mem;
+
+ mlocked_mem = fio_pin_memory();
printf("Starting %d thread%s\n", thread_number, thread_number > 1 ? "s" : "");
+ fflush(stdout);
signal(SIGINT, sig_handler);
signal(SIGALRM, sig_handler);
- if (mlock_size) {
- mlocked_mem = mmap(NULL, mlock_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | OS_MAP_ANON, 0, 0);
- if (!mlocked_mem) {
- perror("mmap locked mem");
- return;
- }
- if (mlock(mlocked_mem, mlock_size) < 0) {
- munmap(mlocked_mem, mlock_size);
- return;
- }
- }
-
- fflush(stdout);
-
todo = thread_number;
nr_running = 0;
nr_started = 0;
@@ -2363,12 +2398,7 @@
}
update_io_ticks();
-
- if (mlocked_mem) {
- if (munlock(mlocked_mem, mlock_size) < 0)
- perror("munlock");
- munmap(mlocked_mem, mlock_size);
- }
+ fio_unpin_memory(mlocked_mem);
}
static void show_group_stats(struct group_run_stats *rs, int id)