xref: /freebsd/tools/test/stress2/misc/pg_zero.sh (revision f88300a7b56e32808e91fc893e7f1afc67ce72fd)
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