1 /* 01/02/2003 Port to LTP avenkat@us.ibm.com */
2 /* 06/30/2001 Port to Linux nsharoff@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
main(int argc,char * argv[])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 /* burn level 2 ptes by spacing mmaps 4Meg apart */
85 /* This should switch to large anonymous swap space granularity */
86 for (i = 0; i < GRAN_NUMBER; i++) {
87 if (mmap(mmapaddr, pagesize, PROT_READ | PROT_WRITE,
88 MAP_ANONYMOUS | MAP_PRIVATE, 0, 0) == (caddr_t) - 1) {
89 ERROR("mmap failed");
90 local_flag = FAILED;
91 anyfail();
92 }
93 mmapaddr += NPTEPG * pagesize;
94 }
95 /* Free bizillion level2 ptes to switch to small granularity */
96 if (munmap(munmap_begin, (size_t) (mmapaddr - munmap_begin))) {
97 ERROR("munmap failed");
98 local_flag = FAILED;
99 anyfail();
100 }
101 (void)time(&t);
102 //(void)printf("%s: Finished %s", argv[0], ctime(&t));
103 ok_exit();
104 tst_exit();
105 }
106
107 /***** LTP Port *****/
ok_exit(void)108 void ok_exit(void)
109 {
110 tst_resm(TPASS, "Test passed\n");
111 tst_exit();
112 }
113
anyfail(void)114 int anyfail(void)
115 {
116 tst_brkm(TFAIL, NULL, "Test failed\n");
117 }
118
119 #else /* defined(__i386__) || defined(__x86_64__) */
main(void)120 int main(void)
121 {
122 tst_brkm(TCONF, NULL, "Test is only applicable for IA-32 and x86-64.");
123 }
124 #endif
125 /***** ** ** *****/
126