vm_meter.c revision 34961
11541Srgrimes/* 21541Srgrimes * Copyright (c) 1982, 1986, 1989, 1993 31541Srgrimes * The Regents of the University of California. All rights reserved. 41541Srgrimes * 51541Srgrimes * Redistribution and use in source and binary forms, with or without 61541Srgrimes * modification, are permitted provided that the following conditions 71541Srgrimes * are met: 81541Srgrimes * 1. Redistributions of source code must retain the above copyright 91541Srgrimes * notice, this list of conditions and the following disclaimer. 101541Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 111541Srgrimes * notice, this list of conditions and the following disclaimer in the 121541Srgrimes * documentation and/or other materials provided with the distribution. 131541Srgrimes * 3. All advertising materials mentioning features or use of this software 141541Srgrimes * must display the following acknowledgement: 151541Srgrimes * This product includes software developed by the University of 161541Srgrimes * California, Berkeley and its contributors. 171541Srgrimes * 4. Neither the name of the University nor the names of its contributors 181541Srgrimes * may be used to endorse or promote products derived from this software 191541Srgrimes * without specific prior written permission. 201541Srgrimes * 211541Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 221541Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 231541Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 241541Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 251541Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 261541Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 271541Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 281541Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 291541Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 301541Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 311541Srgrimes * SUCH DAMAGE. 321541Srgrimes * 331541Srgrimes * @(#)vm_meter.c 8.4 (Berkeley) 1/4/94 3434961Sphk * $Id: vm_meter.c,v 1.24 1998/03/28 10:33:27 bde Exp $ 351541Srgrimes */ 361541Srgrimes 371541Srgrimes#include <sys/param.h> 381541Srgrimes#include <sys/proc.h> 391541Srgrimes#include <sys/systm.h> 401541Srgrimes#include <sys/kernel.h> 4134924Sbde#include <sys/resource.h> 4212662Sdg#include <sys/vmmeter.h> 4312662Sdg 441541Srgrimes#include <vm/vm.h> 4512726Sbde#include <vm/vm_extern.h> 4612662Sdg#include <vm/vm_param.h> 4722521Sdyson#include <sys/lock.h> 4812662Sdg#include <vm/pmap.h> 4912662Sdg#include <vm/vm_map.h> 5012662Sdg#include <vm/vm_object.h> 511541Srgrimes#include <sys/sysctl.h> 521541Srgrimes 5312623Sphkstruct loadavg averunnable = 5412623Sphk { {0, 0, 0}, FSCALE }; /* load average, of runnable procs */ 5512623Sphk 569759Sbdestruct vmmeter cnt; 571541Srgrimes 5812820Sphkstatic int maxslp = MAXSLP; 591541Srgrimes 601541Srgrimes/* 611541Srgrimes * Constants for averages over 1, 5, and 15 minutes 621541Srgrimes * when sampling at 5 second intervals. 631541Srgrimes */ 6412820Sphkstatic fixpt_t cexp[3] = { 651541Srgrimes 0.9200444146293232 * FSCALE, /* exp(-1/12) */ 661541Srgrimes 0.9834714538216174 * FSCALE, /* exp(-1/60) */ 671541Srgrimes 0.9944598480048967 * FSCALE, /* exp(-1/180) */ 681541Srgrimes}; 691541Srgrimes 701541Srgrimes/* 711541Srgrimes * Compute a tenex style load average of a quantity on 721541Srgrimes * 1, 5 and 15 minute intervals. 731541Srgrimes */ 749507Sdgstatic void 7512286Sphkloadav(struct loadavg *avg) 761541Srgrimes{ 771541Srgrimes register int i, nrun; 781541Srgrimes register struct proc *p; 791541Srgrimes 8014531Shsu for (nrun = 0, p = allproc.lh_first; p != 0; p = p->p_list.le_next) { 811541Srgrimes switch (p->p_stat) { 821541Srgrimes case SSLEEP: 831541Srgrimes if (p->p_priority > PZERO || p->p_slptime != 0) 841541Srgrimes continue; 851541Srgrimes /* fall through */ 861541Srgrimes case SRUN: 871541Srgrimes case SIDL: 881541Srgrimes nrun++; 891541Srgrimes } 901541Srgrimes } 911541Srgrimes for (i = 0; i < 3; i++) 921541Srgrimes avg->ldavg[i] = (cexp[i] * avg->ldavg[i] + 935455Sdg nrun * FSCALE * (FSCALE - cexp[i])) >> FSHIFT; 941541Srgrimes} 951541Srgrimes 969507Sdgvoid 979507Sdgvmmeter() 989507Sdg{ 999507Sdg 10034961Sphk if (time_second % 5 == 0) 1019507Sdg loadav(&averunnable); 1029507Sdg if (proc0.p_slptime > maxslp / 2) 1039507Sdg wakeup(&proc0); 1049507Sdg} 1059507Sdg 10612286SphkSYSCTL_INT(_vm, VM_V_FREE_MIN, v_free_min, 10712286Sphk CTLFLAG_RW, &cnt.v_free_min, 0, ""); 10812286SphkSYSCTL_INT(_vm, VM_V_FREE_TARGET, v_free_target, 10912286Sphk CTLFLAG_RW, &cnt.v_free_target, 0, ""); 11012286SphkSYSCTL_INT(_vm, VM_V_FREE_RESERVED, v_free_reserved, 11112286Sphk CTLFLAG_RW, &cnt.v_free_reserved, 0, ""); 11212286SphkSYSCTL_INT(_vm, VM_V_INACTIVE_TARGET, v_inactive_target, 11312286Sphk CTLFLAG_RW, &cnt.v_inactive_target, 0, ""); 11412286SphkSYSCTL_INT(_vm, VM_V_CACHE_MIN, v_cache_min, 11512286Sphk CTLFLAG_RW, &cnt.v_cache_min, 0, ""); 11612286SphkSYSCTL_INT(_vm, VM_V_CACHE_MAX, v_cache_max, 11712286Sphk CTLFLAG_RW, &cnt.v_cache_max, 0, ""); 11812286SphkSYSCTL_INT(_vm, VM_V_PAGEOUT_FREE_MIN, v_pageout_free_min, 11912286Sphk CTLFLAG_RW, &cnt.v_pageout_free_min, 0, ""); 12012286Sphk 12112623SphkSYSCTL_STRUCT(_vm, VM_LOADAVG, loadavg, CTLFLAG_RD, &averunnable, loadavg, ""); 1221541Srgrimes 12312286Sphkstatic int 12412286Sphkvmtotal SYSCTL_HANDLER_ARGS 1251541Srgrimes{ 12612286Sphk struct proc *p; 12712286Sphk struct vmtotal total, *totalp; 12812286Sphk vm_map_entry_t entry; 12912286Sphk vm_object_t object; 13012286Sphk vm_map_t map; 1311541Srgrimes int paging; 1321541Srgrimes 13312286Sphk totalp = &total; 1341541Srgrimes bzero(totalp, sizeof *totalp); 1351541Srgrimes /* 1361541Srgrimes * Mark all objects as inactive. 1371541Srgrimes */ 13815809Sdyson for (object = TAILQ_FIRST(&vm_object_list); 1395455Sdg object != NULL; 14015809Sdyson object = TAILQ_NEXT(object,object_list)) 1411541Srgrimes object->flags &= ~OBJ_ACTIVE; 1421541Srgrimes /* 1431541Srgrimes * Calculate process statistics. 1441541Srgrimes */ 14514531Shsu for (p = allproc.lh_first; p != 0; p = p->p_list.le_next) { 1461541Srgrimes if (p->p_flag & P_SYSTEM) 1471541Srgrimes continue; 1481541Srgrimes switch (p->p_stat) { 1491541Srgrimes case 0: 1501541Srgrimes continue; 1511541Srgrimes 1521541Srgrimes case SSLEEP: 1531541Srgrimes case SSTOP: 1541541Srgrimes if (p->p_flag & P_INMEM) { 1551541Srgrimes if (p->p_priority <= PZERO) 1561541Srgrimes totalp->t_dw++; 1571541Srgrimes else if (p->p_slptime < maxslp) 1581541Srgrimes totalp->t_sl++; 1591541Srgrimes } else if (p->p_slptime < maxslp) 1601541Srgrimes totalp->t_sw++; 1611541Srgrimes if (p->p_slptime >= maxslp) 1621541Srgrimes continue; 1631541Srgrimes break; 1641541Srgrimes 1651541Srgrimes case SRUN: 1661541Srgrimes case SIDL: 1671541Srgrimes if (p->p_flag & P_INMEM) 1681541Srgrimes totalp->t_rq++; 1691541Srgrimes else 1701541Srgrimes totalp->t_sw++; 1711541Srgrimes if (p->p_stat == SIDL) 1721541Srgrimes continue; 1731541Srgrimes break; 1741541Srgrimes } 1751541Srgrimes /* 1761541Srgrimes * Note active objects. 1771541Srgrimes */ 1781541Srgrimes paging = 0; 1791541Srgrimes for (map = &p->p_vmspace->vm_map, entry = map->header.next; 1805455Sdg entry != &map->header; entry = entry->next) { 18121754Sdyson if ((entry->eflags & (MAP_ENTRY_IS_A_MAP|MAP_ENTRY_IS_SUB_MAP)) || 1821541Srgrimes entry->object.vm_object == NULL) 1831541Srgrimes continue; 1841541Srgrimes entry->object.vm_object->flags |= OBJ_ACTIVE; 1851541Srgrimes paging |= entry->object.vm_object->paging_in_progress; 1861541Srgrimes } 1871541Srgrimes if (paging) 1881541Srgrimes totalp->t_pw++; 1891541Srgrimes } 1901541Srgrimes /* 1911541Srgrimes * Calculate object memory usage statistics. 1921541Srgrimes */ 19315809Sdyson for (object = TAILQ_FIRST(&vm_object_list); 1945455Sdg object != NULL; 19515809Sdyson object = TAILQ_NEXT(object, object_list)) { 19618169Sdyson totalp->t_vm += object->size; 1971541Srgrimes totalp->t_rm += object->resident_page_count; 1981541Srgrimes if (object->flags & OBJ_ACTIVE) { 19918169Sdyson totalp->t_avm += object->size; 2001541Srgrimes totalp->t_arm += object->resident_page_count; 2011541Srgrimes } 20218169Sdyson if (object->shadow_count > 1) { 2031541Srgrimes /* shared object */ 20418169Sdyson totalp->t_vmshr += object->size; 2051541Srgrimes totalp->t_rmshr += object->resident_page_count; 2061541Srgrimes if (object->flags & OBJ_ACTIVE) { 20718169Sdyson totalp->t_avmshr += object->size; 2081541Srgrimes totalp->t_armshr += object->resident_page_count; 2091541Srgrimes } 2101541Srgrimes } 2111541Srgrimes } 2125455Sdg totalp->t_free = cnt.v_free_count + cnt.v_cache_count; 21312286Sphk return (sysctl_handle_opaque(oidp, totalp, sizeof total, req)); 2141541Srgrimes} 21512286Sphk 21612286SphkSYSCTL_PROC(_vm, VM_METER, vmmeter, CTLTYPE_OPAQUE|CTLFLAG_RD, 21712623Sphk 0, sizeof(struct vmtotal), vmtotal, "S,vmtotal", ""); 218