vm_meter.c revision 248084
1151497Sru/*- 2151497Sru * Copyright (c) 1982, 1986, 1989, 1993 3151497Sru * The Regents of the University of California. All rights reserved. 475584Sru * 5151497Sru * Redistribution and use in source and binary forms, with or without 6151497Sru * modification, are permitted provided that the following conditions 7151497Sru * are met: 8151497Sru * 1. Redistributions of source code must retain the above copyright 9151497Sru * notice, this list of conditions and the following disclaimer. 10151497Sru * 2. Redistributions in binary form must reproduce the above copyright 11151497Sru * notice, this list of conditions and the following disclaimer in the 12151497Sru * documentation and/or other materials provided with the distribution. 13151497Sru * 4. Neither the name of the University nor the names of its contributors 14151497Sru * may be used to endorse or promote products derived from this software 15151497Sru * without specific prior written permission. 16151497Sru * 17151497Sru * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 18151497Sru * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19151497Sru * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20151497Sru * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 21151497Sru * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22151497Sru * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23151497Sru * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24151497Sru * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25151497Sru * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26151497Sru * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27151497Sru * SUCH DAMAGE. 28151497Sru * 29151497Sru * @(#)vm_meter.c 8.4 (Berkeley) 1/4/94 30151497Sru */ 31151497Sru 32151497Sru#include <sys/cdefs.h> 33151497Sru__FBSDID("$FreeBSD: head/sys/vm/vm_meter.c 248084 2013-03-09 02:32:23Z attilio $"); 34151497Sru 35151497Sru#include <sys/param.h> 36151497Sru#include <sys/systm.h> 37151497Sru#include <sys/kernel.h> 38151497Sru#include <sys/lock.h> 39151497Sru#include <sys/mutex.h> 40151497Sru#include <sys/proc.h> 41151497Sru#include <sys/resource.h> 42151497Sru#include <sys/rwlock.h> 43151497Sru#include <sys/sx.h> 44151497Sru#include <sys/vmmeter.h> 45151497Sru#include <sys/smp.h> 46151497Sru 47151497Sru#include <vm/vm.h> 48151497Sru#include <vm/vm_page.h> 49151497Sru#include <vm/vm_extern.h> 50151497Sru#include <vm/vm_param.h> 51151497Sru#include <vm/pmap.h> 52151497Sru#include <vm/vm_map.h> 53151497Sru#include <vm/vm_object.h> 54151497Sru#include <sys/sysctl.h> 55151497Sru 56151497Srustruct vmmeter cnt; 57151497Sru 58151497SruSYSCTL_UINT(_vm, VM_V_FREE_MIN, v_free_min, 59151497Sru CTLFLAG_RW, &cnt.v_free_min, 0, "Minimum low-free-pages threshold"); 60151497SruSYSCTL_UINT(_vm, VM_V_FREE_TARGET, v_free_target, 61151497Sru CTLFLAG_RW, &cnt.v_free_target, 0, "Desired free pages"); 62151497SruSYSCTL_UINT(_vm, VM_V_FREE_RESERVED, v_free_reserved, 63151497Sru CTLFLAG_RW, &cnt.v_free_reserved, 0, "Pages reserved for deadlock"); 64151497SruSYSCTL_UINT(_vm, VM_V_INACTIVE_TARGET, v_inactive_target, 65151497Sru CTLFLAG_RW, &cnt.v_inactive_target, 0, "Pages desired inactive"); 66151497SruSYSCTL_UINT(_vm, VM_V_CACHE_MIN, v_cache_min, 67151497Sru CTLFLAG_RW, &cnt.v_cache_min, 0, "Min pages on cache queue"); 68151497SruSYSCTL_UINT(_vm, VM_V_CACHE_MAX, v_cache_max, 69151497Sru CTLFLAG_RW, &cnt.v_cache_max, 0, "Max pages on cache queue"); 70151497SruSYSCTL_UINT(_vm, VM_V_PAGEOUT_FREE_MIN, v_pageout_free_min, 71151497Sru CTLFLAG_RW, &cnt.v_pageout_free_min, 0, "Min pages reserved for kernel"); 72151497SruSYSCTL_UINT(_vm, OID_AUTO, v_free_severe, 73151497Sru CTLFLAG_RW, &cnt.v_free_severe, 0, "Severe page depletion point"); 74151497Sru 75151497Srustatic int 76151497Srusysctl_vm_loadavg(SYSCTL_HANDLER_ARGS) 77151497Sru{ 78151497Sru 79151497Sru#ifdef SCTL_MASK32 80151497Sru u_int32_t la[4]; 81151497Sru 82151497Sru if (req->flags & SCTL_MASK32) { 83151497Sru la[0] = averunnable.ldavg[0]; 84151497Sru la[1] = averunnable.ldavg[1]; 85151497Sru la[2] = averunnable.ldavg[2]; 86151497Sru la[3] = averunnable.fscale; 87151497Sru return SYSCTL_OUT(req, la, sizeof(la)); 88151497Sru } else 89151497Sru#endif 90151497Sru return SYSCTL_OUT(req, &averunnable, sizeof(averunnable)); 91151497Sru} 92151497SruSYSCTL_PROC(_vm, VM_LOADAVG, loadavg, CTLTYPE_STRUCT | CTLFLAG_RD | 93151497Sru CTLFLAG_MPSAFE, NULL, 0, sysctl_vm_loadavg, "S,loadavg", 94151497Sru "Machine loadaverage history"); 95151497Sru 96151497Srustatic int 97151497Sruvmtotal(SYSCTL_HANDLER_ARGS) 98151497Sru{ 99151497Sru struct proc *p; 100151497Sru struct vmtotal total; 101151497Sru vm_map_entry_t entry; 102151497Sru vm_object_t object; 103151497Sru vm_map_t map; 104151497Sru int paging; 105151497Sru struct thread *td; 106151497Sru struct vmspace *vm; 107151497Sru 108151497Sru bzero(&total, sizeof(total)); 109151497Sru /* 110151497Sru * Mark all objects as inactive. 111151497Sru */ 112151497Sru mtx_lock(&vm_object_list_mtx); 113151497Sru TAILQ_FOREACH(object, &vm_object_list, object_list) { 114151497Sru if (!VM_OBJECT_TRYWLOCK(object)) { 115151497Sru /* 116151497Sru * Avoid a lock-order reversal. Consequently, 117151497Sru * the reported number of active pages may be 118151497Sru * greater than the actual number. 119151497Sru */ 120151497Sru continue; 121151497Sru } 122151497Sru vm_object_clear_flag(object, OBJ_ACTIVE); 123151497Sru VM_OBJECT_WUNLOCK(object); 124151497Sru } 125151497Sru mtx_unlock(&vm_object_list_mtx); 126151497Sru /* 127151497Sru * Calculate process statistics. 128151497Sru */ 129151497Sru sx_slock(&allproc_lock); 130151497Sru FOREACH_PROC_IN_SYSTEM(p) { 131151497Sru if (p->p_flag & P_SYSTEM) 132151497Sru continue; 133151497Sru PROC_LOCK(p); 134151497Sru switch (p->p_state) { 135151497Sru case PRS_NEW: 136151497Sru PROC_UNLOCK(p); 137151497Sru continue; 138151497Sru break; 139151497Sru default: 140151497Sru FOREACH_THREAD_IN_PROC(p, td) { 141151497Sru thread_lock(td); 142151497Sru switch (td->td_state) { 143151497Sru case TDS_INHIBITED: 144151497Sru if (TD_IS_SWAPPED(td)) 145151497Sru total.t_sw++; 146151497Sru else if (TD_IS_SLEEPING(td) && 147151497Sru td->td_priority <= PZERO) 148151497Sru total.t_dw++; 149151497Sru else 150151497Sru total.t_sl++; 151151497Sru break; 152151497Sru 153151497Sru case TDS_CAN_RUN: 154151497Sru total.t_sw++; 155151497Sru break; 156151497Sru case TDS_RUNQ: 157151497Sru case TDS_RUNNING: 158151497Sru total.t_rq++; 159151497Sru thread_unlock(td); 160151497Sru continue; 161151497Sru default: 162151497Sru break; 163151497Sru } 164151497Sru thread_unlock(td); 165151497Sru } 166151497Sru } 167151497Sru PROC_UNLOCK(p); 168151497Sru /* 169151497Sru * Note active objects. 170151497Sru */ 171151497Sru paging = 0; 172151497Sru vm = vmspace_acquire_ref(p); 173151497Sru if (vm == NULL) 174151497Sru continue; 175151497Sru map = &vm->vm_map; 176151497Sru vm_map_lock_read(map); 177151497Sru for (entry = map->header.next; 178151497Sru entry != &map->header; entry = entry->next) { 179151497Sru if ((entry->eflags & MAP_ENTRY_IS_SUB_MAP) || 180151497Sru (object = entry->object.vm_object) == NULL) 181151497Sru continue; 182151497Sru VM_OBJECT_WLOCK(object); 183151497Sru vm_object_set_flag(object, OBJ_ACTIVE); 184151497Sru paging |= object->paging_in_progress; 185151497Sru VM_OBJECT_WUNLOCK(object); 186151497Sru } 187151497Sru vm_map_unlock_read(map); 188151497Sru vmspace_free(vm); 189151497Sru if (paging) 190151497Sru total.t_pw++; 191151497Sru } 192151497Sru sx_sunlock(&allproc_lock); 193151497Sru /* 194151497Sru * Calculate object memory usage statistics. 195151497Sru */ 196151497Sru mtx_lock(&vm_object_list_mtx); 197151497Sru TAILQ_FOREACH(object, &vm_object_list, object_list) { 198151497Sru /* 199151497Sru * Perform unsynchronized reads on the object to avoid 200151497Sru * a lock-order reversal. In this case, the lack of 201151497Sru * synchronization should not impair the accuracy of 202151497Sru * the reported statistics. 203151497Sru */ 204151497Sru if ((object->flags & OBJ_FICTITIOUS) != 0) { 205151497Sru /* 206151497Sru * Devices, like /dev/mem, will badly skew our totals. 207151497Sru */ 208151497Sru continue; 209151497Sru } 210151497Sru if (object->ref_count == 0) { 211151497Sru /* 212151497Sru * Also skip unreferenced objects, including 213151497Sru * vnodes representing mounted file systems. 214151497Sru */ 215151497Sru continue; 216151497Sru } 217151497Sru total.t_vm += object->size; 218151497Sru total.t_rm += object->resident_page_count; 219151497Sru if (object->flags & OBJ_ACTIVE) { 220151497Sru total.t_avm += object->size; 221151497Sru total.t_arm += object->resident_page_count; 222151497Sru } 223151497Sru if (object->shadow_count > 1) { 224151497Sru /* shared object */ 225151497Sru total.t_vmshr += object->size; 226151497Sru total.t_rmshr += object->resident_page_count; 227151497Sru if (object->flags & OBJ_ACTIVE) { 228151497Sru total.t_avmshr += object->size; 229151497Sru total.t_armshr += object->resident_page_count; 230151497Sru } 231151497Sru } 232151497Sru } 233151497Sru mtx_unlock(&vm_object_list_mtx); 234151497Sru total.t_free = cnt.v_free_count + cnt.v_cache_count; 235151497Sru return (sysctl_handle_opaque(oidp, &total, sizeof(total), req)); 236151497Sru} 237151497Sru 238151497Sru/* 239151497Sru * vcnt() - accumulate statistics from all cpus and the global cnt 240151497Sru * structure. 241151497Sru * 242151497Sru * The vmmeter structure is now per-cpu as well as global. Those 243151497Sru * statistics which can be kept on a per-cpu basis (to avoid cache 244151497Sru * stalls between cpus) can be moved to the per-cpu vmmeter. Remaining 245151497Sru * statistics, such as v_free_reserved, are left in the global 246151497Sru * structure. 247151497Sru * 248151497Sru * (sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req) 249151497Sru */ 250151497Srustatic int 251151497Sruvcnt(SYSCTL_HANDLER_ARGS) 252151497Sru{ 253151497Sru int count = *(int *)arg1; 254151497Sru int offset = (char *)arg1 - (char *)&cnt; 255151497Sru int i; 256151497Sru 257151497Sru CPU_FOREACH(i) { 258151497Sru struct pcpu *pcpu = pcpu_find(i); 259151497Sru count += *(int *)((char *)&pcpu->pc_cnt + offset); 260151497Sru } 261151497Sru return (SYSCTL_OUT(req, &count, sizeof(int))); 262151497Sru} 263151497Sru 264151497SruSYSCTL_PROC(_vm, VM_TOTAL, vmtotal, CTLTYPE_OPAQUE|CTLFLAG_RD|CTLFLAG_MPSAFE, 265151497Sru 0, sizeof(struct vmtotal), vmtotal, "S,vmtotal", 266151497Sru "System virtual memory statistics"); 267151497SruSYSCTL_NODE(_vm, OID_AUTO, stats, CTLFLAG_RW, 0, "VM meter stats"); 268151497Srustatic SYSCTL_NODE(_vm_stats, OID_AUTO, sys, CTLFLAG_RW, 0, 269151497Sru "VM meter sys stats"); 270151497Srustatic SYSCTL_NODE(_vm_stats, OID_AUTO, vm, CTLFLAG_RW, 0, 271151497Sru "VM meter vm stats"); 272SYSCTL_NODE(_vm_stats, OID_AUTO, misc, CTLFLAG_RW, 0, "VM meter misc stats"); 273 274#define VM_STATS(parent, var, descr) \ 275 SYSCTL_PROC(parent, OID_AUTO, var, \ 276 CTLTYPE_UINT | CTLFLAG_RD | CTLFLAG_MPSAFE, &cnt.var, 0, vcnt, \ 277 "IU", descr) 278#define VM_STATS_VM(var, descr) VM_STATS(_vm_stats_vm, var, descr) 279#define VM_STATS_SYS(var, descr) VM_STATS(_vm_stats_sys, var, descr) 280 281VM_STATS_SYS(v_swtch, "Context switches"); 282VM_STATS_SYS(v_trap, "Traps"); 283VM_STATS_SYS(v_syscall, "System calls"); 284VM_STATS_SYS(v_intr, "Device interrupts"); 285VM_STATS_SYS(v_soft, "Software interrupts"); 286VM_STATS_VM(v_vm_faults, "Address memory faults"); 287VM_STATS_VM(v_io_faults, "Page faults requiring I/O"); 288VM_STATS_VM(v_cow_faults, "Copy-on-write faults"); 289VM_STATS_VM(v_cow_optim, "Optimized COW faults"); 290VM_STATS_VM(v_zfod, "Pages zero-filled on demand"); 291VM_STATS_VM(v_ozfod, "Optimized zero fill pages"); 292VM_STATS_VM(v_swapin, "Swap pager pageins"); 293VM_STATS_VM(v_swapout, "Swap pager pageouts"); 294VM_STATS_VM(v_swappgsin, "Swap pages swapped in"); 295VM_STATS_VM(v_swappgsout, "Swap pages swapped out"); 296VM_STATS_VM(v_vnodein, "Vnode pager pageins"); 297VM_STATS_VM(v_vnodeout, "Vnode pager pageouts"); 298VM_STATS_VM(v_vnodepgsin, "Vnode pages paged in"); 299VM_STATS_VM(v_vnodepgsout, "Vnode pages paged out"); 300VM_STATS_VM(v_intrans, "In transit page faults"); 301VM_STATS_VM(v_reactivated, "Pages reactivated from free list"); 302VM_STATS_VM(v_pdwakeups, "Pagedaemon wakeups"); 303VM_STATS_VM(v_pdpages, "Pages analyzed by pagedaemon"); 304VM_STATS_VM(v_tcached, "Total pages cached"); 305VM_STATS_VM(v_dfree, "Pages freed by pagedaemon"); 306VM_STATS_VM(v_pfree, "Pages freed by exiting processes"); 307VM_STATS_VM(v_tfree, "Total pages freed"); 308VM_STATS_VM(v_page_size, "Page size in bytes"); 309VM_STATS_VM(v_page_count, "Total number of pages in system"); 310VM_STATS_VM(v_free_reserved, "Pages reserved for deadlock"); 311VM_STATS_VM(v_free_target, "Pages desired free"); 312VM_STATS_VM(v_free_min, "Minimum low-free-pages threshold"); 313VM_STATS_VM(v_free_count, "Free pages"); 314VM_STATS_VM(v_wire_count, "Wired pages"); 315VM_STATS_VM(v_active_count, "Active pages"); 316VM_STATS_VM(v_inactive_target, "Desired inactive pages"); 317VM_STATS_VM(v_inactive_count, "Inactive pages"); 318VM_STATS_VM(v_cache_count, "Pages on cache queue"); 319VM_STATS_VM(v_cache_min, "Min pages on cache queue"); 320VM_STATS_VM(v_cache_max, "Max pages on cached queue"); 321VM_STATS_VM(v_pageout_free_min, "Min pages reserved for kernel"); 322VM_STATS_VM(v_interrupt_free_min, "Reserved pages for interrupt code"); 323VM_STATS_VM(v_forks, "Number of fork() calls"); 324VM_STATS_VM(v_vforks, "Number of vfork() calls"); 325VM_STATS_VM(v_rforks, "Number of rfork() calls"); 326VM_STATS_VM(v_kthreads, "Number of fork() calls by kernel"); 327VM_STATS_VM(v_forkpages, "VM pages affected by fork()"); 328VM_STATS_VM(v_vforkpages, "VM pages affected by vfork()"); 329VM_STATS_VM(v_rforkpages, "VM pages affected by rfork()"); 330VM_STATS_VM(v_kthreadpages, "VM pages affected by fork() by kernel"); 331 332SYSCTL_INT(_vm_stats_misc, OID_AUTO, zero_page_count, CTLFLAG_RD, 333 &vm_page_zero_count, 0, "Number of zero-ed free pages"); 334