date and time created 88/12/14 15:30:04 by sklower
[unix-history] / usr / src / sys / vm / vm_meter.c
index 6e67e2d..9924dff 100644 (file)
@@ -1,14 +1,23 @@
-/*     vm_meter.c      4.6     81/04/23        */
+/*
+ * Copyright (c) 1982, 1986 Regents of the University of California.
+ * All rights reserved.  The Berkeley software License Agreement
+ * specifies the terms and conditions for redistribution.
+ *
+ *     @(#)vm_meter.c  7.4 (Berkeley) %G%
+ */
+
+#include "param.h"
+#include "systm.h"
+#include "seg.h"
+#include "dir.h"
+#include "user.h"
+#include "proc.h"
+#include "text.h"
+#include "vm.h"
+#include "cmap.h"
+#include "kernel.h"
+
 
 
-#include "../h/param.h"
-#include "../h/systm.h"
-#include "../h/seg.h"
-#include "../h/dir.h"
-#include "../h/user.h"
-#include "../h/proc.h"
-#include "../h/text.h"
-#include "../h/vm.h"
-#include "../h/cmap.h"
 
 int    maxslp = MAXSLP;
 int    saferss = SAFERSS;
 
 int    maxslp = MAXSLP;
 int    saferss = SAFERSS;
@@ -28,97 +37,13 @@ int slowscan = 0;
 int    fastscan = 0;
 int    klin = KLIN;
 int    klseql = KLSEQL;
 int    fastscan = 0;
 int    klin = KLIN;
 int    klseql = KLSEQL;
+int    klsdist = KLSDIST;
 int    kltxt = KLTXT;
 int    klout = KLOUT;
 int    multprog = -1;          /* so we don't count process 2 */
 
 double avenrun[3];             /* load average, of runnable procs */
 
 int    kltxt = KLTXT;
 int    klout = KLOUT;
 int    multprog = -1;          /* so we don't count process 2 */
 
 double avenrun[3];             /* load average, of runnable procs */
 
-/*
- * Setup the paging constants for the clock algorithm.
- * Called after the system is initialized and the amount of memory
- * and number of paging devices is known.
- */
-setupclock()
-{
-       int nclust, nkb;
-
-       /*
-        * Setup thresholds for paging:
-        *      lotsfree        is threshold where paging daemon turns on
-        *      desfree         is amount of memory desired free.  if less
-        *                      than this for extended period, do swapping
-        *      minfree         is minimal amount of free memory which is
-        *                      tolerable.
-        *
-        * Strategy of 4/22/81:
-        *      lotsfree is 1/4 of memory free.
-        *      desfree is 200k bytes, but at most 1/8 of memory
-        *      minfree is 32k bytes.
-        */
-       if (lotsfree == 0)
-               lotsfree = LOOPPAGES / 4;
-       if (desfree == 0) {
-               desfree = (200*1024) / NBPG;
-               if (desfree > LOOPPAGES / 8)
-                       desfree = LOOPPAGES / 8;
-       }
-       if (minfree == 0)
-               minfree = (32*1024) / NBPG;
-
-       /*
-        * Maxpgio thresholds how much paging is acceptable.
-        * This figures that 2/3 busy on an arm is all that is
-        * tolerable for paging.  We assume one operation per disk rev.
-        */
-       if (maxpgio == 0)
-               maxpgio = (DISKRPM * 2) / 3;
-
-       /*
-        * Clock to scan using max of 10% of processor time for sampling,
-        *     this estimated to allow maximum of 400 samples per second.
-        * Allow slighly higher angular velocity if 2 or more swap devices,
-        *     allow max of 600 samples per second (but only >= 2m)
-        * Basic scan time for ``fastscan'', the time for a clock rev
-        * with given memory and CLSIZE=2:
-        *      swap ilv        <=1m    2m      3m      4m      6m      8m
-        *      one-way         4s      5s      7s      XXX     XXX     XXX
-        *      two-way         4s      4s      5s      6s      10s     13s
-        * XXXs here are situations we should not be in.
-        */
-       if (fastscan == 0) {
-               nclust = LOOPPAGES / CLSIZE;
-               nkb = (LOOPPAGES * NBPG) / 1024;
-               if (nswdev == 1 && nkb >= 2*1024)
-                       printf("WARNING: should run interleaved swap with >= 2Mb\n");
-               if (nswdev == 1 || nkb < 2*1024)
-                       fastscan = nclust / 400;
-               else {
-                       maxpgio = (maxpgio * 3) / 2;
-                       fastscan = nclust / 600;
-               }
-       }
-       if (fastscan < 4)
-               fastscan = 4;
-       if (fastscan > maxslp)
-               fastscan = maxslp;
-
-       /*
-        * Set slow scan time to 1/3 the fast scan time but at most
-        * maxslp (a macroscopic slow).
-        */
-       if (slowscan == 0)
-               slowscan = 3 * fastscan;
-       if (slowscan > maxslp)
-               slowscan = maxslp;
-#ifdef defined(BERT) || defined(ERNIE)
-       printf("slowscan %d, fastscan %d, maxpgio %d\n",
-           slowscan, fastscan, maxpgio);
-       printf("lotsfree %d, desfree %d, minfree %d\n",
-           lotsfree, desfree, minfree);
-#endif
-}
-
 /*
  * The main loop of the scheduling (swapping) process.
  *
 /*
  * The main loop of the scheduling (swapping) process.
  *
@@ -166,17 +91,13 @@ sched()
        register struct bigp *bp, *nbp;
        int biggot, gives;
 
        register struct bigp *bp, *nbp;
        int biggot, gives;
 
-       /*
-        * Check if paging rate is too high, or average of
-        * free list very low and if so, adjust multiprogramming
-        * load by swapping someone out.
-        */
 loop:
        wantin = 0;
        deservin = 0;
        sleeper = 0;
        p = 0;
        /*
 loop:
        wantin = 0;
        deservin = 0;
        sleeper = 0;
        p = 0;
        /*
+        * See if paging system is overloaded; if so swap someone out.
         * Conditions for hard outswap are:
         *      if need kernel map (mix it up).
         * or
         * Conditions for hard outswap are:
         *      if need kernel map (mix it up).
         * or
@@ -185,7 +106,8 @@ loop:
         * and  3. the short (5-second) and longer (30-second) average
         *         memory is less than desirable.
         */
         * and  3. the short (5-second) and longer (30-second) average
         *         memory is less than desirable.
         */
