summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Holzheu <holzheu@linux.vnet.ibm.com>2015-09-04 14:11:59 +0200
committerSimon Horman <horms@verge.net.au>2015-09-07 15:43:52 +0900
commit7ab842d8a004f6cd75a9d7b3528e4a70819ce4ef (patch)
treedf78ae7aa062cd131da46e4b6ed5f0cc2be0d701
parenta304e2d82a8c3e4f66d0707118bc53704b5d9c59 (diff)
kexec: use mmap instead of read for slurp_file()
The slurp_fd() function allocates memory and uses the read() system call. This results in double memory consumption for image and initrd: 1) Memory allocated in user space by the kexec tool 2) Memory allocated in kernel by the kexec() system call Therefore use mmap() for non-character devices to reduce the runtime memory consumption of the kexec tool. The following use case illustrates the usefulness of this patch a bit more: 1) Boot a 4 GB Linux system 2) Read kernel and 1,5 GB ramdisk from external source into local tmpfs (ram) 3) kexec the kernel and ramdisk Without this patch for the kexec runtime we need: 1,5 GB (tmpfs) + 1,5 GB (kexec malloc) + 1,5 GB (kernel memory) = 4,5 GB Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com> Signed-off-by: Simon Horman <horms@verge.net.au>
-rw-r--r--kexec/kexec.c8
1 files changed, 5 insertions, 3 deletions
diff --git a/kexec/kexec.c b/kexec/kexec.c
index b9f1816..ff024f3 100644
--- a/kexec/kexec.c
+++ b/kexec/kexec.c
@@ -26,6 +26,7 @@
#include <stdlib.h>
#include <errno.h>
#include <limits.h>
+#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/reboot.h>
@@ -552,11 +553,12 @@ char *slurp_file(const char *filename, off_t *r_size)
if (err < 0)
die("Can not seek to the begin of file %s: %s\n",
filename, strerror(errno));
+ buf = slurp_fd(fd, filename, size, &nread);
} else {
- size = stats.st_size;
+ size = nread = stats.st_size;
+ buf = mmap(NULL, size,
+ PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
}
-
- buf = slurp_fd(fd, filename, size, &nread);
if (!buf)
die("Cannot read %s", filename);