• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *
3  *   Copyright (c) International Business Machines  Corp., 2004
4  *
5  *   This program is free software;  you can redistribute it and/or modify
6  *   it under the terms of the GNU General Public License as published by
7  *   the Free Software Foundation; either version 2 of the License, or
8  *   (at your option) any later version.
9  *
10  *   This program is distributed in the hope that it will be useful,
11  *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
13  *   the GNU General Public License for more details.
14  *
15  *   You should have received a copy of the GNU General Public License
16  *   along with this program;  if not, write to the Free Software
17  *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18  */
19 
20 /*
21  * Test Name: hugemmap01
22  *
23  * Test Description:
24  *  Verify that, mmap() succeeds when used to map a file in a hugetlbfs.
25  *
26  * Expected Result:
27  *  mmap() should succeed returning the address of the hugetlb mapped region.
28  *  The number of free huge pages should decrease.
29  *
30  * Algorithm:
31  *  Setup:
32  *   Setup signal handling.
33  *   Pause for SIGUSR1 if option specified.
34  *   Create temporary directory.
35  *
36  * Test:
37  *  Loop if the proper options are given.
38  *  Execute system call
39  *  Check return code, if system call failed (return=-1)
40  *  Log the errno and Issue a FAIL message.
41  * Cleanup:
42  *  Print timing stats if options given
43  *  Delete the temporary directory created.
44  *
45  * HISTORY
46  *  04/2004 Written by Robbie Williamson
47  */
48 
49 #include <sys/types.h>
50 #include <sys/mman.h>
51 #include <sys/mount.h>
52 #include <sys/stat.h>
53 #include <errno.h>
54 #include <fcntl.h>
55 #include <signal.h>
56 #include <stdint.h>
57 #include <stdio.h>
58 #include <stdlib.h>
59 #include <string.h>
60 #include <unistd.h>
61 
62 #include "test.h"
63 #include "hugetlb.h"
64 #include "safe_macros.h"
65 #include "mem.h"
66 
67 static char TEMPFILE[MAXPATHLEN];
68 
69 char *TCID = "hugemmap01";
70 int TST_TOTAL = 1;
71 static long *addr;
72 static int fildes;
73 static char *Hopt;
74 static long beforetest;
75 static long aftertest;
76 static long hugepagesmapped;
77 static long hugepages = 128;
78 
79 static void help(void);
80 
main(int ac,char ** av)81 int main(int ac, char **av)
82 {
83 	int lc;
84 	int Hflag = 0;
85 	long page_sz = 0;
86 	int sflag = 0;
87 
88 	option_t options[] = {
89 		{"H:", &Hflag, &Hopt},
90 		{"s:", &sflag, &nr_opt},
91 		{NULL, NULL, NULL}
92 	};
93 
94 	tst_parse_opts(ac, av, options, &help);
95 
96 	if (!Hflag) {
97 		tst_tmpdir();
98 		Hopt = tst_get_tmpdir();
99 	}
100 	if (sflag)
101 		hugepages = SAFE_STRTOL(NULL, nr_opt, 0, LONG_MAX);
102 
103 	setup();
104 
105 	for (lc = 0; TEST_LOOPING(lc); lc++) {
106 		/* Creat a temporary file used for mapping */
107 		fildes = open(TEMPFILE, O_RDWR | O_CREAT, 0666);
108 		if (fildes < 0)
109 			tst_brkm(TFAIL | TERRNO, cleanup, "open %s failed",
110 				 TEMPFILE);
111 
112 		tst_count = 0;
113 
114 		/* Note the number of free huge pages BEFORE testing */
115 		beforetest = read_meminfo("HugePages_Free:");
116 
117 		/* Note the size of huge page size BEFORE testing */
118 		page_sz = read_meminfo("Hugepagesize:") * 1024;
119 
120 		addr = mmap(NULL, page_sz, PROT_READ | PROT_WRITE,
121 			    MAP_SHARED, fildes, 0);
122 		if (addr == MAP_FAILED) {
123 			tst_resm(TFAIL | TERRNO, "mmap() Failed on %s",
124 				 TEMPFILE);
125 			close(fildes);
126 			continue;
127 		} else {
128 			close(fildes);
129 			tst_resm(TPASS, "call succeeded");
130 			/* force to allocate page and change HugePages_Free */
131 			*(int *)addr = 0;
132 		}
133 
134 		/*
135 		 * Make sure the number of free huge pages
136 		 * AFTER testing decreased
137 		 */
138 		aftertest = read_meminfo("HugePages_Free:");
139 		hugepagesmapped = beforetest - aftertest;
140 		if (hugepagesmapped < 1)
141 			tst_resm(TWARN, "Number of HUGEPAGES_FREE stayed the"
142 				 " same. Okay if multiple copies running due"
143 				 " to test collision.");
144 
145 		/* Clean up things in case we are looping */
146 		/* Unmap the mapped memory */
147 		if (munmap(addr, page_sz) != 0)
148 			tst_brkm(TFAIL | TERRNO, NULL, "munmap failed");
149 
150 		close(fildes);
151 	}
152 
153 	cleanup();
154 	tst_exit();
155 }
156 
setup(void)157 void setup(void)
158 {
159 	TEST_PAUSE;
160 	tst_require_root();
161 	check_hugepage();
162 	if (mount("none", Hopt, "hugetlbfs", 0, NULL) < 0)
163 		tst_brkm(TBROK | TERRNO, NULL, "mount failed on %s", Hopt);
164 
165 	orig_hugepages = get_sys_tune("nr_hugepages");
166 	set_sys_tune("nr_hugepages", hugepages, 1);
167 	snprintf(TEMPFILE, sizeof(TEMPFILE), "%s/mmapfile%d", Hopt, getpid());
168 }
169 
cleanup(void)170 void cleanup(void)
171 {
172 	unlink(TEMPFILE);
173 	set_sys_tune("nr_hugepages", orig_hugepages, 0);
174 
175 	umount(Hopt);
176 	tst_rmdir();
177 }
178 
help(void)179 static void help(void)
180 {
181 	printf("    -H /..  Location of hugetlbfs, i.e. -H /var/hugetlbfs\n");
182 	printf("    -s num  Set the number of the been allocated hugepages\n");
183 }
184