Path: blob/main/tools/test/stress2/misc/contigmalloc2.sh
39537 views
#!/bin/sh12#3# Copyright (c) 2015 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# Regression test for allocations >= 2 GiB.30# "panic: vm_page_insert_after: mpred doesn't precede pindex" seen.31# Fixed by r284207.3233[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 134[ -d /usr/src/sys ] || exit 035builddir=`sysctl kern.version | grep @ | sed 's/.*://'`36[ -d "$builddir" ] && export KERNBUILDDIR=$builddir || exit 037export SYSDIR=`echo $builddir | sed 's#/sys.*#/sys#'`3839. ../default.cfg4041odir=`pwd`42dir=/tmp/contigmalloc43rm -rf $dir; mkdir -p $dir44cat > $dir/ctest2.c <<EOF45#include <sys/param.h>46#include <sys/syscall.h>4748#include <err.h>49#include <errno.h>50#include <stdio.h>51#include <stdlib.h>52#include <unistd.h>5354#define TALLOC 155#define TFREE 25657void *p;58long size;59int n;6061void62test(int argc, char *argv[])63{64long mw;65int no, ps, res;6667if (argc == 3) {68no = atoi(argv[1]);69mw = atol(argv[2]);70}71if (argc != 3 || no == 0 || mw == 0)72errx(1, "Usage: %s <syscall number> <max wired>", argv[0]);7374ps = getpagesize();75size = mw / 100 * 80 * ps; /* Use 80% of vm.max_user_wired */76while (size > 0) {77res = syscall(no, TALLOC, &p, &size);78if (res == -1) {79if (errno != ENOMEM)80warn("contigmalloc(%lu pages) failed",81size);82} else {83#if defined(TEST)84fprintf(stderr, "pre contigmalloc(%lu pages): %lu MiB\n",85size, size * ps / 1024 / 1024);86#endif87res = syscall(no, TFREE, &p, &size);88#if defined(TEST)89fprintf(stderr, "free(%lu pages)\n", size);90#endif91}92size /= 2;93}94}9596int97main(int argc, char *argv[])98{99test(argc, argv);100101return (0);102}103104EOF105mycc -o /tmp/ctest2 -Wall -Wextra -O0 -g $dir/ctest2.c || exit 1106rm $dir/ctest2.c107108cd $dir109cat > Makefile <<EOF110KMOD= cmalloc2111SRCS= cmalloc2.c112113.include <bsd.kmod.mk>114EOF115116sed '1,/^EOF2/d' < $odir/$0 > cmalloc2.c117make depend all || exit 1118kldload $dir/cmalloc2.ko || exit 1119120cd $odir121mw=$((`sysctl -n vm.max_user_wired` - \122`sysctl -n vm.stats.vm.v_user_wire_count`)) || exit 1123/tmp/ctest2 `sysctl -n debug.cmalloc_offset` $mw #2>&1 | tail -5124kldunload $dir/cmalloc2.ko125rm -rf $dir /tmp/ctest2126exit 0127128EOF2129#include <sys/param.h>130#include <sys/kernel.h>131#include <sys/malloc.h>132#include <sys/module.h>133#include <sys/proc.h>134#include <sys/sysctl.h>135#include <sys/sysent.h>136#include <sys/sysproto.h>137#include <sys/systm.h>138139#define TALLOC 1140#define TFREE 2141142/*143* Hook up a syscall for contigmalloc testing.144*/145146struct cmalloc_args {147int a_op;148void *a_ptr;149void *a_size;150};151152static int153cmalloc(struct thread *td, struct cmalloc_args *uap)154{155void *p;156unsigned long size;157int error;158159error = copyin(uap->a_size, &size, sizeof(size));160if (error != 0) {161return (error);162}163switch (uap->a_op) {164case TFREE:165error = copyin(uap->a_ptr, &p, sizeof(p));166if (error == 0)167free(p, M_TEMP);168return (error);169170case TALLOC:171p = contigmalloc(size, M_TEMP, M_NOWAIT, 0ul, ~0ul, 4096, 0);172if (p != NULL) {173error = copyout(&p, uap->a_ptr, sizeof(p));174return (error);175}176return (ENOMEM);177}178return (EINVAL);179}180181/*182* The sysent for the new syscall183*/184static struct sysent cmalloc_sysent = {185.sy_narg = 3, /* sy_narg */186.sy_call = (sy_call_t *) cmalloc /* sy_call */187};188189/*190* The offset in sysent where the syscall is allocated.191*/192static int cmalloc_offset = NO_SYSCALL;193194SYSCTL_INT(_debug, OID_AUTO, cmalloc_offset, CTLFLAG_RD, &cmalloc_offset, 0,195"cmalloc syscall number");196197/*198* The function called at load/unload.199*/200201static int202cmalloc_load(struct module *module, int cmd, void *arg)203{204int error = 0;205206switch (cmd) {207case MOD_LOAD :208break;209case MOD_UNLOAD :210break;211default :212error = EOPNOTSUPP;213break;214}215return (error);216}217218SYSCALL_MODULE(cmalloc_syscall, &cmalloc_offset, &cmalloc_sysent,219cmalloc_load, NULL);220221222