xref: /freebsd/tools/test/stress2/misc/freepages.sh (revision 7fdf597e96a02165cfe22ff357b857d5fa15ed8a)
1#!/bin/sh
2
3#
4# Copyright (c) 2018 Dell EMC Isilon
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# Free page shortage test scenario
30# No problems seen
31
32. ../default.cfg
33[ `id -u` -ne 0 ] && echo "Must be root!" && exit 1
34
35dir=/tmp
36odir=`pwd`
37cd $dir
38sed '1,/^EOF/d' < $odir/$0 > $dir/freepages.c
39mycc -o freepages -Wall -Wextra -O0 -g freepages.c || exit 1
40rm -f freepages.c
41cd $odir
42
43$dir/freepages `sysctl -n hw.usermem`
44s=$?
45[ -f freepages.core -a $s -eq 0 ] &&
46    { ls -l freepages.core; mv freepages.core /tmp; s=1; }
47
48rm -rf $dir/freepages
49exit $s
50EOF
51#include <sys/param.h>
52#include <sys/mman.h>
53#include <sys/stat.h>
54#include <sys/wait.h>
55
56#include <machine/atomic.h>
57
58#include <err.h>
59#include <errno.h>
60#include <fcntl.h>
61#include <stdio.h>
62#include <stdlib.h>
63#include <time.h>
64#include <unistd.h>
65
66static volatile u_int *share;
67
68#define PARALLEL 6
69#define RUNTIME (5 * 60)
70#define SYNC 0
71
72static void
73test(char *s)
74{
75	time_t start;
76	size_t i, len;
77	char *cp;
78
79	atomic_add_int(&share[SYNC], 1);
80	while (share[SYNC] != PARALLEL)
81		;
82	start = time(NULL);
83	while ((time(NULL) - start) < RUNTIME) {
84		len = atol(s) / PARALLEL;
85		len = len / 10 * 8;
86		if ((cp = mmap(NULL, len, PROT_READ | PROT_WRITE,
87		    MAP_ANON | MAP_SHARED, -1, 0)) == MAP_FAILED)
88			err(1, "mmap(%zd)", len);
89		for (i = 0; i < len; i += PAGE_SIZE)
90			cp[i] = 1;
91		if (munmap(cp, len) == -1)
92			err(1, "unmap");
93	}
94
95	_exit(0);
96}
97
98int
99main(int argc __unused, char *argv[])
100{
101	pid_t pids[PARALLEL];
102	size_t len;
103	int e, i, status;
104
105	e = 0;
106	len = PAGE_SIZE;
107	if ((share = mmap(NULL, len, PROT_READ | PROT_WRITE,
108	    MAP_ANON | MAP_SHARED, -1, 0)) == MAP_FAILED)
109		err(1, "mmap");
110
111	for (i = 0; i < PARALLEL; i++) {
112		if ((pids[i] = fork()) == 0)
113			test(argv[1]);
114		if (pids[i] == -1)
115			err(1, "fork()");
116	}
117	for (i = 0; i < PARALLEL; i++) {
118		if (waitpid(pids[i], &status, 0) == -1)
119			err(1, "waitpid(%d)", pids[i]);
120		if (status != 0) {
121			if (WIFSIGNALED(status))
122				fprintf(stderr,
123				    "pid %d exit signal %d\n",
124				    pids[i], WTERMSIG(status));
125		}
126		e += status == 0 ? 0 : 1;
127	}
128
129	return (e);
130}
131