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 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 *****/
ok_exit(void)109 void ok_exit(void)
110 {
111 tst_resm(TPASS, "Test passed\n");
112 tst_exit();
113 }
114
anyfail(void)115 int anyfail(void)
116 {
117 tst_brkm(TFAIL, NULL, "Test failed\n");
118 }
119
120 #else /* defined(__i386__) || defined(__x86_64__) */
main(void)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