• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2013 Linux Test Project
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of version 2 of the GNU General Public
6  * License as published by the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it would be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11  *
12  * Further, this software is distributed without any warranty that it
13  * is free of the rightful claim of any third person regarding
14  * infringement or the like.  Any license provided herein, whether
15  * implied or otherwise, applies only to this software file.  Patent
16  * licenses, if any, provided herein do not apply to combinations of
17  * this program with other software, or any other product whatsoever.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22  * 02110-1301, USA.
23  */
24 
25 /*
26  * The case is designed to test new sysfs boolean knob
27  * /sys/kernel/mm/ksm/merge_across_nodes, which was introduced by
28  * commit 90bd6fd31c8097ee (ksm: allow trees per NUMA node).
29  * when merge_across_nodes is set to zero only pages from the same
30  * node are merged, otherwise pages from all nodes can be merged
31  * together.
32  */
33 
34 #include "config.h"
35 #include <sys/types.h>
36 #include <sys/stat.h>
37 #include <sys/mman.h>
38 #include <errno.h>
39 #include <fcntl.h>
40 #if HAVE_NUMAIF_H
41 #include <numaif.h>
42 #endif
43 #include <signal.h>
44 #include <stdio.h>
45 #include <unistd.h>
46 #include "numa_helper.h"
47 #include "test.h"
48 #include "safe_macros.h"
49 #include "mem.h"
50 
51 char *TCID = "ksm06";
52 int TST_TOTAL = 1;
53 
54 #if HAVE_NUMA_H && HAVE_LINUX_MEMPOLICY_H && HAVE_NUMAIF_H \
55 	&& HAVE_MPOL_CONSTANTS
56 
57 static int run;
58 static int sleep_millisecs;
59 static int merge_across_nodes;
60 static int n_flag;
61 static unsigned long nr_pages;
62 
63 static char *n_opt;
64 option_t options[] = {
65 	{ "n:", &n_flag, &n_opt },
66 	{ NULL, NULL, NULL }
67 };
68 static void usage(void);
69 
main(int argc,char * argv[])70 int main(int argc, char *argv[])
71 {
72 	int lc;
73 
74 	tst_parse_opts(argc, argv, options, &usage);
75 
76 	if (n_flag)
77 		nr_pages = SAFE_STRTOUL(NULL, n_opt, 0, ULONG_MAX);
78 	else
79 		nr_pages = 100;
80 
81 	setup();
82 
83 	for (lc = 0; TEST_LOOPING(lc); lc++) {
84 		tst_count = 0;
85 
86 		test_ksm_merge_across_nodes(nr_pages);
87 	}
88 
89 	cleanup();
90 	tst_exit();
91 }
92 
setup(void)93 void setup(void)
94 {
95 	if (access(PATH_KSM "merge_across_nodes", F_OK) == -1)
96 		tst_brkm(TCONF, NULL, "no merge_across_nodes sysfs knob");
97 
98 	if (!is_numa(NULL, NH_MEMS, 2))
99 		tst_brkm(TCONF, NULL, "The case needs a NUMA system.");
100 
101 	/* save the current value */
102 	SAFE_FILE_SCANF(NULL, PATH_KSM "run", "%d", &run);
103 	SAFE_FILE_SCANF(NULL, PATH_KSM "merge_across_nodes",
104 			"%d", &merge_across_nodes);
105 	SAFE_FILE_SCANF(NULL, PATH_KSM "sleep_millisecs",
106 			"%d", &sleep_millisecs);
107 
108 	save_max_page_sharing();
109 
110 	tst_sig(FORK, DEF_HANDLER, cleanup);
111 	TEST_PAUSE;
112 }
113 
cleanup(void)114 void cleanup(void)
115 {
116 	FILE_PRINTF(PATH_KSM "merge_across_nodes",
117 			 "%d", merge_across_nodes);
118 	FILE_PRINTF(PATH_KSM "sleep_millisecs",
119 			 "%d", sleep_millisecs);
120 	FILE_PRINTF(PATH_KSM "run", "%d", run);
121 
122 	restore_max_page_sharing();
123 }
124 
usage(void)125 static void usage(void)
126 {
127 	printf("  -n x    Allocate x pages memory per node\n");
128 }
129 
130 #else /* no NUMA */
main(void)131 int main(void)
132 {
133 	tst_brkm(TCONF, NULL, "no NUMA development packages installed.");
134 }
135 #endif
136