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 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 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 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 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