• 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 "lapi/abisize.h"
42 #include "hugetlb.h"
43 
44 static struct tst_option options[] = {
45 	{"H:", &Hopt,   "-H   /..  Location of hugetlbfs, i.e.  -H /var/hugetlbfs"},
46 	{"s:", &nr_opt, "-s   num  Set the number of the been allocated hugepages"},
47 	{NULL, NULL, NULL}
48 };
49 
50 static char TEMPFILE[MAXPATHLEN];
51 
52 static long *addr;
53 static long long mapsize;
54 static int fildes;
55 static long freepages;
56 static long beforetest;
57 static long aftertest;
58 static long hugepagesmapped;
59 static long hugepages = 128;
60 
test_hugemmap(void)61 static void test_hugemmap(void)
62 {
63 	int huge_pagesize = 0;
64 
65 	/* Creat a temporary file used for huge mapping */
66 	fildes = SAFE_OPEN(TEMPFILE, O_RDWR | O_CREAT, 0666);
67 
68 	freepages = SAFE_READ_MEMINFO("HugePages_Free:");
69 	beforetest = freepages;
70 
71 	huge_pagesize = SAFE_READ_MEMINFO("Hugepagesize:");
72 	tst_res(TINFO, "Size of huge pages is %d KB", huge_pagesize);
73 
74 #ifdef TST_ABI32
75 	tst_res(TINFO, "Total amount of free huge pages is %d",
76 			freepages);
77 	tst_res(TINFO, "Max number allowed for 1 mmap file in"
78 			" 32-bits is 128");
79 	if (freepages > 128)
80 		freepages = 128;
81 #endif
82 	mapsize = (long long)freepages * huge_pagesize * 1024;
83 	addr = mmap(NULL, mapsize, PROT_READ | PROT_WRITE,
84 			MAP_SHARED, fildes, 0);
85 	if (addr == MAP_FAILED) {
86 		tst_res(TFAIL | TERRNO, "mmap() Failed on %s",
87 				TEMPFILE);
88 	} else {
89 		tst_res(TPASS,
90 				"Succeeded mapping file using %ld pages",
91 				freepages);
92 
93 		/* force to allocate page and change HugePages_Free */
94 		*(int *)addr = 0;
95 		/* Make sure the number of free huge pages AFTER testing decreased */
96 		aftertest = SAFE_READ_MEMINFO("HugePages_Free:");
97 		hugepagesmapped = beforetest - aftertest;
98 		if (hugepagesmapped < 1)
99 			tst_res(TWARN, "Number of HUGEPAGES_FREE stayed the"
100 					" same. Okay if multiple copies running due"
101 					" to test collision.");
102 	}
103 
104 	munmap(addr, mapsize);
105 	close(fildes);
106 }
107 
setup(void)108 void setup(void)
109 {
110 	save_nr_hugepages();
111 
112 	if (!Hopt)
113 		Hopt = tst_get_tmpdir();
114 	SAFE_MOUNT("none", Hopt, "hugetlbfs", 0, NULL);
115 
116 	if (nr_opt)
117 		hugepages = SAFE_STRTOL(nr_opt, 0, LONG_MAX);
118 
119 	limit_hugepages(&hugepages);
120 	set_sys_tune("nr_hugepages", hugepages, 1);
121 
122 	snprintf(TEMPFILE, sizeof(TEMPFILE), "%s/mmapfile%d", Hopt, getpid());
123 }
124 
cleanup(void)125 void cleanup(void)
126 {
127 	unlink(TEMPFILE);
128 	restore_nr_hugepages();
129 
130 	umount(Hopt);
131 }
132 
133 static struct tst_test test = {
134 	.needs_root = 1,
135 	.needs_tmpdir = 1,
136 	.options = options,
137 	.setup = setup,
138 	.cleanup = cleanup,
139 	.test_all = test_hugemmap,
140 };
141