• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) International Business Machines  Corp., 2004
3  * Copyright (c) Linux Test Project, 2004-2017
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 
16 /*
17  * Test Name: hugemmap04
18  *
19  * Test Description:
20  *  Verify that, a hugetlb mmap() succeeds when used to map the largest
21  *  size possible.
22  *
23  * Expected Result:
24  *  mmap() should succeed returning the address of the hugetlb mapped region.
25  *  The number of free huge pages should decrease.
26  *
27  * Test:
28  *  Loop if the proper options are given.
29  *  Execute system call
30  *  Check return code, if system call failed (return=-1)
31  *  Log the errno and Issue a FAIL message.
32  *
33  * HISTORY
34  *  04/2004 Written by Robbie Williamson
35  */
36 
37 #include <sys/mount.h>
38 #include <stdio.h>
39 #include <limits.h>
40 #include <sys/param.h>
41 #include "hugetlb.h"
42 
43 static struct tst_option options[] = {
44 	{"H:", &Hopt,   "-H   /..  Location of hugetlbfs, i.e.  -H /var/hugetlbfs"},
45 	{"s:", &nr_opt, "-s   num  Set the number of the been allocated hugepages"},
46 	{NULL, NULL, NULL}
47 };
48 
49 static char TEMPFILE[MAXPATHLEN];
50 
51 static long *addr;
52 static long long mapsize;
53 static int fildes;
54 static long freepages;
55 static long beforetest;
56 static long aftertest;
57 static long hugepagesmapped;
58 static long hugepages = 128;
59 
test_hugemmap(void)60 static void test_hugemmap(void)
61 {
62 	int huge_pagesize = 0;
63 
64 	/* Creat a temporary file used for huge mapping */
65 	fildes = SAFE_OPEN(TEMPFILE, O_RDWR | O_CREAT, 0666);
66 
67 	freepages = SAFE_READ_MEMINFO("HugePages_Free:");
68 	beforetest = freepages;
69 
70 	huge_pagesize = SAFE_READ_MEMINFO("Hugepagesize:");
71 	tst_res(TINFO, "Size of huge pages is %d KB", huge_pagesize);
72 
73 #if __WORDSIZE == 32
74 	tst_res(TINFO, "Total amount of free huge pages is %d",
75 			freepages);
76 	tst_res(TINFO, "Max number allowed for 1 mmap file in"
77 			" 32-bits is 128");
78 	if (freepages > 128)
79 		freepages = 128;
80 #endif
81 	mapsize = (long long)freepages * huge_pagesize * 1024;
82 	addr = mmap(NULL, mapsize, PROT_READ | PROT_WRITE,
83 			MAP_SHARED, fildes, 0);
84 	if (addr == MAP_FAILED) {
85 		tst_res(TFAIL | TERRNO, "mmap() Failed on %s",
86 				TEMPFILE);
87 	} else {
88 		tst_res(TPASS,
89 				"Succeeded mapping file using %ld pages",
90 				freepages);
91 
92 		/* force to allocate page and change HugePages_Free */
93 		*(int *)addr = 0;
94 		/* Make sure the number of free huge pages AFTER testing decreased */
95 		aftertest = SAFE_READ_MEMINFO("HugePages_Free:");
96 		hugepagesmapped = beforetest - aftertest;
97 		if (hugepagesmapped < 1)
98 			tst_res(TWARN, "Number of HUGEPAGES_FREE stayed the"
99 					" same. Okay if multiple copies running due"
100 					" to test collision.");
101 	}
102 
103 	munmap(addr, mapsize);
104 	close(fildes);
105 }
106 
setup(void)107 void setup(void)
108 {
109 	save_nr_hugepages();
110 
111 	if (!Hopt)
112 		Hopt = tst_get_tmpdir();
113 	SAFE_MOUNT("none", Hopt, "hugetlbfs", 0, NULL);
114 
115 	if (nr_opt)
116 		hugepages = SAFE_STRTOL(nr_opt, 0, LONG_MAX);
117 	set_sys_tune("nr_hugepages", hugepages, 1);
118 
119 	snprintf(TEMPFILE, sizeof(TEMPFILE), "%s/mmapfile%d", Hopt, getpid());
120 }
121 
cleanup(void)122 void cleanup(void)
123 {
124 	unlink(TEMPFILE);
125 	restore_nr_hugepages();
126 
127 	umount(Hopt);
128 }
129 
130 static struct tst_test test = {
131 	.needs_root = 1,
132 	.needs_tmpdir = 1,
133 	.options = options,
134 	.setup = setup,
135 	.cleanup = cleanup,
136 	.test_all = test_hugemmap,
137 };
138