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