Annotation of sys/uvm/uvm_meter.c, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: uvm_meter.c,v 1.22 2007/02/14 00:53:48 jsg Exp $ */
! 2: /* $NetBSD: uvm_meter.c,v 1.21 2001/07/14 06:36:03 matt Exp $ */
! 3:
! 4: /*
! 5: * Copyright (c) 1997 Charles D. Cranor and Washington University.
! 6: * Copyright (c) 1982, 1986, 1989, 1993
! 7: * The Regents of the University of California.
! 8: *
! 9: * All rights reserved.
! 10: *
! 11: * Redistribution and use in source and binary forms, with or without
! 12: * modification, are permitted provided that the following conditions
! 13: * are met:
! 14: * 1. Redistributions of source code must retain the above copyright
! 15: * notice, this list of conditions and the following disclaimer.
! 16: * 2. Redistributions in binary form must reproduce the above copyright
! 17: * notice, this list of conditions and the following disclaimer in the
! 18: * documentation and/or other materials provided with the distribution.
! 19: * 3. All advertising materials mentioning features or use of this software
! 20: * must display the following acknowledgement:
! 21: * This product includes software developed by Charles D. Cranor,
! 22: * Washington University, and the University of California, Berkeley
! 23: * and its contributors.
! 24: * 4. Neither the name of the University nor the names of its contributors
! 25: * may be used to endorse or promote products derived from this software
! 26: * without specific prior written permission.
! 27: *
! 28: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
! 29: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
! 30: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
! 31: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
! 32: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
! 33: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
! 34: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
! 35: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
! 36: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
! 37: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
! 38: * SUCH DAMAGE.
! 39: *
! 40: * @(#)vm_meter.c 8.4 (Berkeley) 1/4/94
! 41: * from: Id: uvm_meter.c,v 1.1.2.1 1997/08/14 19:10:35 chuck Exp
! 42: */
! 43:
! 44: #include <sys/param.h>
! 45: #include <sys/proc.h>
! 46: #include <sys/systm.h>
! 47: #include <sys/kernel.h>
! 48: #include <uvm/uvm_extern.h>
! 49: #include <sys/sysctl.h>
! 50: #include <sys/exec.h>
! 51:
! 52: #ifdef UVM_SWAP_ENCRYPT
! 53: #include <uvm/uvm_swap.h>
! 54: #include <uvm/uvm_swap_encrypt.h>
! 55: #endif
! 56:
! 57: /*
! 58: * maxslp: ???? XXXCDC
! 59: */
! 60:
! 61: int maxslp = MAXSLP; /* patchable ... */
! 62: struct loadavg averunnable;
! 63:
! 64: /*
! 65: * constants for averages over 1, 5, and 15 minutes when sampling at
! 66: * 5 second intervals.
! 67: */
! 68:
! 69: static fixpt_t cexp[3] = {
! 70: 0.9200444146293232 * FSCALE, /* exp(-1/12) */
! 71: 0.9834714538216174 * FSCALE, /* exp(-1/60) */
! 72: 0.9944598480048967 * FSCALE, /* exp(-1/180) */
! 73: };
! 74:
! 75: /*
! 76: * prototypes
! 77: */
! 78:
! 79: static void uvm_loadav(struct loadavg *);
! 80:
! 81: /*
! 82: * uvm_meter: calculate load average and wake up the swapper (if needed)
! 83: */
! 84: void
! 85: uvm_meter()
! 86: {
! 87: if ((time_second % 5) == 0)
! 88: uvm_loadav(&averunnable);
! 89: if (proc0.p_slptime > (maxslp / 2))
! 90: wakeup(&proc0);
! 91: }
! 92:
! 93: /*
! 94: * uvm_loadav: compute a tenex style load average of a quantity on
! 95: * 1, 5, and 15 minute intervals.
! 96: */
! 97: static void
! 98: uvm_loadav(avg)
! 99: struct loadavg *avg;
! 100: {
! 101: int i, nrun;
! 102: struct proc *p;
! 103:
! 104: nrun = 0;
! 105: LIST_FOREACH(p, &allproc, p_list) {
! 106: switch (p->p_stat) {
! 107: case SSLEEP:
! 108: if (p->p_priority > PZERO || p->p_slptime > 1)
! 109: continue;
! 110: /* FALLTHROUGH */
! 111: case SRUN:
! 112: case SIDL:
! 113: case SONPROC:
! 114: nrun++;
! 115: }
! 116: }
! 117: for (i = 0; i < 3; i++)
! 118: avg->ldavg[i] = (cexp[i] * avg->ldavg[i] +
! 119: nrun * FSCALE * (FSCALE - cexp[i])) >> FSHIFT;
! 120: }
! 121:
! 122: /*
! 123: * uvm_sysctl: sysctl hook into UVM system.
! 124: */
! 125: int
! 126: uvm_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
! 127: int *name;
! 128: u_int namelen;
! 129: void *oldp;
! 130: size_t *oldlenp;
! 131: void *newp;
! 132: size_t newlen;
! 133: struct proc *p;
! 134: {
! 135: struct vmtotal vmtotals;
! 136: int rv, t;
! 137: struct _ps_strings _ps = { PS_STRINGS };
! 138:
! 139: switch (name[0]) {
! 140: case VM_SWAPENCRYPT:
! 141: #ifdef UVM_SWAP_ENCRYPT
! 142: return (swap_encrypt_ctl(name + 1, namelen - 1, oldp, oldlenp,
! 143: newp, newlen, p));
! 144: #else
! 145: return (EOPNOTSUPP);
! 146: #endif
! 147: default:
! 148: /* all sysctl names at this level are terminal */
! 149: if (namelen != 1)
! 150: return (ENOTDIR); /* overloaded */
! 151: break;
! 152: }
! 153:
! 154: switch (name[0]) {
! 155: case VM_LOADAVG:
! 156: return (sysctl_rdstruct(oldp, oldlenp, newp, &averunnable,
! 157: sizeof(averunnable)));
! 158:
! 159: case VM_METER:
! 160: uvm_total(&vmtotals);
! 161: return (sysctl_rdstruct(oldp, oldlenp, newp, &vmtotals,
! 162: sizeof(vmtotals)));
! 163:
! 164: case VM_UVMEXP:
! 165: return (sysctl_rdstruct(oldp, oldlenp, newp, &uvmexp,
! 166: sizeof(uvmexp)));
! 167:
! 168: case VM_NKMEMPAGES:
! 169: return (sysctl_rdint(oldp, oldlenp, newp, nkmempages));
! 170:
! 171: case VM_PSSTRINGS:
! 172: return (sysctl_rdstruct(oldp, oldlenp, newp, &_ps,
! 173: sizeof(_ps)));
! 174: case VM_ANONMIN:
! 175: t = uvmexp.anonminpct;
! 176: rv = sysctl_int(oldp, oldlenp, newp, newlen, &t);
! 177: if (rv) {
! 178: return rv;
! 179: }
! 180: if (t + uvmexp.vtextminpct + uvmexp.vnodeminpct > 95 || t < 0) {
! 181: return EINVAL;
! 182: }
! 183: uvmexp.anonminpct = t;
! 184: uvmexp.anonmin = t * 256 / 100;
! 185: return rv;
! 186:
! 187: case VM_VTEXTMIN:
! 188: t = uvmexp.vtextminpct;
! 189: rv = sysctl_int(oldp, oldlenp, newp, newlen, &t);
! 190: if (rv) {
! 191: return rv;
! 192: }
! 193: if (uvmexp.anonminpct + t + uvmexp.vnodeminpct > 95 || t < 0) {
! 194: return EINVAL;
! 195: }
! 196: uvmexp.vtextminpct = t;
! 197: uvmexp.vtextmin = t * 256 / 100;
! 198: return rv;
! 199:
! 200: case VM_VNODEMIN:
! 201: t = uvmexp.vnodeminpct;
! 202: rv = sysctl_int(oldp, oldlenp, newp, newlen, &t);
! 203: if (rv) {
! 204: return rv;
! 205: }
! 206: if (uvmexp.anonminpct + uvmexp.vtextminpct + t > 95 || t < 0) {
! 207: return EINVAL;
! 208: }
! 209: uvmexp.vnodeminpct = t;
! 210: uvmexp.vnodemin = t * 256 / 100;
! 211: return rv;
! 212:
! 213: case VM_MAXSLP:
! 214: return (sysctl_rdint(oldp, oldlenp, newp, maxslp));
! 215:
! 216: case VM_USPACE:
! 217: return (sysctl_rdint(oldp, oldlenp, newp, USPACE));
! 218:
! 219: default:
! 220: return (EOPNOTSUPP);
! 221: }
! 222: /* NOTREACHED */
! 223: }
! 224:
! 225: /*
! 226: * uvm_total: calculate the current state of the system.
! 227: */
! 228: void
! 229: uvm_total(totalp)
! 230: struct vmtotal *totalp;
! 231: {
! 232: struct proc *p;
! 233: #if 0
! 234: struct vm_map_entry * entry;
! 235: struct vm_map *map;
! 236: int paging;
! 237: #endif
! 238:
! 239: memset(totalp, 0, sizeof *totalp);
! 240:
! 241: /*
! 242: * calculate process statistics
! 243: */
! 244:
! 245: LIST_FOREACH(p, &allproc, p_list) {
! 246: if (p->p_flag & P_SYSTEM)
! 247: continue;
! 248: switch (p->p_stat) {
! 249: case 0:
! 250: continue;
! 251:
! 252: case SSLEEP:
! 253: case SSTOP:
! 254: if (p->p_priority <= PZERO)
! 255: totalp->t_dw++;
! 256: else if (p->p_slptime < maxslp)
! 257: totalp->t_sl++;
! 258: if (p->p_slptime >= maxslp)
! 259: continue;
! 260: break;
! 261:
! 262: case SRUN:
! 263: case SIDL:
! 264: case SONPROC:
! 265: totalp->t_rq++;
! 266: if (p->p_stat == SIDL)
! 267: continue;
! 268: break;
! 269: }
! 270: /*
! 271: * note active objects
! 272: */
! 273: #if 0
! 274: /*
! 275: * XXXCDC: BOGUS! rethink this. in the mean time
! 276: * don't do it.
! 277: */
! 278: paging = 0;
! 279: vm_map_lock(map);
! 280: for (map = &p->p_vmspace->vm_map, entry = map->header.next;
! 281: entry != &map->header; entry = entry->next) {
! 282: if (entry->is_a_map || entry->is_sub_map ||
! 283: entry->object.uvm_obj == NULL)
! 284: continue;
! 285: /* XXX how to do this with uvm */
! 286: }
! 287: vm_map_unlock(map);
! 288: if (paging)
! 289: totalp->t_pw++;
! 290: #endif
! 291: }
! 292: /*
! 293: * Calculate object memory usage statistics.
! 294: */
! 295: totalp->t_free = uvmexp.free;
! 296: totalp->t_vm = uvmexp.npages - uvmexp.free + uvmexp.swpginuse;
! 297: totalp->t_avm = uvmexp.active + uvmexp.swpginuse; /* XXX */
! 298: totalp->t_rm = uvmexp.npages - uvmexp.free;
! 299: totalp->t_arm = uvmexp.active;
! 300: totalp->t_vmshr = 0; /* XXX */
! 301: totalp->t_avmshr = 0; /* XXX */
! 302: totalp->t_rmshr = 0; /* XXX */
! 303: totalp->t_armshr = 0; /* XXX */
! 304: }
CVSweb