git: f88300a7b56e - main - stress2: Added a regression test
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Tue, 09 Dec 2025 10:35:10 UTC
The branch main has been updated by pho:
URL: https://cgit.FreeBSD.org/src/commit/?id=f88300a7b56e32808e91fc893e7f1afc67ce72fd
commit f88300a7b56e32808e91fc893e7f1afc67ce72fd
Author: Peter Holm <pho@FreeBSD.org>
AuthorDate: 2025-12-09 10:33:09 +0000
Commit: Peter Holm <pho@FreeBSD.org>
CommitDate: 2025-12-09 10:34:44 +0000
stress2: Added a regression test
---
tools/test/stress2/misc/pg_zero.sh | 191 +++++++++++++++++++++++++++++++++++++
1 file changed, 191 insertions(+)
diff --git a/tools/test/stress2/misc/pg_zero.sh b/tools/test/stress2/misc/pg_zero.sh
new file mode 100755
index 000000000000..4d34a59616e1
--- /dev/null
+++ b/tools/test/stress2/misc/pg_zero.sh
@@ -0,0 +1,191 @@
+#!/bin/sh
+
+# Regression test for:
+# D53963: vm_fault: only rely on PG_ZERO when the page was newly allocated
+# Test scenario suggestions by: kib
+
+# Problem seen:
+# b[0] is 4. Expected 0
+# b[0] is 4. Expected 0
+
+. ../default.cfg
+
+set -u
+prog=$(basename "$0" .sh)
+cat > /tmp/$prog.c <<EOF
+#include <sys/param.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+static int debug = 0;
+static int fail, fd, ok, parallel;
+static volatile int done, go;
+static char *buf;
+static char *path = "/dev/md$mdstart";
+
+#define PARALLEL 3
+#define RUNTIME 180
+
+void *
+wr(void *arg __unused)
+{
+ int n;
+
+ while (done != 1) {
+ while (go == 0) {
+ usleep(10);
+ }
+ go = 2;
+ n = write(fd, buf, 512);
+ if (n == -1 && errno != EFAULT)
+ warn("write()");
+ if (debug == 1) {
+ if (n == -1)
+ fail++;
+ else
+ ok++;
+ }
+ }
+
+ return (NULL);
+}
+
+int
+test(void)
+{
+ size_t len;
+ int i, pagesize;
+ char *a, *b, *c, *p;
+
+ pagesize = sysconf(_SC_PAGESIZE);
+ len = 3 * pagesize;
+ if ((p = mmap(NULL, len, PROT_READ | PROT_WRITE,
+ MAP_ANON | MAP_SHARED, -1, 0)) == MAP_FAILED)
+ err(1, "mmap(%ld pages", len);
+ if (mlock(p, len) == -1)
+ err(1, "mlock()");
+
+ a = p;
+ b = a + pagesize;
+ buf = b;
+ c = b + pagesize;
+
+ memset(a, 2, pagesize);
+ memset(b, 4, pagesize);
+ memset(c, 8, pagesize);
+
+ if (munlock(b, pagesize) == -1)
+ err(1, "munlock(b)");
+ go = 1;
+ while (go == 1)
+ usleep(10);
+ if (munmap(b, pagesize) == -1)
+ err(1, "munmap(b)");
+
+ if (mmap(b, pagesize, PROT_READ | PROT_WRITE,
+ MAP_ANON | MAP_FIXED, -1, 0) == MAP_FAILED)
+ err(1, "mmap(%d pages", pagesize);
+
+ for (i = 0; i < pagesize; i++) {
+ if (b[i] != 0) {
+ fprintf(stderr, "b[%d] is %d. Expected 0\n", i, (int)b[i]);
+ return (1);
+ }
+ }
+ go = 0;
+
+ if (munmap(p, len) == -1)
+ err(1, "Final munmap()");
+
+ return (0);
+}
+
+int
+run(void)
+{
+ pthread_t tid;
+ time_t start;
+ int e;
+
+ ok = fail = 0;
+ go = 0;
+ e = pthread_create(&tid, NULL, wr, NULL);
+ if (e)
+ errc(1, e, "pthread_create()");
+ fail = ok = 0;
+ start = time(NULL);
+ while ((time(NULL) - start) < 30) {
+ if (lseek(fd, 0, SEEK_SET) == -1)
+ err(1, "lseek(0)");
+ if (fsync(fd) != 0)
+ err(1, "fsync()");
+ if ((e = test()) != 0)
+ break;
+ }
+ done = 1;
+ pthread_join(tid, NULL);
+ if (debug == 1)
+ fprintf(stderr, "Fail = %3d, OK = %5d, parallel = %d\n", fail, ok, parallel);
+ _exit(e);
+}
+
+int
+main(void)
+{
+ pid_t pids[PARALLEL];
+ time_t start;
+ int e, i, status;
+
+ if ((fd = open(path, O_WRONLY)) == -1)
+ err(1, "open(%s)", path);
+ e = 0;
+ start = time(NULL);
+ while ((time(NULL) - start) < RUNTIME && e == 0) {
+ parallel = arc4random() % PARALLEL + 1;
+ for (i = 0; i < parallel; i++) {
+ if ((pids[i] = fork()) == 0)
+ run();
+ if (pids[i] == -1)
+ err(1, "fork()");
+ }
+ for (i = 0; i < parallel; i++) {
+ if (waitpid(pids[i], &status, 0) == -1)
+ err(1, "waitpid(%d)", pids[i]);
+ if (status != 0) {
+ if (WIFSIGNALED(status))
+ fprintf(stderr,
+ "pid %d exit signal %d\n",
+ pids[i], WTERMSIG(status));
+ }
+ e += status == 0 ? 0 : 1;
+ }
+ }
+ close(fd);
+
+ return (e);
+}
+EOF
+
+mycc -o /tmp/$prog -Wall -Wextra -O0 -g /tmp/$prog.c -pthread || exit 1
+
+mdconfig -l | grep -q md$mdstart && mdconfig -d -u $mdstart
+truncate -s 2g $diskimage
+mdconfig -a -t vnode -f $diskimage -u $mdstart
+../testcases/swap/swap -t 3m -i 20 -l 100 > /dev/null &
+sleep 3
+cd /tmp; ./$prog; s=$?; cd -
+pkill swap
+wait
+rm -f /tmp/$prog.c /tmp/$prog $diskimage
+mdconfig -d -u $mdstart
+exit $s