root/usr/src/uts/common/os/vm_meter.c
/*
 * 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.
 */

#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));
}