xref: /freebsd/tools/test/stress2/misc/swapoff5.sh (revision 4d846d260e2b9a3d4d0a701462568268cbfe7a5b)
18a272653SPeter Holm#!/bin/sh
28a272653SPeter Holm
38a272653SPeter Holm#
4*4d846d26SWarner Losh# SPDX-License-Identifier: BSD-2-Clause
58a272653SPeter Holm#
68a272653SPeter Holm# Copyright (c) 2020 Mark Johnston
78a272653SPeter Holm#
88a272653SPeter Holm# Redistribution and use in source and binary forms, with or without
98a272653SPeter Holm# modification, are permitted provided that the following conditions
108a272653SPeter Holm# are met:
118a272653SPeter Holm# 1. Redistributions of source code must retain the above copyright
128a272653SPeter Holm#    notice, this list of conditions and the following disclaimer.
138a272653SPeter Holm# 2. Redistributions in binary form must reproduce the above copyright
148a272653SPeter Holm#    notice, this list of conditions and the following disclaimer in the
158a272653SPeter Holm#    documentation and/or other materials provided with the distribution.
168a272653SPeter Holm#
178a272653SPeter Holm# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
188a272653SPeter Holm# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
198a272653SPeter Holm# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
208a272653SPeter Holm# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
218a272653SPeter Holm# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
228a272653SPeter Holm# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
238a272653SPeter Holm# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
248a272653SPeter Holm# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
258a272653SPeter Holm# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
268a272653SPeter Holm# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
278a272653SPeter Holm# SUCH DAMAGE.
288a272653SPeter Holm#
298a272653SPeter Holm
308a272653SPeter Holm# Variation of swapoff3.sh
318a272653SPeter Holm
328a272653SPeter Holm# Deadlock seen:
338a272653SPeter Holm# https://people.freebsd.org/~pho/stress/log/log0005.txt
348a272653SPeter Holm# This is a "known" low memory deadlocks caused by using md(4) as a swap
358a272653SPeter Holm# device.
368a272653SPeter Holm
378a272653SPeter Holm. ../default.cfg
388a272653SPeter Holm[ `id -u` -ne 0 ] && echo "Must be root!" && exit 1
398a272653SPeter Holmdir=`dirname $diskimage`
408a272653SPeter Holm[ `df -k $dir | tail -1 | awk '{print $4}'` -lt \
418a272653SPeter Holm    $((20 * 1024 * 1024)) ] &&
428a272653SPeter Holm    { echo "Need 20GB on $dir"; exit 0; }
438a272653SPeter Holm
448a272653SPeter Holmcat > /tmp/swapoff5.c <<EOF
458a272653SPeter Holm#include <sys/param.h>
468a272653SPeter Holm#include <sys/mman.h>
478a272653SPeter Holm#include <sys/sysctl.h>
488a272653SPeter Holm
498a272653SPeter Holm#include <assert.h>
508a272653SPeter Holm#include <err.h>
518a272653SPeter Holm#include <stdlib.h>
528a272653SPeter Holm#include <unistd.h>
538a272653SPeter Holm
548a272653SPeter Holmint
558a272653SPeter Holmmain(void)
568a272653SPeter Holm{
578a272653SPeter Holm	char *addr, *naddr, *res;
588a272653SPeter Holm	size_t i, len, swap, vsz;
598a272653SPeter Holm	u_int free;
608a272653SPeter Holm
618a272653SPeter Holm	vsz = sizeof(free);
628a272653SPeter Holm	if (sysctlbyname("vm.stats.vm.v_free_count", &free, &vsz, NULL, 0) != 0)
638a272653SPeter Holm		err(1, "sysctl(vm.stats.vm.v_free_count)");
648a272653SPeter Holm	vsz = sizeof(swap);
658a272653SPeter Holm	if (sysctlbyname("vm.swap_total", &swap, &vsz, NULL, 0) != 0)
668a272653SPeter Holm		err(1, "sysctl(vm.swap_total)");
678a272653SPeter Holm
688a272653SPeter Holm	len = (size_t)free * PAGE_SIZE + swap / 4;
698a272653SPeter Holm	addr = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE,
708a272653SPeter Holm	    -1, 0);
718a272653SPeter Holm	if (addr == MAP_FAILED)
728a272653SPeter Holm		err(1, "mmap");
738a272653SPeter Holm
748a272653SPeter Holm	res = malloc(howmany(len, PAGE_SIZE));
758a272653SPeter Holm	if (res == NULL)
768a272653SPeter Holm		err(1, "malloc");
778a272653SPeter Holm
788a272653SPeter Holm	for (i = 0; i < len; i += PAGE_SIZE)
798a272653SPeter Holm		addr[i] = 1;
808a272653SPeter Holm
818a272653SPeter Holm	for (;;) {
828a272653SPeter Holm		if (mincore(addr, len, res) != 0)
838a272653SPeter Holm			err(1, "mincore");
848a272653SPeter Holm		for (i = 0; i < howmany(len, PAGE_SIZE); i++)
858a272653SPeter Holm			if ((res[i] & MINCORE_INCORE) == 0) {
868a272653SPeter Holm				naddr = addr + i * PAGE_SIZE;
878a272653SPeter Holm				if (munmap(naddr, PAGE_SIZE) != 0)
888a272653SPeter Holm					err(1, "munmap");
898a272653SPeter Holm				if (mmap(naddr, PAGE_SIZE,
908a272653SPeter Holm				    PROT_READ | PROT_WRITE,
918a272653SPeter Holm				    MAP_ANON | MAP_PRIVATE | MAP_FIXED,
928a272653SPeter Holm				    -1, 0) == MAP_FAILED)
938a272653SPeter Holm					err(1, "mmap");
948a272653SPeter Holm				assert(*naddr == 0);
958a272653SPeter Holm				*naddr = 1;
968a272653SPeter Holm			}
978a272653SPeter Holm	}
988a272653SPeter Holm
998a272653SPeter Holm	return (0);
1008a272653SPeter Holm}
1018a272653SPeter HolmEOF
1028a272653SPeter Holmmycc -o /tmp/swapoff5 -Wall -Wextra -O2 -g /tmp/swapoff5.c || exit
1038a272653SPeter Holm
1048a272653SPeter Holmcat > /tmp/swapoff5x.c <<EOF
1058a272653SPeter Holm#include <sys/mman.h>
1068a272653SPeter Holm
1078a272653SPeter Holm#include <err.h>
1088a272653SPeter Holm#include <stdio.h>
1098a272653SPeter Holm#include <stdlib.h>
1108a272653SPeter Holm#include <time.h>
1118a272653SPeter Holm
1128a272653SPeter Holmint
1138a272653SPeter Holmmain(int argc, char *argv[])
1148a272653SPeter Holm{
1158a272653SPeter Holm	time_t start;
1168a272653SPeter Holm	int n, r;
1178a272653SPeter Holm	char off1[80], off2[80], on1[80], on2[80];
1188a272653SPeter Holm
1198a272653SPeter Holm	if ( argc != 3) {
1208a272653SPeter Holm		fprintf(stderr, "Usage: %s <dev1> <dev2>\n", argv[0]);
1218a272653SPeter Holm		exit(1);
1228a272653SPeter Holm	}
1238a272653SPeter Holm
1248a272653SPeter Holm	snprintf(off1, sizeof(off1), "swapoff %s", argv[1]);
1258a272653SPeter Holm	snprintf(off2, sizeof(off2), "swapoff %s", argv[2]);
1268a272653SPeter Holm	snprintf(on1, sizeof(on1), "swapon %s", argv[1]);
1278a272653SPeter Holm	snprintf(on2, sizeof(on2), "swapon %s", argv[2]);
1288a272653SPeter Holm
1298a272653SPeter Holm	start = time(NULL);
1308a272653SPeter Holm	if (mlockall(MCL_CURRENT | MCL_FUTURE) == -1)
1318a272653SPeter Holm		err(1, "mlockall(MCL_CURRENT) | MCL_FUTURE");
1328a272653SPeter Holm	n = 0;
1338a272653SPeter Holm	while (time(NULL) - start < 240) {
1348a272653SPeter Holm		if ((r = system(off1)) != 0)
1358a272653SPeter Holm			errx(1, "%s failed with %d", off1, r);
1368a272653SPeter Holm		if ((r = system(on1)) != 0)
1378a272653SPeter Holm			errx(1, "%s failed with %d", on1, r);
1388a272653SPeter Holm		if ((r = system(off2)) != 0)
1398a272653SPeter Holm			errx(1, "%s failed with %d", off2, r);
1408a272653SPeter Holm		if ((r = system(on2)) != 0)
1418a272653SPeter Holm			errx(1, "%s failed with %d", on2, r);
1428a272653SPeter Holm		n++;
1438a272653SPeter Holm	}
1448a272653SPeter Holm	if (n < 100)
1458a272653SPeter Holm		fprintf(stderr, "%d swapoffs\n", n);
1468a272653SPeter Holm
1478a272653SPeter Holm	return (0);
1488a272653SPeter Holm}
1498a272653SPeter HolmEOF
1508a272653SPeter Holmmycc -o /tmp/swapoff5x -Wall -Wextra -O2 -g /tmp/swapoff5x.c || exit
1518a272653SPeter Holm
1528a272653SPeter Holmset -e
1538a272653SPeter Holmmd1=$mdstart
1548a272653SPeter Holmmd2=$((md1 + 1))
1558a272653SPeter Holm[ `sysctl -n vm.swap_total` -gt 0 ] && { swapoff -a > /dev/null; off=1; }
1568a272653SPeter Holmtruncate -s 10G $dir/swap1
1578a272653SPeter Holmmdconfig -a -t vnode -f $dir/swap1 -u $md1
1588a272653SPeter Holmswapon /dev/md$md1
1598a272653SPeter Holmtruncate -s 10G $dir/swap2
1608a272653SPeter Holmmdconfig -a -t vnode -f $dir/swap2 -u $md2
1618a272653SPeter Holmswapon /dev/md$md2
1628a272653SPeter Holmset +e
1638a272653SPeter Holm
1648a272653SPeter Holmtimeout 4m /tmp/swapoff5 &
1658a272653SPeter Holmfor i in `jot 60`; do
1668a272653SPeter Holm	n=`swapinfo | tail -1 | awk '{print $3}'`
1678a272653SPeter Holm	[ $n -gt 0 ] && break
1688a272653SPeter Holm	sleep 1
1698a272653SPeter Holmdone
1708a272653SPeter Holm
1718a272653SPeter Holm/tmp/swapoff5x /dev/md$md1 /dev/md$md2
1728a272653SPeter Holmkill $! > /dev/null 2>&1
1738a272653SPeter Holmwait
1748a272653SPeter Holmfor dev in /dev/md$md1 /dev/md$md2; do
1758a272653SPeter Holm	swapoff $dev
1768a272653SPeter Holmdone
1778a272653SPeter Holmmdconfig -d -u $md1
1788a272653SPeter Holmmdconfig -d -u $md2
1798a272653SPeter Holmrm -f $dir/swap1 $dir/swap2 /tmp/swapoff5 /tmp/swapoff5.c /tmp/swapoff5x \
1808a272653SPeter Holm    /tmp/swapoff5x.c
1818a272653SPeter Holm[ $off ] && swapon -a > /dev/null
1828a272653SPeter Holmexit $s
183