/* * Copyright (C) 2013-2017 Red Hat, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See * the GNU General Public License for more details. */ /* * The case is designed to test new sysfs boolean knob * /sys/kernel/mm/ksm/merge_across_nodes, which was introduced by * commit 90bd6fd31c8097ee (ksm: allow trees per NUMA node). * when merge_across_nodes is set to zero only pages from the same * node are merged, otherwise pages from all nodes can be merged * together. */ #include "config.h" #include #include #include #include #include #include #include #include #include #include #include "mem.h" #include "numa_helper.h" #ifdef HAVE_NUMA_V2 #include static int run = -1; static int sleep_millisecs = -1; static int merge_across_nodes = -1; static unsigned long nr_pages; static char *n_opt; static void test_ksm(void) { if (n_opt) nr_pages = SAFE_STRTOUL(n_opt, 0, ULONG_MAX); else nr_pages = 100; test_ksm_merge_across_nodes(nr_pages); } static void setup(void) { if (access(PATH_KSM "merge_across_nodes", F_OK) == -1) tst_brk(TCONF, "no merge_across_nodes sysfs knob"); if (!is_numa(NULL, NH_MEMS, 2)) tst_brk(TCONF, "The case needs a NUMA system."); /* save the current value */ SAFE_FILE_SCANF(PATH_KSM "run", "%d", &run); SAFE_FILE_SCANF(PATH_KSM "merge_across_nodes", "%d", &merge_across_nodes); SAFE_FILE_SCANF(PATH_KSM "sleep_millisecs", "%d", &sleep_millisecs); } static void cleanup(void) { if (merge_across_nodes != -1) { FILE_PRINTF(PATH_KSM "merge_across_nodes", "%d", merge_across_nodes); } if (sleep_millisecs != -1) FILE_PRINTF(PATH_KSM "sleep_millisecs", "%d", sleep_millisecs); if (run != -1) FILE_PRINTF(PATH_KSM "run", "%d", run); } static struct tst_test test = { .needs_root = 1, .options = (struct tst_option[]) { {"n:", &n_opt, "-n x Allocate x pages memory per node"}, {} }, .setup = setup, .cleanup = cleanup, .save_restore = (const char * const[]) { "?/sys/kernel/mm/ksm/max_page_sharing", NULL, }, .test_all = test_ksm, }; #else TST_TEST_TCONF(NUMA_ERROR_MSG); #endif