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