attempt to make "average active VM" count more accurate--
[unix-history] / usr / src / sys / vm / vm_meter.c
index dd0c8c0..858eb97 100644 (file)
@@ -1,18 +1,18 @@
 /*
 /*
- * Copyright (c) 1982, 1986, 1989 Regents of the University of California.
- * All rights reserved.
+ * Copyright (c) 1982, 1986, 1989, 1993
+ *     The Regents of the University of California.  All rights reserved.
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)vm_meter.c  7.16 (Berkeley) %G%
+ *     @(#)vm_meter.c  8.5 (Berkeley) %G%
  */
 
 #include <sys/param.h>
 #include <sys/proc.h>
 #include <sys/systm.h>
 #include <sys/kernel.h>
  */
 
 #include <sys/param.h>
 #include <sys/proc.h>
 #include <sys/systm.h>
 #include <sys/kernel.h>
-
 #include <vm/vm.h>
 #include <vm/vm.h>
+#include <sys/sysctl.h>
 
 struct loadavg averunnable;            /* load average, of runnable procs */
 
 
 struct loadavg averunnable;            /* load average, of runnable procs */
 
@@ -22,7 +22,6 @@ int   saferss = SAFERSS;
 void
 vmmeter()
 {
 void
 vmmeter()
 {
-       register unsigned *cp, *rp, *sp;
 
        if (time.tv_sec % 5 == 0)
                loadav(&averunnable);
 
        if (time.tv_sec % 5 == 0)
                loadav(&averunnable);
@@ -51,10 +50,10 @@ loadav(avg)
        register int i, nrun;
        register struct proc *p;
 
        register int i, nrun;
        register struct proc *p;
 
-       for (nrun = 0, p = allproc; p != NULL; p = p->p_nxt) {
+       for (nrun = 0, p = (struct proc *)allproc; p != NULL; p = p->p_next) {
                switch (p->p_stat) {
                case SSLEEP:
                switch (p->p_stat) {
                case SSLEEP:
-                       if (p->p_pri > PZERO || p->p_slptime != 0)
+                       if (p->p_priority > PZERO || p->p_slptime != 0)
                                continue;
                        /* fall through */
                case SRUN:
                                continue;
                        /* fall through */
                case SRUN:
@@ -65,67 +64,39 @@ loadav(avg)
        for (i = 0; i < 3; i++)
                avg->ldavg[i] = (cexp[i] * avg->ldavg[i] +
                        nrun * FSCALE * (FSCALE - cexp[i])) >> FSHIFT;
        for (i = 0; i < 3; i++)
                avg->ldavg[i] = (cexp[i] * avg->ldavg[i] +
                        nrun * FSCALE * (FSCALE - cexp[i])) >> FSHIFT;
-#if defined(COMPAT_43) && (defined(vax) || defined(tahoe))
-       for (i = 0; i < 3; i++)
-               avenrun[i] = (double) avg->ldavg[i] / FSCALE;
-#endif /* COMPAT_43 */
 }
 
 /*
 }
 
 /*
- * Load average information
+ * Attributes associated with virtual memory.
  */
  */
-/* ARGSUSED */
-int
-kinfo_loadavg(op, where, acopysize, arg, aneeded)
-       int op;
-       register char *where;
-       int *acopysize, arg, *aneeded;
-{
-       int buflen, error;
-
-       *aneeded = sizeof(averunnable);
-       if (where == NULL)
-               return (0);
-       /*
-        * Check for enough buffering.
-        */
-       buflen = *acopysize;
-       if (buflen < sizeof(averunnable)) {
-               *acopysize = 0;
-               return (0);
-       }
-       /*
-        * Copyout averunnable structure.
-        */
-       averunnable.fscale = FSCALE;
-       if (error = copyout((caddr_t)&averunnable, where, sizeof(averunnable)))
-               return (error);
-       *acopysize = sizeof(averunnable);
-       return (0);
-}
-
-/*
- * Calculate and return vmtotals structure.
- */
-int
-kinfo_meter(op, where, acopysize, arg, aneeded)
-       int op;
-       caddr_t where;
-       int *acopysize, arg, *aneeded;
+vm_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
+       int *name;
+       u_int namelen;
+       void *oldp;
+       size_t *oldlenp;
+       void *newp;
+       size_t newlen;
+       struct proc *p;
 {
        struct vmtotal vmtotals;
 {
        struct vmtotal vmtotals;
-       int error;
 
 
-       *aneeded = sizeof(struct vmtotal);
-       if (where == NULL)
-               return (0);
-       if (*acopysize < sizeof(struct vmtotal))
-               return (EINVAL);
-       vmtotal(&vmtotals);
-       if (error = copyout((caddr_t)&vmtotals, where, sizeof(struct vmtotal)))
-               return (error);
-       *acopysize = sizeof(struct vmtotal);
-       return (0);
+       /* all sysctl names at this level are terminal */
+       if (namelen != 1)
+               return (ENOTDIR);               /* overloaded */
+
+       switch (name[0]) {
+       case VM_LOADAVG:
+               averunnable.fscale = FSCALE;
+               return (sysctl_rdstruct(oldp, oldlenp, newp, &averunnable,
+                   sizeof(averunnable)));
+       case VM_METER:
+               vmtotal(&vmtotals);
+               return (sysctl_rdstruct(oldp, oldlenp, newp, &vmtotals,
+                   sizeof(vmtotals)));
+       default:
+               return (EOPNOTSUPP);
+       }
+       /* NOTREACHED */
 }
 
 /*
 }
 
 /*
@@ -147,17 +118,16 @@ vmtotal(totalp)
         * Mark all objects as inactive.
         */
        simple_lock(&vm_object_list_lock);
         * Mark all objects as inactive.
         */
        simple_lock(&vm_object_list_lock);
-       object = (vm_object_t) queue_first(&vm_object_list);
-       while (!queue_end(&vm_object_list, (queue_entry_t) object)) {
+       for (object = vm_object_list.tqh_first;
+            object != NULL;
+            object = object->object_list.tqe_next)
                object->flags &= ~OBJ_ACTIVE;
                object->flags &= ~OBJ_ACTIVE;
-               object = (vm_object_t) queue_next(&object->object_list);
-       }
        simple_unlock(&vm_object_list_lock);
        /*
         * Calculate process statistics.
         */
        simple_unlock(&vm_object_list_lock);
        /*
         * Calculate process statistics.
         */
-       for (p = allproc; p != NULL; p = p->p_nxt) {
-               if (p->p_flag & SSYS)
+       for (p = (struct proc *)allproc; p != NULL; p = p->p_next) {
+               if (p->p_flag & P_SYSTEM)
                        continue;
                switch (p->p_stat) {
                case 0:
                        continue;
                switch (p->p_stat) {
                case 0:
@@ -165,8 +135,8 @@ vmtotal(totalp)
 
                case SSLEEP:
                case SSTOP:
 
                case SSLEEP:
                case SSTOP:
-                       if (p->p_flag & SLOAD) {
-                               if (p->p_pri <= PZERO)
+                       if (p->p_flag & P_INMEM) {
+                               if (p->p_priority <= PZERO)
                                        totalp->t_dw++;
                                else if (p->p_slptime < maxslp)
                                        totalp->t_sl++;
                                        totalp->t_dw++;
                                else if (p->p_slptime < maxslp)
                                        totalp->t_sl++;
@@ -178,7 +148,7 @@ vmtotal(totalp)
 
                case SRUN:
                case SIDL:
 
                case SRUN:
                case SIDL:
-                       if (p->p_flag & SLOAD)
+                       if (p->p_flag & P_INMEM)
                                totalp->t_rq++;
                        else
                                totalp->t_sw++;
                                totalp->t_rq++;
                        else
                                totalp->t_sw++;
@@ -188,15 +158,25 @@ vmtotal(totalp)
                }
                /*
                 * Note active objects.
                }
                /*
                 * Note active objects.
+                *
+                * XXX don't count shadow objects with no resident pages.
+                * This eliminates the forced shadows caused by MAP_PRIVATE.
+                * Right now we require that such an object completely shadow
+                * the original, to catch just those cases.
                 */
                paging = 0;
                for (map = &p->p_vmspace->vm_map, entry = map->header.next;
                     entry != &map->header; entry = entry->next) {
                        if (entry->is_a_map || entry->is_sub_map ||
                 */
                paging = 0;
                for (map = &p->p_vmspace->vm_map, entry = map->header.next;
                     entry != &map->header; entry = entry->next) {
                        if (entry->is_a_map || entry->is_sub_map ||
-                           entry->object.vm_object == NULL)
+                           (object = entry->object.vm_object) == NULL)
                                continue;
                                continue;
-                       entry->object.vm_object->flags |= OBJ_ACTIVE;
-                       paging |= entry->object.vm_object->paging_in_progress;
+                       while (object->shadow &&
+                              object->resident_page_count == 0 &&
+                              object->shadow_offset == 0 &&
+                              object->size == object->shadow->size)
+                               object = object->shadow;
+                       object->flags |= OBJ_ACTIVE;
+                       paging |= object->paging_in_progress;
                }
                if (paging)
                        totalp->t_pw++;
                }
                if (paging)
                        totalp->t_pw++;
@@ -205,8 +185,9 @@ vmtotal(totalp)
         * Calculate object memory usage statistics.
         */
        simple_lock(&vm_object_list_lock);
         * Calculate object memory usage statistics.
         */
        simple_lock(&vm_object_list_lock);
-       object = (vm_object_t) queue_first(&vm_object_list);
-       while (!queue_end(&vm_object_list, (queue_entry_t) object)) {
+       for (object = vm_object_list.tqh_first;
+            object != NULL;
+            object = object->object_list.tqe_next) {
                totalp->t_vm += num_pages(object->size);
                totalp->t_rm += object->resident_page_count;
                if (object->flags & OBJ_ACTIVE) {
                totalp->t_vm += num_pages(object->size);
                totalp->t_rm += object->resident_page_count;
                if (object->flags & OBJ_ACTIVE) {
@@ -222,7 +203,6 @@ vmtotal(totalp)
                                totalp->t_armshr += object->resident_page_count;
                        }
                }
                                totalp->t_armshr += object->resident_page_count;
                        }
                }
-               object = (vm_object_t) queue_next(&object->object_list);
        }
        totalp->t_free = cnt.v_free_count;
 }
        }
        totalp->t_free = cnt.v_free_count;
 }