1#!/bin/sh 2 3# 4# Copyright (c) 2014 EMC Corp. 5# All rights reserved. 6# 7# Redistribution and use in source and binary forms, with or without 8# modification, are permitted provided that the following conditions 9# are met: 10# 1. Redistributions of source code must retain the above copyright 11# notice, this list of conditions and the following disclaimer. 12# 2. Redistributions in binary form must reproduce the above copyright 13# notice, this list of conditions and the following disclaimer in the 14# documentation and/or other materials provided with the distribution. 15# 16# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26# SUCH DAMAGE. 27# 28 29# "panic: vm_page_dirty: page is invalid!" seen. 30# http://people.freebsd.org/~pho/stress/log/mmap10.txt 31# No problems seen after r271681. 32 33. ../default.cfg 34 35[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 36 37here=`pwd` 38cd /tmp 39sed '1,/^EOF/d' < $here/$0 > mmap10.c 40mycc -o mmap10 -Wall -Wextra -O2 -g mmap10.c -lpthread || exit 1 41rm -f mmap10.c 42 43daemon sh -c "(cd $here/../testcases/swap; ./swap -t 2m -i 20 -k > /dev/null)" 44ulimit -c 0 45sleep `jot -r 1 0 9` 46for i in `jot 2`; do 47 su $testuser -c /tmp/mmap10 & 48done 49start=`date +%s` 50while pgrep -q mmap10; do 51 [ $((`date +%s` - start)) -ge 300 ] && break 52 sleep 2 53done 54while pgrep -q 'mmap10|swap'; do 55 pkill -9 mmap10 swap 56 sleep 2 57done 58wait 59 60rm -f /tmp/mmap10 /tmp/mmap10.core 61exit 0 62EOF 63#include <sys/types.h> 64#include <sys/mman.h> 65#include <sys/stat.h> 66#include <sys/wait.h> 67 68#include <err.h> 69#include <errno.h> 70#include <fcntl.h> 71#include <pthread.h> 72#include <pthread_np.h> 73#include <stdio.h> 74#include <stdlib.h> 75#include <string.h> 76#include <unistd.h> 77 78#define LOOPS 2 79#define MMSIZE (192 * 1024 * 1024) 80#define N (128 * 1024 / (int)sizeof(u_int32_t)) 81#define PARALLEL 50 82 83static int debug = 0; /* set to "1" for debug output */ 84void *p; 85u_int32_t r[N]; 86 87unsigned long 88makearg(void) 89{ 90 unsigned long val; 91 unsigned int i; 92 93 val = arc4random(); 94 i = arc4random() % 100; 95 if (i < 20) 96 val = val & 0xff; 97 if (i >= 20 && i < 40) 98 val = val & 0xffff; 99 if (i >= 40 && i < 60) 100 val = (unsigned long)(r) | (val & 0xffff); 101#if defined(__LP64__) 102 if (i >= 60) { 103 val = (val << 32) | arc4random(); 104 if (i > 80) 105 val = val & 0x00007fffffffffffUL; 106 } 107#endif 108 109 return(val); 110} 111 112void * 113makeptr(void) 114{ 115 unsigned long val; 116 117 if (p != MAP_FAILED && p != NULL) 118 val = (unsigned long)p + arc4random(); 119 else 120 val = makearg(); 121 val = trunc_page(val); 122 123 return ((void *)val); 124} 125 126void * 127tmmap(void *arg __unused) 128{ 129 size_t len; 130 int i, j, fd; 131 132 pthread_set_name_np(pthread_self(), __func__); 133 len = MMSIZE; 134 135 for (i = 0, j = 0; i < 100; i++) { 136 if ((fd = open("/dev/zero", O_RDWR)) == -1) 137 err(1,"open()"); 138 139 if ((p = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_PRIVATE, 140 fd, 0)) != MAP_FAILED) { 141 usleep(100); 142 munmap(p, len); 143 j++; 144 } 145 146 if ((p = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_ANON, 147 -1, 0)) != MAP_FAILED) { 148 usleep(100); 149 munmap(p, len); 150 j++; 151 } 152 close(fd); 153 } 154 if (j == 0) 155 fprintf(stderr, "FAIL: all mmap(2) calls failed.\n"); 156 157 return (NULL); 158} 159 160void * 161tmlock(void *arg __unused) 162{ 163 size_t len; 164 int i, n; 165 166 pthread_set_name_np(pthread_self(), __func__); 167 n = 0; 168 for (i = 0; i < 200; i++) { 169 len = trunc_page(makearg()); 170 if (mlock(makeptr(), len) == 0) 171 n++; 172 len = trunc_page(makearg()); 173 if (arc4random() % 100 < 50) 174 if (munlock(makeptr(), len) == 0) 175 n++; 176 } 177 if (debug == 1 && n < 10) 178 fprintf(stderr, "Note: tmlock() only succeeded %d times.\n", 179 n); 180 181 return (NULL); 182} 183 184void * 185tmprotect(void *arg __unused) 186{ 187 size_t len; 188 void *addr; 189 int i, n, prot; 190 191 pthread_set_name_np(pthread_self(), __func__); 192 n = 0; 193 for (i = 0; i < 200; i++) { 194 addr = makeptr(); 195 len = trunc_page(makearg()); 196 prot = makearg(); 197 if (mprotect(addr, len, prot) == 0) 198 n++; 199 usleep(1000); 200 } 201 if (debug == 1 && n < 10) 202 fprintf(stderr, "Note: tmprotect() only succeeded %d times.\n", 203 n); 204 205 return (NULL); 206} 207 208void * 209tmlockall(void *arg __unused) 210{ 211 int flags, i, n; 212 213 pthread_set_name_np(pthread_self(), __func__); 214 n = 0; 215 for (i = 0; i < 200; i++) { 216 flags = makearg(); 217 if (mlockall(flags) == 0) 218 n++; 219 usleep(100); 220 munlockall(); 221 usleep(1000); 222 } 223 if (debug == 1 && n < 10) 224 fprintf(stderr, "Note: tmlockall() only succeeded %d times.\n", 225 n); 226 227 return (NULL); 228} 229 230void 231test(void) 232{ 233 pthread_t tid[4]; 234 int i, rc; 235 236 if ((rc = pthread_create(&tid[0], NULL, tmmap, NULL)) != 0) 237 errc(1, rc, "tmmap()"); 238 if ((rc = pthread_create(&tid[1], NULL, tmlock, NULL)) != 0) 239 errc(1, rc, "tmlock()"); 240 if ((rc = pthread_create(&tid[2], NULL, tmprotect, NULL)) != 0) 241 errc(1, rc, "tmprotect()"); 242 if ((rc = pthread_create(&tid[3], NULL, tmlockall, NULL)) != 0) 243 errc(1, rc, "tmlockall()"); 244 245 for (i = 0; i < 100; i++) { 246 if (fork() == 0) { 247 usleep(10000); 248 _exit(0); 249 } 250 wait(NULL); 251 } 252 253 for (i = 0; i < 4; i++) 254 if ((rc = pthread_join(tid[i], NULL)) != 0) 255 errc(1, rc, "pthread_join(%d)", i); 256 _exit(0); 257} 258 259int 260main(void) 261{ 262 int i, j; 263 264 for (i = 0; i < N; i++) 265 r[i] = arc4random(); 266 267 for (i = 0; i < LOOPS; i++) { 268 for (j = 0; j < PARALLEL; j++) { 269 if (fork() == 0) 270 test(); 271 } 272 273 for (j = 0; j < PARALLEL; j++) 274 wait(NULL); 275 } 276 277 return (0); 278} 279