| |
| |
| |
| |
| |
| |
| |
| #include <unistd.h> |
| #include <stdio.h> |
| #include <limits.h> |
| #include <stdint.h> |
| #include <stdlib.h> |
| #include <string.h> |
| |
| #define KSM_MAX_KERNEL_PAGES_FILE "/sys/kernel/mm/ksm/max_kernel_pages" |
| #define KSM_RUN_FILE "/sys/kernel/mm/ksm/run" |
| |
| char *program_name; |
| |
| int usage(void) |
| { |
| fprintf(stderr, "Usage: %s {start|stop}\n", program_name); |
| return 1; |
| } |
| |
| int write_value(uint64_t value, char *filename) |
| { |
| FILE *fp; |
| if (!(fp = fopen(filename, "w")) || |
| fprintf(fp, "%llu\n", (unsigned long long) value) == EOF || |
| fflush(fp) == EOF || |
| fclose(fp) == EOF) |
| return 1; |
| |
| return 0; |
| } |
| |
| uint64_t ksm_max_kernel_pages() |
| { |
| char *var = getenv("KSM_MAX_KERNEL_PAGES"); |
| char *endptr; |
| uint64_t value; |
| if (var && *var) { |
| value = strtoll(var, &endptr, 0); |
| if (value < LLONG_MAX && !*endptr) |
| return value; |
| } |
| |
| |
| return sysconf(_SC_PHYS_PAGES) / 2; |
| } |
| |
| int start(void) |
| { |
| if (access(KSM_MAX_KERNEL_PAGES_FILE, R_OK) >= 0) |
| write_value(ksm_max_kernel_pages(), KSM_MAX_KERNEL_PAGES_FILE); |
| return write_value(1, KSM_RUN_FILE); |
| } |
| |
| int stop(void) |
| { |
| return write_value(0, KSM_RUN_FILE); |
| } |
| |
| int main(int argc, char **argv) |
| { |
| program_name = argv[0]; |
| if (argc < 2) { |
| return usage(); |
| } else if (!strcmp(argv[1], "start")) { |
| return start(); |
| } else if (!strcmp(argv[1], "stop")) { |
| return stop(); |
| } else { |
| return usage(); |
| } |
| } |