/* 01/02/2003 Port to LTP avenkat@us.ibm.com */ /* 06/30/2001 Port to Linux nsharoff@us.ibm.com */ /* * Copyright (c) International Business Machines Corp., 2003 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See * the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /* as_anon_get: * This program tests the kernel primitive as_anon_get by using up lots of * level 2 page tables causing the kernel to switch to large blocks of * anonymous backing store allocation. This is done by allocating pages 4 * megs apart since each pt handles 1024 pages of 4096 bytes each. Each * page thus requires another page table. The pages are then unmapped to * switch back to small swap space allocations. */ #include <sys/types.h> #include <sys/mman.h> #include <unistd.h> #include <errno.h> #include <stdio.h> /***** LTP Port *****/ #include "test.h" #define FAILED 0 #define PASSED 1 int local_flag = PASSED; char *TCID = "mmapstress08"; FILE *temp; int TST_TOTAL = 1; #if defined(__i386__) || defined(__x86_64__) int anyfail(); void ok_exit(); /***** ** ** *****/ #define NPTEPG (1024) /*#define GRAN_NUMBER (1<<2)*/ #define GRAN_NUMBER (1<<8) /* == 256 @ 4MB per mmap(2), we span a total of 1 GB */ extern time_t time(time_t *); extern char *ctime(const time_t *); extern long sysconf(int name); #define ERROR(M) (void)fprintf(stderr, "%s: errno = %d: " M "\n", argv[0], \ errno) /*ARGSUSED*/ int main(int argc, char *argv[]) { caddr_t mmapaddr, munmap_begin; long pagesize = sysconf(_SC_PAGE_SIZE); int i; time_t t; (void)time(&t); //(void)printf("%s: Started %s", argv[0], ctime(&t)); if (sbrk(pagesize - ((u_long) sbrk(0) % (u_long) pagesize)) == (char *)-1) { ERROR("couldn't round up brk to a page boundary"); local_flag = FAILED; anyfail(); } /* The brk is now at the begining of a page. */ if ((munmap_begin = mmapaddr = (caddr_t) sbrk(0)) == (caddr_t) - 1) { ERROR("couldn't find top of brk"); local_flag = FAILED; anyfail(); } /* burn level 2 ptes by spacing mmaps 4Meg apart */ /* This should switch to large anonymous swap space granularity */ for (i = 0; i < GRAN_NUMBER; i++) { if (mmap(mmapaddr, pagesize, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, 0, 0) == (caddr_t) - 1) { ERROR("mmap failed"); local_flag = FAILED; anyfail(); } mmapaddr += NPTEPG * pagesize; } /* Free bizillion level2 ptes to switch to small granularity */ if (munmap(munmap_begin, (size_t) (mmapaddr - munmap_begin))) { ERROR("munmap failed"); local_flag = FAILED; anyfail(); } (void)time(&t); //(void)printf("%s: Finished %s", argv[0], ctime(&t)); ok_exit(); tst_exit(); } /***** LTP Port *****/ void ok_exit(void) { tst_resm(TPASS, "Test passed\n"); tst_exit(); } int anyfail(void) { tst_brkm(TFAIL, NULL, "Test failed\n"); } #else /* defined(__i386__) || defined(__x86_64__) */ int main(void) { tst_brkm(TCONF, NULL, "Test is only applicable for IA-32 and x86-64."); } #endif /***** ** ** *****/