/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2002 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
/*
* University Copyright- Copyright (c) 1982, 1986, 1988
* The Regents of the University of California
* All Rights Reserved
*
* University Acknowledgment- Portions of this document are derived from
* software developed by the University of California, Berkeley, and its
* contributors.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <sys/types.h>
#include <sys/param.h>
#include <sys/sysmacros.h>
#include <sys/systm.h>
#include <sys/vmsystm.h>
#include <sys/cpuvar.h>
#include <sys/sysinfo.h>
/*
* This define represents the number of
* useful pages transferred per paging i/o operation, under the assumption
* that half of the total number is actually useful. However, if there's
* only one page transferred per operation, we assume that it's useful.
*/
#ifdef lint
#define UsefulPagesPerIO 1
#else /* lint */
#define UsefulPagesPerIO nz((MAXBSIZE/PAGESIZE)/2)
#endif /* lint */
extern int dopageout;
/* Average new into old with aging factor time */
#define ave(smooth, cnt, time) \
smooth = ((time - 1) * (smooth) + (cnt)) / (time)
/*
* pagein and pageout rates for use by swapper.
*/
ulong_t pginrate; /* 5 second average */
ulong_t pgoutrate; /* 5 second average */
static ulong_t ogpagein; /* pagein rate a sec ago */
static ulong_t ogpageout; /* pageout rate a sec ago */
/*
* Called once a second to gather statistics.
*/
void
vmmeter(void)
{
cpu_t *cp;
ulong_t gpagein, gpageout;
/*
* Compute 5 sec and 30 sec average free memory values.
*/
ave(avefree, freemem, 5);
ave(avefree30, freemem, 30);
/*
* Compute the 5 secs average of pageins and pageouts.
*/
gpagein = gpageout = 0;
cp = cpu_list;
do {
gpagein += (ulong_t)CPU_STATS(cp, vm.pgin);
gpageout += (ulong_t)CPU_STATS(cp, vm.pgout);
} while ((cp = cp->cpu_next) != cpu_list);
if ((gpagein >= ogpagein) && (gpageout >= ogpageout)) {
ave(pginrate, gpagein - ogpagein, 5);
ave(pgoutrate, gpageout - ogpageout, 5);
}
/*
* Save the current pagein/pageout values.
*/
ogpagein = gpagein;
ogpageout = gpageout;
if (!lotsfree || !dopageout)
return;
/*
* Decay deficit by the expected number of pages brought in since
* the last call (i.e., in the last second). The calculation
* assumes that one half of the pages brought in are actually
* useful (see comment above), and that half of the overall
* paging i/o activity is pageins as opposed to pageouts (the
* trailing factor of 2) It also assumes that paging i/o is done
* in units of MAXBSIZE bytes, which is a dubious assumption to
* apply to all file system types.
*/
deficit -= MIN(deficit,
MAX(deficit / 10, UsefulPagesPerIO * maxpgio / 2));
}