aboutsummaryrefslogtreecommitdiff
path: root/hugeadm.c
diff options
context:
space:
mode:
authorAvantika Mathur <mathur@linux.vnet.ibm.com>2009-05-26 23:48:21 -0700
committerEric B Munson <ebmunson@us.ibm.com>2009-05-27 10:21:37 +0100
commit018413ee373aa29d4e28b99ee72036f7b7dc50f2 (patch)
treecf38c49f5dd08b28aec7c68ee9cca51fd00461d0 /hugeadm.c
parent86cae04d8263c08bbe3b717225230533e154f8f3 (diff)
downloadlibhugetlbfs-018413ee373aa29d4e28b99ee72036f7b7dc50f2.tar.gz
hugeadm: Add temporary swap on disk for duration of positive pool resize when --add-temp-swap is specified
When growing the hugepage pool with --pool-pages-min, swap space is generally needed to allocate free memory for the resize. For systems that do not have enough or any swap configured, the user can specify the --add-temp-swap flag. When this flag is specified, temporary swap space is created and activated on disk for the duration of a positive resize of the minimum pool size. After the resize is completed, the swap is turned off and swapfile removed. Signed-off-by: Avantika Mathur <mathur@us.ibm.com> Acked-by: Eric B Munson <ebmunson@us.ibm.com> Signed-off-by: Eric B Munson <ebmunson@us.ibm.com>
Diffstat (limited to 'hugeadm.c')
-rw-r--r--hugeadm.c75
1 files changed, 73 insertions, 2 deletions
diff --git a/hugeadm.c b/hugeadm.c
index 1d6b3c9..7c8170d 100644
--- a/hugeadm.c
+++ b/hugeadm.c
@@ -36,6 +36,7 @@
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/mount.h>
+#include <sys/swap.h>
#define _GNU_SOURCE /* for getopt_long */
#include <unistd.h>
@@ -85,6 +86,8 @@ void print_usage()
CONT("Adjust pool 'size' lower bound");
OPTION("--pool-pages-max <size>:[+|-]<count>", "");
CONT("Adjust pool 'size' upper bound");
+ OPTION("--add-temp-swap", "Specified with --pool-pages-min to create");
+ CONT("temporary swap space for the duration of the pool resize");
OPTION("--enable-zone-movable", "Use ZONE_MOVABLE for huge pages");
OPTION("--disable-zone-movable", "Do not use ZONE_MOVABLE for huge pages");
OPTION("--create-mounts", "Creates a mount point for each available");
@@ -119,6 +122,7 @@ void print_usage()
int opt_dry_run = 0;
int opt_hard = 0;
int opt_movable = -1;
+int opt_temp_swap = 0;
int verbose_level = VERBOSITY_DEFAULT;
void setup_environment(char *var, char *val)
@@ -199,6 +203,7 @@ void verbose_expose(void)
#define LONG_MOVABLE_DISABLE (LONG_MOVABLE|'d')
#define LONG_HARD ('h' << 8)
+#define LONG_ADD_TEMP_SWAP ('s' << 8)
#define LONG_PAGE ('P' << 8)
#define LONG_PAGE_SIZES (LONG_PAGE|'s')
@@ -576,14 +581,69 @@ void check_swap()
swap_total = read_meminfo(SWAP_TOTAL);
if (swap_total <= 0) {
WARNING("There is no swap space configured, resizing hugepage pool may fail\n");
+ WARNING("Use --add-temp-swap option to temporarily add swap during the resize\n");
return;
}
swap_sz = read_meminfo(SWAP_FREE);
/* meminfo keeps values in kb, but we use bytes for hpage sizes */
swap_sz *= 1024;
- if (swap_sz <= gethugepagesize())
+ if (swap_sz <= gethugepagesize()) {
WARNING("There is very little swap space free, resizing hugepage pool may fail\n");
+ WARNING("Use --add-temp-swap option to temporarily add swap during the resize\n");
+ }
+}
+
+void add_temp_swap()
+{
+ char path[PATH_MAX];
+ char file[PATH_MAX];
+ char mkswap_cmd[PATH_MAX];
+ FILE *f;
+ char *buf;
+ long swap_size;
+ if (geteuid() != 0) {
+ ERROR("Swap can only be manipulated by root\n");
+ exit(EXIT_FAILURE);
+ }
+
+ snprintf(path, PATH_MAX, "%s/swap/temp", MOUNT_DIR);
+ snprintf(file, PATH_MAX, "%s/swapfile", path);
+
+
+ if (ensure_dir(path, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH, 0, 0))
+ exit(EXIT_FAILURE);
+
+ f = fopen(file, "w");
+ if (!f) {
+ ERROR("Couldn't open %s: %s\n", file, strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+
+ /* swapsize is 5 hugepages (in KB) */
+ swap_size = gethugepagesize() * 5;
+ buf = malloc(swap_size);
+ memset(buf, 0, swap_size);
+ fwrite(buf, sizeof(char), swap_size, f);
+ free(buf);
+ fclose(f);
+
+ snprintf(mkswap_cmd, PATH_MAX, "mkswap %s", file);
+ system(mkswap_cmd);
+
+ INFO("swapon %s\n", file);
+ if (swapon(file, 0))
+ ERROR("swapon on %s failed: %s\n", file, strerror(errno));
+}
+
+void rem_temp_swap() {
+ char file[PATH_MAX];
+
+ snprintf(file, PATH_MAX, "%s/swap/temp/swapfile", MOUNT_DIR);
+ if (swapoff(file))
+ ERROR("swapoff on %s failed: %s\n", file, strerror(errno));
+ remove(file);
+ INFO("swapoff %s\n", file);
}
enum {
@@ -694,8 +754,11 @@ void pool_adjust(char *cmd, unsigned int counter)
else
cnt = -1;
- if (min > min_orig)
+ if (min > min_orig) {
+ if (opt_temp_swap)
+ add_temp_swap();
check_swap();
+ }
INFO("setting HUGEPAGES_TOTAL to %ld\n", min);
set_huge_page_counter(page_size, HUGEPAGES_TOTAL, min);
@@ -718,6 +781,9 @@ void pool_adjust(char *cmd, unsigned int counter)
get_pool_size(page_size, &pools[pos]);
}
+ if ((min > min_orig) && opt_temp_swap)
+ rem_temp_swap();
+
/*
* HUGEPAGES_TOTAL is not guarenteed to check to exactly the figure
* requested should there be insufficient pages. Check the new
@@ -790,6 +856,7 @@ int main(int argc, char** argv)
{"enable-zone-movable", no_argument, NULL, LONG_MOVABLE_ENABLE},
{"disable-zone-movable", no_argument, NULL, LONG_MOVABLE_DISABLE},
{"hard", no_argument, NULL, LONG_HARD},
+ {"add-temp-swap", no_argument, NULL, LONG_ADD_TEMP_SWAP},
{"create-mounts", no_argument, NULL, LONG_CREATE_MOUNTS},
{"create-user-mounts", required_argument, NULL, LONG_CREATE_USER_MOUNTS},
{"create-group-mounts", required_argument, NULL, LONG_CREATE_GROUP_MOUNTS},
@@ -845,6 +912,10 @@ int main(int argc, char** argv)
opt_hard = 1;
continue;
+ case LONG_ADD_TEMP_SWAP:
+ opt_temp_swap = 1;
+ break;
+
case LONG_LIST_ALL_MOUNTS:
opt_list_mounts = 1;
break;