Home | History | Annotate | Download | only in mmapstress
      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