1 /* 2 * Copyright (C) 2010 Red Hat, Inc. 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of version 2 of the GNU General Public License as 6 * published by the Free Software Foundation. 7 * 8 * This program is distributed in the hope that it would be useful, but 9 * WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 * 12 * Further, this software is distributed without any warranty that it is 13 * free of the rightful claim of any third person regarding infringement 14 * or the like. Any license provided herein, whether implied or 15 * otherwise, applies only to this software file. Patent licenses, if 16 * any, provided herein do not apply to combinations of this program 17 * with other software, or any other product whatsoever. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with this program; if not, write the Free Software Foundation, 21 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 22 */ 23 /* 24 * munmap() don't check sysctl_max_mapcount 25 * 26 * From http://lkml.org/lkml/2009/10/2/85: 27 * 28 * On ia64, the following test program exit abnormally, because glibc 29 * thread library called abort(). 30 * 31 * ======================================================== 32 * (gdb) bt 33 * #0 0xa000000000010620 in __kernel_syscall_via_break () 34 * #1 0x20000000003208e0 in raise () from /lib/libc.so.6.1 35 * #2 0x2000000000324090 in abort () from /lib/libc.so.6.1 36 * #3 0x200000000027c3e0 in __deallocate_stack () from 37 * /lib/libpthread.so.0 38 * #4 0x200000000027f7c0 in start_thread () from /lib/libpthread.so.0 39 * #5 0x200000000047ef60 in __clone2 () from /lib/libc.so.6.1 40 * ======================================================== 41 * The fact is, glibc call munmap() when thread exitng time for freeing 42 * stack, and it assume munlock() never fail. However, munmap() often 43 * make vma splitting and it with many mapcount make -ENOMEM. 44 * 45 * Oh well, stack unfreeing is not reasonable option. Also munlock() via 46 * free() shouldn't failed. 47 * 48 * Thus, munmap() shoudn't check max-mapcount. 49 */ 50 #include<stdio.h> 51 #include<stdlib.h> 52 #include<string.h> 53 #include<pthread.h> 54 #include<errno.h> 55 #include<unistd.h> 56 #include "test.h" 57 58 char *TCID = "mmap11"; 59 int TST_TOTAL = 1; 60 61 #define MAL_SIZE (100*1024) 62 63 static void *wait_thread(void *args); 64 static void *wait_thread2(void *args); 65 static void setup(void); 66 static void cleanup(void); 67 static void check(void); 68 69 int main(int argc, char *argv[]) 70 { 71 72 tst_parse_opts(argc, argv, NULL, NULL); 73 setup(); 74 check(); 75 cleanup(); 76 tst_exit(); 77 } 78 79 void setup(void) 80 { 81 tst_require_root(); 82 83 tst_sig(FORK, DEF_HANDLER, cleanup); 84 TEST_PAUSE; 85 } 86 87 void cleanup(void) 88 { 89 } 90 91 void check(void) 92 { 93 int lc; 94 pthread_t *thread, th; 95 int ret, count = 0; 96 pthread_attr_t attr; 97 98 ret = pthread_attr_init(&attr); 99 if (ret) 100 tst_brkm(TBROK | TERRNO, cleanup, "pthread_attr_init"); 101 ret = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 102 if (ret) 103 tst_brkm(TBROK | TERRNO, cleanup, 104 "pthread_attr_setdetachstate"); 105 thread = malloc(STD_LOOP_COUNT * sizeof(pthread_t)); 106 if (thread == NULL) 107 tst_brkm(TBROK | TERRNO, cleanup, "malloc"); 108 109 for (lc = 0; TEST_LOOPING(lc); lc++) { 110 tst_count = 0; 111 ret = pthread_create(&th, &attr, wait_thread, NULL); 112 if (ret) { 113 tst_resm(TINFO, "[%d] ", count); 114 tst_brkm(TBROK | TERRNO, cleanup, "pthread_create"); 115 } 116 count++; 117 ret = pthread_create(&thread[lc], &attr, wait_thread2, NULL); 118 if (ret) { 119 tst_resm(TINFO, "[%d] ", count); 120 tst_brkm(TBROK | TERRNO, cleanup, "pthread_create"); 121 } 122 count++; 123 } 124 tst_resm(TPASS, "test completed."); 125 free(thread); 126 } 127 128 void *wait_thread(void *args) 129 { 130 void *addr; 131 132 addr = malloc(MAL_SIZE); 133 if (addr) 134 memset(addr, 1, MAL_SIZE); 135 sleep(1); 136 return NULL; 137 } 138 139 void *wait_thread2(void *args) 140 { 141 return NULL; 142 } 143