Path: blob/main/tools/test/stress2/misc/contigmalloc.sh
39536 views
#!/bin/sh12#3# Copyright (c) 2014 EMC Corp.4# All rights reserved.5#6# Redistribution and use in source and binary forms, with or without7# modification, are permitted provided that the following conditions8# are met:9# 1. Redistributions of source code must retain the above copyright10# notice, this list of conditions and the following disclaimer.11# 2. Redistributions in binary form must reproduce the above copyright12# notice, this list of conditions and the following disclaimer in the13# documentation and/or other materials provided with the distribution.14#15# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND16# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE17# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE18# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE19# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL20# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS21# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)22# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT23# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY24# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF25# SUCH DAMAGE.26#2728# contigmalloc(9) / free(9) test scenario.29# malloc() a random number of buffers with random size and then free them.3031# A malloc pattern might look like this:32# contigmalloc(186 pages)33# contigmalloc(56 pages)34# contigmalloc(9 pages)35# contigmalloc(202 pages)36# contigmalloc(49 pages)37# contigmalloc(5 pages)3839# "panic: vm_reserv_alloc_contig: reserv 0xff... isn't free" seen.40# http://people.freebsd.org/~pho/stress/log/contigmalloc.txt41# Fixed by r271351.4243[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 144[ -d /usr/src/sys ] || exit 045builddir=`sysctl kern.version | grep @ | sed 's/.*://'`46[ -d "$builddir" ] && export KERNBUILDDIR=$builddir || exit 047export SYSDIR=`echo $builddir | sed 's#/sys.*#/sys#'`4849. ../default.cfg5051odir=`pwd`52dir=/tmp/contigmalloc53rm -rf $dir; mkdir -p $dir54cat > $dir/ctest.c <<EOF55#include <sys/param.h>56#include <sys/syscall.h>5758#include <err.h>59#include <stdio.h>60#include <stdlib.h>61#include <time.h>62#include <unistd.h>6364#define min(a,b) (((a)<(b))?(a):(b))65#define CAP (64 * 1024 * 1024) /* Total allocation */66#define MAXBUF (32 * 1024 * 1024) /* Max buffer size */67#define N 512 /* Max allocations */68#define RUNTIME 12069#define TALLOC 170#define TFREE 27172void *p[N];73long size[N];74int n;7576void77test(int argc, char *argv[])78{79long mw, s;80int i, no, ps, res;8182if (argc == 3) {83no = atoi(argv[1]);84mw = atol(argv[2]);85}86if (argc != 3 || no == 0 || mw == 0)87errx(1, "Usage: %s <syscall number> <max wired>", argv[0]);8889ps = getpagesize();90s = 0;91n = arc4random() % N + 1;92mw = mw / 100 * 10 * ps; /* Use 10% of vm.max_user_wired */93mw = min(mw, CAP);94for (i = 0; i < n; i++) {95size[i] = round_page((arc4random() % MAXBUF) + 1);96if (s + size[i] > mw)97continue;98res = syscall(no, TALLOC, &p[i], &size[i]);99if (res == -1) {100warn("contigmalloc(%lu pages) failed at loop %d",101size[i] / ps, i);102usleep(200000);103} else {104#if defined(TEST)105fprintf(stderr, "contigmalloc(%lu pages)\n",106size[i] / ps);107#endif108s += size[i];109}110}111112setproctitle("%ld Mb", s / 1024 / 1024);113114for (i = 0; i < n; i++) {115if (p[i] != NULL) {116res = syscall(no, TFREE, &p[i], &size[i]);117#if defined(TEST)118fprintf(stderr, "free(%lu pages)\n",119size[i] / ps);120#endif121p[i] = NULL;122}123}124}125126int127main(int argc, char *argv[])128{129time_t start;130131start = time(NULL);132while (time(NULL) - start < RUNTIME)133test(argc, argv);134135return (0);136}137138EOF139mycc -o /tmp/ctest -Wall -Wextra -O0 -g $dir/ctest.c || exit 1140rm $dir/ctest.c141142cd $dir143cat > Makefile <<EOF144KMOD= cmalloc145SRCS= cmalloc.c146147.include <bsd.kmod.mk>148EOF149150sed '1,/^EOF2/d' < $odir/$0 > cmalloc.c151make || exit 1152kldload $dir/cmalloc.ko || exit 1153154cd $odir155mw=`sysctl -n vm.max_user_wired` || exit 1156/tmp/ctest `sysctl -n debug.cmalloc_offset` $mw 2>&1 | tail -5157kldunload $dir/cmalloc.ko158rm -rf $dir /tmp/ctest159exit 0160161EOF2162#include <sys/param.h>163#include <sys/kernel.h>164#include <sys/malloc.h>165#include <sys/module.h>166#include <sys/proc.h>167#include <sys/sysctl.h>168#include <sys/sysent.h>169#include <sys/sysproto.h>170#include <sys/systm.h>171172#define TALLOC 1173#define TFREE 2174175/*176* Hook up a syscall for contigmalloc testing.177*/178179struct cmalloc_args {180int a_op;181void *a_ptr;182void *a_size;183};184185static int186cmalloc(struct thread *td, struct cmalloc_args *uap)187{188void *p;189unsigned long size;190int error;191192error = copyin(uap->a_size, &size, sizeof(size));193if (error != 0) {194return (error);195}196switch (uap->a_op) {197case TFREE:198error = copyin(uap->a_ptr, &p, sizeof(p));199if (error == 0)200free(p, M_TEMP);201return (error);202203case TALLOC:204p = contigmalloc(size, M_TEMP, M_NOWAIT, 0ul, ~0ul, 4096, 0);205if (p != NULL) {206error = copyout(&p, uap->a_ptr, sizeof(p));207return (error);208}209return (ENOMEM);210}211return (EINVAL);212}213214/*215* The sysent for the new syscall216*/217static struct sysent cmalloc_sysent = {218.sy_narg = 3, /* sy_narg */219.sy_call = (sy_call_t *) cmalloc /* sy_call */220};221222/*223* The offset in sysent where the syscall is allocated.224*/225static int cmalloc_offset = NO_SYSCALL;226227SYSCTL_INT(_debug, OID_AUTO, cmalloc_offset, CTLFLAG_RD, &cmalloc_offset, 0,228"cmalloc syscall number");229230/*231* The function called at load/unload.232*/233234static int235cmalloc_load(struct module *module, int cmd, void *arg)236{237int error = 0;238239switch (cmd) {240case MOD_LOAD :241break;242case MOD_UNLOAD :243break;244default :245error = EOPNOTSUPP;246break;247}248return (error);249}250251SYSCALL_MODULE(cmalloc_syscall, &cmalloc_offset, &cmalloc_sysent,252cmalloc_load, NULL);253254255