1: /*
   2:  * Copyright (c) 1982, 1986 Regents of the University of California.
   3:  * All rights reserved.  The Berkeley software License Agreement
   4:  * specifies the terms and conditions for redistribution.
   5:  *
   6:  *	@(#)vm_swap.c	7.1 (Berkeley) 6/5/86
   7:  */
   8: 
   9: #include "../machine/pte.h"
  10: 
  11: #include "param.h"
  12: #include "systm.h"
  13: #include "dir.h"
  14: #include "user.h"
  15: #include "proc.h"
  16: #include "text.h"
  17: #include "map.h"
  18: #include "buf.h"
  19: #include "cmap.h"
  20: #include "vm.h"
  21: 
  22: /*
  23:  * Swap a process in.
  24:  */
  25: swapin(p)
  26:     register struct proc *p;
  27: {
  28:     register struct text *xp;
  29:     register int i, s;
  30: 
  31:     if (xp = p->p_textp)
  32:         xlock(xp);
  33:     p->p_szpt = clrnd(ctopt(p->p_ssize+p->p_dsize+p->p_tsize+UPAGES));
  34:     if (vgetpt(p, memall) == 0)
  35:         goto nomem;
  36:     if (vgetu(p, memall, Swapmap, &swaputl, (struct user *)0) == 0) {
  37:         vrelpt(p);
  38:         goto nomem;
  39:     }
  40: 
  41:     swdspt(p, &swaputl, B_READ);
  42:     /*
  43: 	 * Make sure swdspt didn't smash u. pte's
  44: 	 */
  45:     for (i = 0; i < UPAGES; i++) {
  46:         if (Swapmap[i].pg_pfnum != p->p_addr[i].pg_pfnum)
  47:             panic("swapin");
  48:     }
  49:     vrelswu(p, &swaputl);
  50:     if (xp) {
  51:         xlink(p);
  52:         xunlock(xp);
  53:     }
  54: 
  55:     p->p_rssize = 0;
  56:     s = splclock();
  57:     if (p->p_stat == SRUN)
  58:         setrq(p);
  59:     p->p_flag |= SLOAD;
  60:     if (p->p_flag & SSWAP) {
  61:         swaputl.u_pcb.pcb_sswap = (int *)&u.u_ssave;
  62:         p->p_flag &= ~SSWAP;
  63:     }
  64:     splx(s);
  65:     p->p_time = 0;
  66:     multprog++;
  67:     cnt.v_swpin++;
  68:     return (1);
  69: 
  70: nomem:
  71:     if (xp)
  72:         xunlock(xp);
  73:     return (0);
  74: }
  75: 
  76: int xswapwant, xswaplock;
  77: /*
  78:  * Swap out process p.
  79:  * ds and ss are the old data size and the stack size
  80:  * of the process, and are supplied during page table
  81:  * expansion swaps.
  82:  */
  83: swapout(p, ds, ss)
  84:     register struct proc *p;
  85:     size_t ds, ss;
  86: {
  87:     register struct pte *map;
  88:     register struct user *utl;
  89:     int s;
  90:     int rc = 1;
  91: 
  92:     s = 1;
  93:     map = Xswapmap;
  94:     utl = &xswaputl;
  95:     if (xswaplock & s)
  96:         if ((xswaplock & 2) == 0) {
  97:             s = 2;
  98:             map = Xswap2map;
  99:             utl = &xswap2utl;
 100:         }
 101:     while (xswaplock & s) {
 102:         xswapwant |= s;
 103:         sleep((caddr_t)map, PSWP);
 104:     }
 105:     xswaplock |= s;
 106:     uaccess(p, map, utl);
 107:     if (vgetswu(p, utl) == 0) {
 108:         p->p_flag |= SLOAD;
 109:         rc = 0;
 110:         goto out;
 111:     }
 112:     utl->u_ru.ru_nswap++;
 113:     utl->u_odsize = ds;
 114:     utl->u_ossize = ss;
 115:     p->p_flag |= SLOCK;
 116:     if (p->p_textp) {
 117:         if (p->p_textp->x_ccount == 1)
 118:             p->p_textp->x_swrss = p->p_textp->x_rssize;
 119:         xdetach(p->p_textp, p);
 120:     }
 121:     p->p_swrss = p->p_rssize;
 122:     vsswap(p, dptopte(p, 0), CDATA, 0, (int)ds, &utl->u_dmap);
 123:     vsswap(p, sptopte(p, CLSIZE-1), CSTACK, 0, (int)ss, &utl->u_smap);
 124:     if (p->p_rssize != 0)
 125:         panic("swapout rssize");
 126: 
 127:     swdspt(p, utl, B_WRITE);
 128:     /*
 129: 	 * If freeing the user structure and kernel stack
 130: 	 * for the current process, have to run a bit longer
 131: 	 * using the pages which are about to be freed...
 132: 	 * vrelu will then block memory allocation by raising ipl.
 133: 	 */
 134:     vrelu(p, 1);
 135:     if ((p->p_flag & SLOAD) && (p->p_stat != SRUN || p != u.u_procp))
 136:         panic("swapout");
 137:     p->p_flag &= ~SLOAD;
 138:     vrelpt(p);
 139:     p->p_flag &= ~SLOCK;
 140:     p->p_time = 0;
 141: 
 142:     multprog--;
 143:     cnt.v_swpout++;
 144: 
 145:     if (runout) {
 146:         runout = 0;
 147:         wakeup((caddr_t)&runout);
 148:     }
 149: out:
 150:     xswaplock &= ~s;
 151:     if (xswapwant & s) {
 152:         xswapwant &= ~s;
 153:         wakeup((caddr_t)map);
 154:     }
 155:     return (rc);
 156: }
 157: 
 158: /*
 159:  * Swap the data and stack page tables in or out.
 160:  * Only hard thing is swapping out when new pt size is different than old.
 161:  * If we are growing new pt pages, then we must spread pages with 2 swaps.
 162:  * If we are shrinking pt pages, then we must merge stack pte's into last
 163:  * data page so as not to lose them (and also do two swaps).
 164:  */
 165: swdspt(p, utl, rdwri)
 166:     register struct proc *p;
 167:     register struct user *utl;
 168: {
 169:     register int szpt, tsz, ssz;
 170:     int tdlast, slast, tdsz;
 171:     register struct pte *pte;
 172:     register int i;
 173: 
 174:     szpt = clrnd(ctopt(p->p_tsize+p->p_dsize+p->p_ssize+UPAGES));
 175:     tsz = p->p_tsize / NPTEPG;
 176:     if (szpt == p->p_szpt) {
 177:         swptstat.pteasy++;
 178:         swpt(rdwri, p, 0, tsz,
 179:             (p->p_szpt - tsz) * NBPG - UPAGES * sizeof (struct pte));
 180:         goto check;
 181:     }
 182:     if (szpt < p->p_szpt)
 183:         swptstat.ptshrink++;
 184:     else
 185:         swptstat.ptexpand++;
 186:     ssz = clrnd(ctopt(utl->u_ossize+UPAGES));
 187:     if (szpt < p->p_szpt && utl->u_odsize && (utl->u_ossize+UPAGES)) {
 188:         /*
 189: 		 * Page tables shrinking... see if last text+data and
 190: 		 * last stack page must be merged... if so, copy
 191: 		 * stack pte's from last stack page to end of last
 192: 		 * data page, and decrease size of stack pt to be swapped.
 193: 		 */
 194:         tdlast = (p->p_tsize + utl->u_odsize) % (NPTEPG * CLSIZE);
 195:         slast = (utl->u_ossize + UPAGES) % (NPTEPG * CLSIZE);
 196:         if (tdlast && slast && tdlast + slast <= (NPTEPG * CLSIZE)) {
 197:             swptstat.ptpack++;
 198:             tdsz = clrnd(ctopt(p->p_tsize + utl->u_odsize));
 199:             bcopy((caddr_t)sptopte(p, utl->u_ossize - 1),
 200:                 (caddr_t)&p->p_p0br[tdsz * NPTEPG - slast],
 201:                 (unsigned)(slast * sizeof (struct pte)));
 202:             ssz -= CLSIZE;
 203:         }
 204:     }
 205:     if (ssz)
 206:         swpt(rdwri, p, szpt - ssz - tsz, p->p_szpt - ssz, ssz * NBPG);
 207:     if (utl->u_odsize)
 208:         swpt(rdwri, p, 0, tsz,
 209:           (int)(clrnd(ctopt(p->p_tsize + utl->u_odsize)) - tsz) * NBPG);
 210: check:
 211:     for (i = 0; i < utl->u_odsize; i++) {
 212:         pte = dptopte(p, i);
 213:         if (pte->pg_v || pte->pg_fod == 0 && (pte->pg_pfnum||pte->pg_m))
 214:             panic("swdspt");
 215:     }
 216:     for (i = 0; i < utl->u_ossize; i++) {
 217:         pte = sptopte(p, i);
 218:         if (pte->pg_v || pte->pg_fod == 0 && (pte->pg_pfnum||pte->pg_m))
 219:             panic("swdspt");
 220:     }
 221: }
 222: 
 223: /*
 224:  * Swap a section of the page tables.
 225:  * Errors are handled at a lower level (by doing a panic).
 226:  */
 227: swpt(rdwri, p, doff, a, n)
 228:     int rdwri;
 229:     struct proc *p;
 230:     int doff, a, n;
 231: {
 232: 
 233:     if (n <= 0)
 234:         return;
 235:     (void)swap(p, p->p_swaddr + ctod(UPAGES) + ctod(doff),
 236:         (caddr_t)&p->p_p0br[a * NPTEPG], n, rdwri, B_PAGET, swapdev, 0);
 237: }

Defined functions

swapin defined in line 25; used 1 times
swapout defined in line 83; used 3 times
swdspt defined in line 165; used 2 times
swpt defined in line 227; used 3 times

Defined variables

xswaplock defined in line 76; used 5 times
xswapwant defined in line 76; used 3 times
Last modified: 1986-06-05
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1084
Valid CSS Valid XHTML 1.0 Strict