-       if (kmapwnt || (avenrun[0] >= 2 && max(avefree, avefree30) < desfree &&
+       if (kmapwnt ||
+           (avenrun[0] >= 2 && imax(avefree, avefree30) < desfree &&
            (rate.v_pgin + rate.v_pgout > maxpgio || avefree < minfree))) {
                desperate = 1;
                goto hardswap;
            (rate.v_pgin + rate.v_pgout > maxpgio || avefree < minfree))) {
                desperate = 1;
                goto hardswap;
@@ -196,7 +118,7 @@ loop:
         * look for someone who deserves to be brought in.
         */
        outpri = -20000;
         * look for someone who deserves to be brought in.
         */
        outpri = -20000;
-       for (rp = proc; rp < procNPROC; rp++) switch(rp->p_stat) {
+       for (rp = allproc; rp != NULL; rp = rp->p_nxt) switch(rp->p_stat) {
 
        case SRUN:
                if ((rp->p_flag&SLOAD) == 0) {
 
        case SRUN:
                if ((rp->p_flag&SLOAD) == 0) {
@@ -223,26 +145,20 @@ loop:
                        /*
                         * Kick out deadwood.
                         */
                        /*
                         * Kick out deadwood.
                         */
-                       (void) spl6();
                        rp->p_flag &= ~SLOAD;
                        rp->p_flag &= ~SLOAD;
-                       if (rp->p_stat == SRUN)
-                               remrq(rp);
-                       (void) spl0();
                        (void) swapout(rp, rp->p_dsize, rp->p_ssize);
                        (void) swapout(rp, rp->p_dsize, rp->p_ssize);
-                       goto loop;
                }
                continue;
        }
 
        /*
                }
                continue;
        }
 
        /*
-        * No one wants in, so nothing to do.
+        * If something came ready after we checked it,
+        * wantin will be set.  Otherwise,
+        * no one wants in, so nothing to do.
         */
        if (outpri == -20000) {
         */
        if (outpri == -20000) {
-               (void) spl6();
-               if (wantin) {
-                       wantin = 0;
-                       sleep((caddr_t)&lbolt, PSWP);
-               } else {
+               (void) splhigh();
+               if (wantin == 0) {
                        runout++;
                        sleep((caddr_t)&runout, PSWP);
                }
                        runout++;
                        sleep((caddr_t)&runout, PSWP);
                }
@@ -288,11 +204,9 @@ hardswap:
                nbig = 1;
        biggot = 0;
        bplist.bp_link = 0;
                nbig = 1;
        biggot = 0;
        bplist.bp_link = 0;
-       for (rp = proc; rp < procNPROC; rp++) {
+       for (rp = allproc; rp != NULL; rp = rp->p_nxt) {
                if (!swappable(rp))
                        continue;
                if (!swappable(rp))
                        continue;
-               if (rp->p_stat==SZOMB)
-                       continue;
                if (rp == inp)
                        continue;
                if (rp->p_textp && rp->p_textp->x_flag&XLOCK)
                if (rp == inp)
                        continue;
                if (rp->p_textp && rp->p_textp->x_flag&XLOCK)
@@ -344,7 +258,7 @@ hardswap:
         * we kick the poor luser out.
         */
        if (sleeper || desperate && p || deservin && inpri > maxslp) {
         * we kick the poor luser out.
         */
        if (sleeper || desperate && p || deservin && inpri > maxslp) {
-               (void) spl6();
+               (void) splhigh();
                p->p_flag &= ~SLOAD;
                if (p->p_stat == SRUN)
                        remrq(p);
                p->p_flag &= ~SLOAD;
                if (p->p_stat == SRUN)
                        remrq(p);
@@ -358,19 +272,20 @@ hardswap:
                        gives = p->p_rssize;
                        if (p->p_textp)
                                gives += p->p_textp->x_rssize / p->p_textp->x_ccount;
                        gives = p->p_rssize;
                        if (p->p_textp)
                                gives += p->p_textp->x_rssize / p->p_textp->x_ccount;
-                       gives = min(gives, lotsfree);
+                       gives = imin(gives, lotsfree);
                        deficit += gives;
                } else
                        gives = 0;      /* someone else taketh away */
                if (swapout(p, p->p_dsize, p->p_ssize) == 0)
                        deficit -= imin(gives, deficit);
                        deficit += gives;
                } else
                        gives = 0;      /* someone else taketh away */
                if (swapout(p, p->p_dsize, p->p_ssize) == 0)
                        deficit -= imin(gives, deficit);
-               goto loop;
+               else
+                       goto loop;
        }
        /*
         * Want to swap someone in, but can't
         * so wait on runin.
         */
        }
        /*
         * Want to swap someone in, but can't
         * so wait on runin.
         */
-       (void) spl6();
+       (void) splhigh();
        runin++;
        sleep((caddr_t)&runin, PSWP);
        (void) spl0();
        runin++;
        sleep((caddr_t)&runin, PSWP);
        (void) spl0();
@@ -393,7 +308,7 @@ vmmeter()
                *cp = 0;
                rp++, cp++, sp++;
        }
                *cp = 0;
                rp++, cp++, sp++;
        }
-       if (time % 5 == 0) {
+       if (time.tv_sec % 5 == 0) {
                vmtotal();
                rate.v_swpin = cnt.v_swpin;
                sum.v_swpin += cnt.v_swpin;
                vmtotal();
                rate.v_swpin = cnt.v_swpin;
                sum.v_swpin += cnt.v_swpin;
@@ -410,32 +325,25 @@ vmmeter()
        }
 }
 
        }
 }
 
-vmpago()
+/*
+ * Schedule rate for paging.
+ * Rate is linear interpolation between
+ * slowscan with lotsfree and fastscan when out of memory.
+ */
+schedpaging()
 {
        register int vavail;
 {
        register int vavail;
-       register int scanrate;
 
 
-       /*
-        * Compute new rate for clock; if
-        * nonzero, restart clock.
-        * Rate ranges linearly from one rev per
-        * slowscan seconds when there is lotsfree memory
-        * available to one rev per fastscan seconds when
-        * there is no memory available.
-        */
        nscan = desscan = 0;
        vavail = freemem - deficit;
        if (vavail < 0)
                vavail = 0;
        nscan = desscan = 0;
        vavail = freemem - deficit;
        if (vavail < 0)
                vavail = 0;
-       if (freemem >= lotsfree)
-               return;
-       scanrate = (slowscan * vavail + fastscan * (lotsfree - vavail)) / nz(lotsfree);
-       desscan = (LOOPPAGES / CLSIZE) / nz(scanrate);
-       /*
-        * DIVIDE BY 4 TO ACCOUNT FOR RUNNING 4* A SECOND (see clock.c)
-        */
-       desscan /= 4;
-       wakeup((caddr_t)&proc[2]);
+       if (freemem < lotsfree) {
+               desscan = (slowscan * vavail + fastscan * (lotsfree - vavail)) /
+                       nz(lotsfree) / RATETOSCHEDPAGING;
+               wakeup((caddr_t)&proc[2]);
+       }
+       timeout(schedpaging, (caddr_t)0, hz / RATETOSCHEDPAGING);
 }
 
 vmtotal()
 }
 
 vmtotal()
@@ -479,17 +387,19 @@ next:
        total.t_pw = 0;
        total.t_sl = 0;
        total.t_sw = 0;
        total.t_pw = 0;
        total.t_sl = 0;
        total.t_sw = 0;
-       for (p = proc; p < procNPROC; p++) {
+       for (p = allproc; p != NULL; p = p->p_nxt) {
                if (p->p_flag & SSYS)
                        continue;
                if (p->p_stat) {
                if (p->p_flag & SSYS)
                        continue;
                if (p->p_stat) {
-                       total.t_vm += p->p_dsize + p->p_ssize;
-                       total.t_rm += p->p_rssize;
+                       if (p->p_stat != SZOMB) {
+                               total.t_vm += p->p_dsize + p->p_ssize;
+                               total.t_rm += p->p_rssize;
+                       }
                        switch (p->p_stat) {
 
                        case SSLEEP:
                        case SSTOP:
                        switch (p->p_stat) {
 
                        case SSLEEP:
                        case SSTOP:
-                               if (p->p_pri <= PZERO)
+                               if (p->p_pri <= PZERO && p->p_stat == SSLEEP)
                                        nrun++;
                                if (p->p_flag & SPAGE)
                                        total.t_pw++;
                                        nrun++;
                                if (p->p_flag & SPAGE)
                                        total.t_pw++;