1: /* 2: * Copyright (c) 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 1.3 (2.11BSD GTE) 3/10/93 7: */ 8: 9: #include "param.h" 10: #include "../machine/seg.h" 11: 12: #include "user.h" 13: #include "proc.h" 14: #include "text.h" 15: #include "map.h" 16: #include "buf.h" 17: #include "systm.h" 18: #include "vm.h" 19: 20: /* 21: * Swap a process in. 22: * Allocate data and possible text separately. It would be better 23: * to do largest first. Text, data, stack and u. are allocated in 24: * that order, as that is likely to be in order of size. 25: */ 26: swapin(p) 27: register struct proc *p; 28: { 29: register struct text *xp; 30: register memaddr x = NULL; 31: memaddr a[3]; 32: 33: /* Malloc the text segment first, as it tends to be largest. */ 34: xp = p->p_textp; 35: if (xp) { 36: xlock(xp); 37: if (!xp->x_caddr && !xp->x_ccount) { 38: x = malloc(coremap, xp->x_size); 39: if (!x) { 40: xunlock(xp); 41: return(0); 42: } 43: } 44: } 45: if (malloc3(coremap, p->p_dsize, p->p_ssize, USIZE, a) == NULL) { 46: if (x) 47: mfree(coremap, xp->x_size, x); 48: if (xp) 49: xunlock(xp); 50: return(0); 51: } 52: if (xp) { 53: if (x) { 54: xp->x_caddr = x; 55: if ((xp->x_flag & XLOAD) == 0) 56: swap(xp->x_daddr, x, xp->x_size, B_READ); 57: } 58: xp->x_ccount++; 59: xunlock(xp); 60: } 61: if (p->p_dsize) { 62: swap(p->p_daddr, a[0], p->p_dsize, B_READ); 63: mfree(swapmap, ctod(p->p_dsize), p->p_daddr); 64: } 65: if (p->p_ssize) { 66: swap(p->p_saddr, a[1], p->p_ssize, B_READ); 67: mfree(swapmap, ctod(p->p_ssize), p->p_saddr); 68: } 69: swap(p->p_addr, a[2], USIZE, B_READ); 70: mfree(swapmap, ctod(USIZE), p->p_addr); 71: p->p_daddr = a[0]; 72: p->p_saddr = a[1]; 73: p->p_addr = a[2]; 74: if (p->p_stat == SRUN) 75: setrq(p); 76: p->p_flag |= SLOAD; 77: p->p_time = 0; 78: #ifdef UCB_METER 79: cnt.v_swpin++; 80: #endif 81: return(1); 82: } 83: 84: /* 85: * Swap out process p. 86: * odata and ostack are the old data size and the stack size 87: * of the process, and are supplied during core expansion swaps. 88: * The freecore flag causes its core to be freed -- it may be 89: * off when called to create an image for a child process 90: * in newproc. 91: * 92: * panic: out of swap space 93: */ 94: swapout(p, freecore, odata, ostack) 95: register struct proc *p; 96: int freecore; 97: register u_int odata, ostack; 98: { 99: memaddr a[3]; 100: 101: if (odata == (u_int)X_OLDSIZE) 102: odata = p->p_dsize; 103: if (ostack == (u_int)X_OLDSIZE) 104: ostack = p->p_ssize; 105: if (malloc3(swapmap, ctod(p->p_dsize), ctod(p->p_ssize), 106: ctod(USIZE), a) == NULL) 107: panic("out of swap space"); 108: p->p_flag |= SLOCK; 109: if (p->p_textp) 110: xccdec(p->p_textp); 111: if (odata) { 112: swap(a[0], p->p_daddr, odata, B_WRITE); 113: if (freecore == X_FREECORE) 114: mfree(coremap, odata, p->p_daddr); 115: } 116: if (ostack) { 117: swap(a[1], p->p_saddr, ostack, B_WRITE); 118: if (freecore == X_FREECORE) 119: mfree(coremap, ostack, p->p_saddr); 120: } 121: /* 122: * Increment u_ru.ru_nswap for process being tossed out of core. 123: * We can be called to swap out a process other than the current 124: * process, so we have to map in the victim's u structure briefly. 125: * Note, savekdsa6 *must* be a static, because we remove the stack 126: * in the next instruction. The splclock is to prevent the clock 127: * from coming in and doing accounting for the wrong process, plus 128: * we don't want to come through here twice. Why are we doing 129: * this, anyway? 130: */ 131: { 132: static u_short savekdsa6; 133: int s; 134: 135: s = splclock(); 136: savekdsa6 = *KDSA6; 137: *KDSA6 = p->p_addr; 138: u.u_ru.ru_nswap++; 139: *KDSA6 = savekdsa6; 140: splx(s); 141: } 142: swap(a[2], p->p_addr, USIZE, B_WRITE); 143: if (freecore == X_FREECORE) 144: mfree(coremap, USIZE, p->p_addr); 145: p->p_daddr = a[0]; 146: p->p_saddr = a[1]; 147: p->p_addr = a[2]; 148: p->p_flag &= ~(SLOAD|SLOCK); 149: p->p_time = 0; 150: 151: #ifdef UCB_METER 152: cnt.v_swpout++; 153: #endif 154: 155: if (runout) { 156: runout = 0; 157: wakeup((caddr_t)&runout); 158: } 159: }