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