1#!/bin/sh 2 3# Regression test for: 4# D53963: vm_fault: only rely on PG_ZERO when the page was newly allocated 5# Test scenario suggestions by: kib 6 7# Problem seen: 8# b[0] is 4. Expected 0 9# b[0] is 4. Expected 0 10 11. ../default.cfg 12 13set -u 14prog=$(basename "$0" .sh) 15cat > /tmp/$prog.c <<EOF 16#include <sys/param.h> 17#include <sys/mman.h> 18#include <sys/stat.h> 19#include <sys/wait.h> 20 21#include <err.h> 22#include <errno.h> 23#include <fcntl.h> 24#include <pthread.h> 25#include <stdio.h> 26#include <stdlib.h> 27#include <string.h> 28#include <unistd.h> 29 30static int debug = 0; 31static int fail, fd, ok, parallel; 32static volatile int done, go; 33static char *buf; 34static char *path = "/dev/md$mdstart"; 35 36#define PARALLEL 3 37#define RUNTIME 180 38 39void * 40wr(void *arg __unused) 41{ 42 int n; 43 44 while (done != 1) { 45 while (go == 0) { 46 usleep(10); 47 } 48 go = 2; 49 n = write(fd, buf, 512); 50 if (n == -1 && errno != EFAULT) 51 warn("write()"); 52 if (debug == 1) { 53 if (n == -1) 54 fail++; 55 else 56 ok++; 57 } 58 } 59 60 return (NULL); 61} 62 63int 64test(void) 65{ 66 size_t len; 67 int i, pagesize; 68 char *a, *b, *c, *p; 69 70 pagesize = sysconf(_SC_PAGESIZE); 71 len = 3 * pagesize; 72 if ((p = mmap(NULL, len, PROT_READ | PROT_WRITE, 73 MAP_ANON | MAP_SHARED, -1, 0)) == MAP_FAILED) 74 err(1, "mmap(%ld pages", len); 75 if (mlock(p, len) == -1) 76 err(1, "mlock()"); 77 78 a = p; 79 b = a + pagesize; 80 buf = b; 81 c = b + pagesize; 82 83 memset(a, 2, pagesize); 84 memset(b, 4, pagesize); 85 memset(c, 8, pagesize); 86 87 if (munlock(b, pagesize) == -1) 88 err(1, "munlock(b)"); 89 go = 1; 90 while (go == 1) 91 usleep(10); 92 if (munmap(b, pagesize) == -1) 93 err(1, "munmap(b)"); 94 95 if (mmap(b, pagesize, PROT_READ | PROT_WRITE, 96 MAP_ANON | MAP_FIXED, -1, 0) == MAP_FAILED) 97 err(1, "mmap(%d pages", pagesize); 98 99 for (i = 0; i < pagesize; i++) { 100 if (b[i] != 0) { 101 fprintf(stderr, "b[%d] is %d. Expected 0\n", i, (int)b[i]); 102 return (1); 103 } 104 } 105 go = 0; 106 107 if (munmap(p, len) == -1) 108 err(1, "Final munmap()"); 109 110 return (0); 111} 112 113int 114run(void) 115{ 116 pthread_t tid; 117 time_t start; 118 int e; 119 120 ok = fail = 0; 121 go = 0; 122 e = pthread_create(&tid, NULL, wr, NULL); 123 if (e) 124 errc(1, e, "pthread_create()"); 125 fail = ok = 0; 126 start = time(NULL); 127 while ((time(NULL) - start) < 30) { 128 if (lseek(fd, 0, SEEK_SET) == -1) 129 err(1, "lseek(0)"); 130 if (fsync(fd) != 0) 131 err(1, "fsync()"); 132 if ((e = test()) != 0) 133 break; 134 } 135 done = 1; 136 pthread_join(tid, NULL); 137 if (debug == 1) 138 fprintf(stderr, "Fail = %3d, OK = %5d, parallel = %d\n", fail, ok, parallel); 139 _exit(e); 140} 141 142int 143main(void) 144{ 145 pid_t pids[PARALLEL]; 146 time_t start; 147 int e, i, status; 148 149 if ((fd = open(path, O_WRONLY)) == -1) 150 err(1, "open(%s)", path); 151 e = 0; 152 start = time(NULL); 153 while ((time(NULL) - start) < RUNTIME && e == 0) { 154 parallel = arc4random() % PARALLEL + 1; 155 for (i = 0; i < parallel; i++) { 156 if ((pids[i] = fork()) == 0) 157 run(); 158 if (pids[i] == -1) 159 err(1, "fork()"); 160 } 161 for (i = 0; i < parallel; i++) { 162 if (waitpid(pids[i], &status, 0) == -1) 163 err(1, "waitpid(%d)", pids[i]); 164 if (status != 0) { 165 if (WIFSIGNALED(status)) 166 fprintf(stderr, 167 "pid %d exit signal %d\n", 168 pids[i], WTERMSIG(status)); 169 } 170 e += status == 0 ? 0 : 1; 171 } 172 } 173 close(fd); 174 175 return (e); 176} 177EOF 178 179mycc -o /tmp/$prog -Wall -Wextra -O0 -g /tmp/$prog.c -pthread || exit 1 180 181mdconfig -l | grep -q md$mdstart && mdconfig -d -u $mdstart 182truncate -s 2g $diskimage 183mdconfig -a -t vnode -f $diskimage -u $mdstart 184../testcases/swap/swap -t 3m -i 20 -l 100 > /dev/null & 185sleep 3 186cd /tmp; ./$prog; s=$?; cd - 187pkill swap 188wait 189rm -f /tmp/$prog.c /tmp/$prog $diskimage 190mdconfig -d -u $mdstart 191exit $s 192