1 /* 01/02/2003 Port to LTP avenkat (at) us.ibm.com */ 2 /* 06/30/2001 Port to Linux nsharoff (at) us.ibm.com */ 3 /* 4 * Copyright (c) International Business Machines Corp., 2003 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 14 * the GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 */ 20 21 /* as_anon_get: 22 * This program tests the kernel primitive as_anon_get by using up lots of 23 * level 2 page tables causing the kernel to switch to large blocks of 24 * anonymous backing store allocation. This is done by allocating pages 4 25 * megs apart since each pt handles 1024 pages of 4096 bytes each. Each 26 * page thus requires another page table. The pages are then unmapped to 27 * switch back to small swap space allocations. 28 */ 29 #include <sys/types.h> 30 #include <sys/mman.h> 31 #include <unistd.h> 32 #include <errno.h> 33 #include <stdio.h> 34 /***** LTP Port *****/ 35 #include "test.h" 36 #define FAILED 0 37 #define PASSED 1 38 39 int local_flag = PASSED; 40 char *TCID = "mmapstress08"; 41 FILE *temp; 42 int TST_TOTAL = 1; 43 44 #if defined(__i386__) || defined(__x86_64__) 45 int anyfail(); 46 void ok_exit(); 47 /***** ** ** *****/ 48 49 #define NPTEPG (1024) 50 /*#define GRAN_NUMBER (1<<2)*/ 51 52 #define GRAN_NUMBER (1<<8) 53 /* == 256 @ 4MB per mmap(2), we span a total of 1 GB */ 54 55 extern time_t time(time_t *); 56 extern char *ctime(const time_t *); 57 extern long sysconf(int name); 58 59 #define ERROR(M) (void)fprintf(stderr, "%s: errno = %d: " M "\n", argv[0], \ 60 errno) 61 62 /*ARGSUSED*/ int main(int argc, char *argv[]) 63 { 64 caddr_t mmapaddr, munmap_begin; 65 long pagesize = sysconf(_SC_PAGE_SIZE); 66 int i; 67 time_t t; 68 69 (void)time(&t); 70 //(void)printf("%s: Started %s", argv[0], ctime(&t)); 71 if (sbrk(pagesize - ((u_long) sbrk(0) % (u_long) pagesize)) == 72 (char *)-1) { 73 ERROR("couldn't round up brk to a page boundary"); 74 local_flag = FAILED; 75 anyfail(); 76 } 77 /* The brk is now at the begining of a page. */ 78 79 if ((munmap_begin = mmapaddr = (caddr_t) sbrk(0)) == (caddr_t) - 1) { 80 ERROR("couldn't find top of brk"); 81 local_flag = FAILED; 82 anyfail(); 83 } 84 mmapaddr = 0; 85 /* burn level 2 ptes by spacing mmaps 4Meg apart */ 86 /* This should switch to large anonymous swap space granularity */ 87 for (i = 0; i < GRAN_NUMBER; i++) { 88 if (mmap(mmapaddr, pagesize, PROT_READ | PROT_WRITE, 89 MAP_ANONYMOUS | MAP_PRIVATE, 0, 0) == (caddr_t) - 1) { 90 ERROR("mmap failed"); 91 local_flag = FAILED; 92 anyfail(); 93 } 94 mmapaddr += NPTEPG * pagesize; 95 } 96 /* Free bizillion level2 ptes to switch to small granularity */ 97 if (munmap(munmap_begin, (size_t) (mmapaddr - munmap_begin))) { 98 ERROR("munmap failed"); 99 local_flag = FAILED; 100 anyfail(); 101 } 102 (void)time(&t); 103 //(void)printf("%s: Finished %s", argv[0], ctime(&t)); 104 ok_exit(); 105 tst_exit(); 106 } 107 108 /***** LTP Port *****/ 109 void ok_exit(void) 110 { 111 tst_resm(TPASS, "Test passed\n"); 112 tst_exit(); 113 } 114 115 int anyfail(void) 116 { 117 tst_brkm(TFAIL, NULL, "Test failed\n"); 118 } 119 120 #else /* defined(__i386__) || defined(__x86_64__) */ 121 int main(void) 122 { 123 tst_brkm(TCONF, NULL, "Test is only applicable for IA-32 and x86-64."); 124 } 125 #endif 126 /***** ** ** *****/ 127