xref: /freebsd/tools/test/stress2/misc/mlockall7.sh (revision 8a272653d9fbd9fc37691c9aad6a05089b4ecb4d)
1*8a272653SPeter Holm#!/bin/sh
2*8a272653SPeter Holm
3*8a272653SPeter Holm#
4*8a272653SPeter Holm# Copyright (c) 2014 EMC Corp.
5*8a272653SPeter Holm# All rights reserved.
6*8a272653SPeter Holm#
7*8a272653SPeter Holm# Redistribution and use in source and binary forms, with or without
8*8a272653SPeter Holm# modification, are permitted provided that the following conditions
9*8a272653SPeter Holm# are met:
10*8a272653SPeter Holm# 1. Redistributions of source code must retain the above copyright
11*8a272653SPeter Holm#    notice, this list of conditions and the following disclaimer.
12*8a272653SPeter Holm# 2. Redistributions in binary form must reproduce the above copyright
13*8a272653SPeter Holm#    notice, this list of conditions and the following disclaimer in the
14*8a272653SPeter Holm#    documentation and/or other materials provided with the distribution.
15*8a272653SPeter Holm#
16*8a272653SPeter Holm# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17*8a272653SPeter Holm# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18*8a272653SPeter Holm# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19*8a272653SPeter Holm# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20*8a272653SPeter Holm# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21*8a272653SPeter Holm# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22*8a272653SPeter Holm# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23*8a272653SPeter Holm# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24*8a272653SPeter Holm# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25*8a272653SPeter Holm# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26*8a272653SPeter Holm# SUCH DAMAGE.
27*8a272653SPeter Holm#
28*8a272653SPeter Holm
29*8a272653SPeter Holm# Variation of mmap18.sh.
30*8a272653SPeter Holm# "panic: vm_page_unwire: page 0xfffff81038d721f0's wire count is zero" seen:
31*8a272653SPeter Holm# https://people.freebsd.org/~pho/stress/log/mlockall7.txt
32*8a272653SPeter Holm# Fixed by r328880
33*8a272653SPeter Holm
34*8a272653SPeter Holm[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
35*8a272653SPeter Holm
36*8a272653SPeter Holm. ../default.cfg
37*8a272653SPeter Holm
38*8a272653SPeter Holmhere=`pwd`
39*8a272653SPeter Holmcd /tmp
40*8a272653SPeter Holmsed '1,/^EOF/d' < $here/$0 > mlockall7.c
41*8a272653SPeter Holmmycc -o mlockall7 -Wall -Wextra -O2 mlockall7.c -lpthread || exit 1
42*8a272653SPeter Holmrm -f mlockall7.c
43*8a272653SPeter Holm
44*8a272653SPeter Holm/tmp/mlockall7 `[ $# -eq 0 ] && echo 1 || echo $1` || s=1
45*8a272653SPeter Holm
46*8a272653SPeter Holmsleep 2
47*8a272653SPeter Holmrm -f /tmp/mlockall7 /tmp/mlockall7.core
48*8a272653SPeter Holmexit $s
49*8a272653SPeter HolmEOF
50*8a272653SPeter Holm#include <sys/types.h>
51*8a272653SPeter Holm#include <sys/mman.h>
52*8a272653SPeter Holm#include <sys/resource.h>
53*8a272653SPeter Holm#include <sys/stat.h>
54*8a272653SPeter Holm#include <sys/sysctl.h>
55*8a272653SPeter Holm#include <sys/time.h>
56*8a272653SPeter Holm#include <sys/wait.h>
57*8a272653SPeter Holm
58*8a272653SPeter Holm#include <err.h>
59*8a272653SPeter Holm#include <fcntl.h>
60*8a272653SPeter Holm#include <pwd.h>
61*8a272653SPeter Holm#include <pthread.h>
62*8a272653SPeter Holm#include <pthread_np.h>
63*8a272653SPeter Holm#include <sched.h>
64*8a272653SPeter Holm#include <signal.h>
65*8a272653SPeter Holm#include <stdio.h>
66*8a272653SPeter Holm#include <stdlib.h>
67*8a272653SPeter Holm#include <string.h>
68*8a272653SPeter Holm#include <time.h>
69*8a272653SPeter Holm#include <unistd.h>
70*8a272653SPeter Holm
71*8a272653SPeter Holm#define N 4096
72*8a272653SPeter Holm#define PARALLEL 50
73*8a272653SPeter Holm#define RUNTIME 180
74*8a272653SPeter Holm
75*8a272653SPeter Holmstatic u_int32_t r[N];
76*8a272653SPeter Holmstatic void *p;
77*8a272653SPeter Holm
78*8a272653SPeter Holmstatic unsigned long
79*8a272653SPeter Holmmakearg(void)
80*8a272653SPeter Holm{
81*8a272653SPeter Holm	unsigned long val;
82*8a272653SPeter Holm	unsigned int i;
83*8a272653SPeter Holm
84*8a272653SPeter Holm	val = arc4random();
85*8a272653SPeter Holm	i   = arc4random() % 100;
86*8a272653SPeter Holm	if (i < 20)
87*8a272653SPeter Holm		val = val & 0xff;
88*8a272653SPeter Holm	if (i >= 20 && i < 40)
89*8a272653SPeter Holm		val = val & 0xffff;
90*8a272653SPeter Holm	if (i >= 40 && i < 60)
91*8a272653SPeter Holm		val = (unsigned long)(r) | (val & 0xffff);
92*8a272653SPeter Holm#if defined(__LP64__)
93*8a272653SPeter Holm	if (i >= 60) {
94*8a272653SPeter Holm		val = (val << 32) | arc4random();
95*8a272653SPeter Holm		if (i > 80)
96*8a272653SPeter Holm			val = val & 0x00007fffffffffffUL;
97*8a272653SPeter Holm	}
98*8a272653SPeter Holm#endif
99*8a272653SPeter Holm
100*8a272653SPeter Holm	return (val);
101*8a272653SPeter Holm}
102*8a272653SPeter Holm
103*8a272653SPeter Holmstatic void *
104*8a272653SPeter Holmtmmap(void *arg __unused)
105*8a272653SPeter Holm{
106*8a272653SPeter Holm	size_t len;
107*8a272653SPeter Holm	time_t start;
108*8a272653SPeter Holm
109*8a272653SPeter Holm	pthread_set_name_np(pthread_self(), __func__);
110*8a272653SPeter Holm	len = 128LL * 1024 * 1024;
111*8a272653SPeter Holm
112*8a272653SPeter Holm	start = time(NULL);
113*8a272653SPeter Holm	while (time(NULL) - start < 60) {
114*8a272653SPeter Holm		if ((p = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_ANON,
115*8a272653SPeter Holm		    -1, 0)) != MAP_FAILED) {
116*8a272653SPeter Holm			usleep(100);
117*8a272653SPeter Holm			munmap(p, len);
118*8a272653SPeter Holm		}
119*8a272653SPeter Holm	}
120*8a272653SPeter Holm
121*8a272653SPeter Holm	return (NULL);
122*8a272653SPeter Holm}
123*8a272653SPeter Holm
124*8a272653SPeter Holmstatic void *
125*8a272653SPeter Holmtmlockall(void *arg __unused)
126*8a272653SPeter Holm{
127*8a272653SPeter Holm	time_t start;
128*8a272653SPeter Holm	int flags;
129*8a272653SPeter Holm
130*8a272653SPeter Holm	pthread_set_name_np(pthread_self(), __func__);
131*8a272653SPeter Holm	start = time(NULL);
132*8a272653SPeter Holm	while (time(NULL) - start < 60) {
133*8a272653SPeter Holm		flags = makearg() & 0xff;
134*8a272653SPeter Holm		mlockall(flags);
135*8a272653SPeter Holm		usleep(100);
136*8a272653SPeter Holm		munlockall();
137*8a272653SPeter Holm		usleep(1000);
138*8a272653SPeter Holm	}
139*8a272653SPeter Holm
140*8a272653SPeter Holm	return (NULL);
141*8a272653SPeter Holm}
142*8a272653SPeter Holm
143*8a272653SPeter Holmstatic void
144*8a272653SPeter Holmtest(void)
145*8a272653SPeter Holm{
146*8a272653SPeter Holm	pthread_t tid[2];
147*8a272653SPeter Holm	time_t start;
148*8a272653SPeter Holm	int i, rc;
149*8a272653SPeter Holm
150*8a272653SPeter Holm	if ((rc = pthread_create(&tid[0], NULL, tmmap, NULL)) != 0)
151*8a272653SPeter Holm		errc(1, rc, "tmmap()");
152*8a272653SPeter Holm	if ((rc = pthread_create(&tid[1], NULL, tmlockall, NULL)) != 0)
153*8a272653SPeter Holm		errc(1, rc, "tmlock()");
154*8a272653SPeter Holm
155*8a272653SPeter Holm	start = time(NULL);
156*8a272653SPeter Holm	while (time(NULL) - start < 60) {
157*8a272653SPeter Holm		if (fork() == 0) {
158*8a272653SPeter Holm			usleep(10000);
159*8a272653SPeter Holm			_exit(0);
160*8a272653SPeter Holm		}
161*8a272653SPeter Holm		wait(NULL);
162*8a272653SPeter Holm	}
163*8a272653SPeter Holm
164*8a272653SPeter Holm	for (i = 0; i < 2; i++)
165*8a272653SPeter Holm		if ((rc = pthread_join(tid[i], NULL)) != 0)
166*8a272653SPeter Holm			errc(1, rc, "pthread_join");
167*8a272653SPeter Holm	_exit(0);
168*8a272653SPeter Holm}
169*8a272653SPeter Holm
170*8a272653SPeter Holmint
171*8a272653SPeter Holmtesting(unsigned long maxl)
172*8a272653SPeter Holm{
173*8a272653SPeter Holm	struct passwd *pw;
174*8a272653SPeter Holm	struct rlimit rl;
175*8a272653SPeter Holm	rlim_t maxlock;
176*8a272653SPeter Holm	time_t start;
177*8a272653SPeter Holm	int i;
178*8a272653SPeter Holm
179*8a272653SPeter Holm	maxlock = maxl;
180*8a272653SPeter Holm	if ((pw = getpwnam("nobody")) == NULL)
181*8a272653SPeter Holm		err(1, "failed to resolve nobody");
182*8a272653SPeter Holm	if (setgroups(1, &pw->pw_gid) ||
183*8a272653SPeter Holm	    setegid(pw->pw_gid) || setgid(pw->pw_gid) ||
184*8a272653SPeter Holm	    seteuid(pw->pw_uid) || setuid(pw->pw_uid))
185*8a272653SPeter Holm		err(1, "Can't drop privileges to \"nobody\"");
186*8a272653SPeter Holm	endpwent();
187*8a272653SPeter Holm
188*8a272653SPeter Holm	rl.rlim_max = rl.rlim_cur = 0;
189*8a272653SPeter Holm	if (setrlimit(RLIMIT_CORE, &rl) == -1)
190*8a272653SPeter Holm		warn("setrlimit");
191*8a272653SPeter Holm
192*8a272653SPeter Holm	if (getrlimit(RLIMIT_MEMLOCK, &rl) == -1)
193*8a272653SPeter Holm		warn("getrlimit");
194*8a272653SPeter Holm	if (maxlock <= 0)
195*8a272653SPeter Holm		errx(1, "Argument is %jd", maxlock);
196*8a272653SPeter Holm	maxlock = (maxlock / 10 * 8) / PARALLEL * PAGE_SIZE;
197*8a272653SPeter Holm	if (maxlock < rl.rlim_cur) {
198*8a272653SPeter Holm		rl.rlim_max = rl.rlim_cur = maxlock;
199*8a272653SPeter Holm		if (setrlimit(RLIMIT_MEMLOCK, &rl) == -1)
200*8a272653SPeter Holm			warn("setrlimit");
201*8a272653SPeter Holm	}
202*8a272653SPeter Holm
203*8a272653SPeter Holm	for (i = 0; i < N; i++)
204*8a272653SPeter Holm		r[i] = arc4random();
205*8a272653SPeter Holm
206*8a272653SPeter Holm	start = time(NULL);
207*8a272653SPeter Holm	while (time(NULL) - start < RUNTIME) {
208*8a272653SPeter Holm		for (i = 0; i < PARALLEL; i++) {
209*8a272653SPeter Holm			if (fork() == 0)
210*8a272653SPeter Holm				test();
211*8a272653SPeter Holm		}
212*8a272653SPeter Holm
213*8a272653SPeter Holm		for (i = 0; i < PARALLEL; i++)
214*8a272653SPeter Holm			wait(NULL);
215*8a272653SPeter Holm	}
216*8a272653SPeter Holm
217*8a272653SPeter Holm	_exit(0);
218*8a272653SPeter Holm}
219*8a272653SPeter Holm
220*8a272653SPeter Holmint
221*8a272653SPeter Holmmain(int argc, char *argv[])
222*8a272653SPeter Holm{
223*8a272653SPeter Holm	pid_t pid;
224*8a272653SPeter Holm	size_t len;
225*8a272653SPeter Holm	int i, loops, s, status;
226*8a272653SPeter Holm	unsigned long max_wired;
227*8a272653SPeter Holm	unsigned int wire_count, wire_count_old;
228*8a272653SPeter Holm
229*8a272653SPeter Holm	s = 0;
230*8a272653SPeter Holm	if (argc != 2)
231*8a272653SPeter Holm		errx(1, "Usage: %s <loops>", argv[0]);
232*8a272653SPeter Holm	loops = atoi(argv[1]);
233*8a272653SPeter Holm
234*8a272653SPeter Holm	len = sizeof(max_wired);
235*8a272653SPeter Holm	if (sysctlbyname("vm.max_user_wired", &max_wired, &len, NULL, 0) != 0)
236*8a272653SPeter Holm		err(1, "vm.max_user_wired");
237*8a272653SPeter Holm
238*8a272653SPeter Holm	len = sizeof(wire_count);
239*8a272653SPeter Holm	if (sysctlbyname("vm.stats.vm.v_user_wire_count", &wire_count, &len,
240*8a272653SPeter Holm	    NULL, 0) != 0)
241*8a272653SPeter Holm		err(1, "vm.stats.vm.v_user_wire_count");
242*8a272653SPeter Holm
243*8a272653SPeter Holm	for (i = 0; i < loops; i++) {
244*8a272653SPeter Holm		wire_count_old = wire_count;
245*8a272653SPeter Holm
246*8a272653SPeter Holm		if ((pid = fork()) == 0)
247*8a272653SPeter Holm			testing(max_wired);
248*8a272653SPeter Holm		if (waitpid(pid, &status, 0) != pid)
249*8a272653SPeter Holm			err(1, "waitpid(%d)", pid);
250*8a272653SPeter Holm		if (status != 0)
251*8a272653SPeter Holm			errx(1, "Exit status %d from pid %d\n", status, pid);
252*8a272653SPeter Holm
253*8a272653SPeter Holm		len = sizeof(wire_count);
254*8a272653SPeter Holm		if (sysctlbyname("vm.stats.vm.v_user_wire_count", &wire_count, &len,
255*8a272653SPeter Holm		    NULL, 0) != 0)
256*8a272653SPeter Holm			err(1, "vm.stats.vm.v_user_wire_count");
257*8a272653SPeter Holm		fprintf(stderr, "vm.stats.vm.v_user_wire_count was %d, is %d. %d\n",
258*8a272653SPeter Holm		    wire_count_old, wire_count, wire_count - wire_count_old);
259*8a272653SPeter Holm	}
260*8a272653SPeter Holm
261*8a272653SPeter Holm	return (s);
262*8a272653SPeter Holm}
263