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_swp.c	2.3 (2.11BSD) 11/30/94
   7:  */
   8: 
   9: #include "param.h"
  10: #include "../machine/seg.h"
  11: 
  12: #include "user.h"
  13: #include "proc.h"
  14: #include "buf.h"
  15: #include "conf.h"
  16: #include "systm.h"
  17: #include "vm.h"
  18: #include "trace.h"
  19: #include "uio.h"
  20: 
  21: /*
  22:  * swap I/O
  23:  */
  24: swap(blkno, coreaddr, count, rdflg)
  25:     memaddr blkno, coreaddr;
  26:     register int count;
  27:     int rdflg;
  28: {
  29:     register struct buf *bp;
  30:     register int tcount;
  31:     int s;
  32: 
  33: #ifdef UCB_METER
  34:     if (rdflg) {
  35:         cnt.v_pswpin += count;
  36:         cnt.v_pgin++;
  37:     }
  38:     else {
  39:         cnt.v_pswpout += count;
  40:         cnt.v_pgout++;
  41:     }
  42: #endif
  43:     bp = geteblk();         /* allocate a buffer header */
  44: 
  45:     while (count) {
  46:         bp->b_flags = B_BUSY | B_PHYS | B_INVAL | rdflg;
  47:         bp->b_dev = swapdev;
  48:         tcount = count;
  49:         if (tcount >= 01700)    /* prevent byte-count wrap */
  50:             tcount = 01700;
  51:         bp->b_bcount = ctob(tcount);
  52:         bp->b_blkno = blkno;
  53:         bp->b_un.b_addr = (caddr_t)(coreaddr<<6);
  54:         bp->b_xmem = (coreaddr>>10) & 077;
  55:         trace(TR_SWAPIO);
  56:         (*bdevsw[major(swapdev)].d_strategy)(bp);
  57:         s = splbio();
  58:         while ((bp->b_flags & B_DONE) == 0)
  59:             sleep((caddr_t)bp, PSWP);
  60:         splx(s);
  61:         if ((bp->b_flags & B_ERROR) || bp->b_resid)
  62:             panic("hard err: swap");
  63:         count -= tcount;
  64:         coreaddr += tcount;
  65:         blkno += ctod(tcount);
  66:     }
  67:     brelse(bp);
  68: }
  69: 
  70: /*
  71:  * rout is the name of the routine where we ran out of swap space.
  72:  */
  73: swkill(p, rout)
  74:     register struct proc *p;
  75:     char *rout;
  76: {
  77: 
  78:     tprintf(u.u_ttyp, "sorry, pid %d killed in %s: no swap space\n",
  79:         p->p_pid, rout);
  80:     /*
  81: 	 * To be sure no looping (e.g. in vmsched trying to
  82: 	 * swap out) mark process locked in core (as though
  83: 	 * done by user) after killing it so noone will try
  84: 	 * to swap it out.
  85: 	 */
  86:     psignal(p, SIGKILL);
  87:     p->p_flag |= SULOCK;
  88: }
  89: 
  90: /*
  91:  * Raw I/O. The arguments are
  92:  *	The strategy routine for the device
  93:  *	A buffer, which may be a special buffer header
  94:  *	  owned exclusively by the device for this purpose or
  95:  *	  NULL if one is to be allocated.
  96:  *	The device number
  97:  *	Read/write flag
  98:  * Essentially all the work is computing physical addresses and
  99:  * validating them.
 100:  *
 101:  * rewritten to use the iov/uio mechanism from 4.3bsd.  the physbuf routine
 102:  * was inlined.  essentially the chkphys routine performs the same task
 103:  * as the useracc routine on a 4.3 system. 3/90 sms
 104:  *
 105:  * If the buffer pointer is NULL then one is allocated "dynamically" from
 106:  * the system cache.  the 'invalid' flag is turned on so that the brelse()
 107:  * done later doesn't place the buffer back in the cache.  the 'phys' flag
 108:  * is left on so that the address of the buffer is recalcuated in getnewbuf().
 109:  * The BYTE/WORD stuff began to be removed after testing proved that either
 110:  * 1) the underlying hardware gives an error or 2) nothing bad happens.
 111:  * besides, 4.3BSD doesn't do the byte/word check and noone could remember
 112:  * why the byte/word check was added in the first place - likely historical
 113:  * paranoia.  chkphys() inlined.  5/91 sms
 114:  *
 115:  * Refined (and streamlined) the flow by using a 'for' construct
 116:  * (a la 4.3Reno).  Avoid allocating/freeing the buffer for each iovec
 117:  * element (i must have been confused at the time).  6/91-sms
 118:  *
 119:  * Finished removing the BYTE/WORD code as part of implementing the common
 120:  * raw read&write routines , systems had been running fine for several
 121:  * months with it ifdef'd out.  9/91-sms
 122:  */
 123: physio(strat, bp, dev, rw, uio)
 124:     int (*strat)();
 125:     register struct buf *bp;
 126:     dev_t dev;
 127:     int rw;
 128:     register struct uio *uio;
 129: {
 130:     int error = 0, s, nb, ts, c, allocbuf = 0;
 131:     register struct iovec *iov;
 132: 
 133:     if (!bp) {
 134:         allocbuf++;
 135:         bp = geteblk();
 136:     }
 137:     u.u_procp->p_flag |= SLOCK;
 138:     for ( ; uio->uio_iovcnt; uio->uio_iov++, uio->uio_iovcnt--) {
 139:         iov = uio->uio_iov;
 140:         if (iov->iov_base >= iov->iov_base + iov->iov_len) {
 141:             error = EFAULT;
 142:             break;
 143:         }
 144:         if (u.u_sep)
 145:             ts = 0;
 146:         else
 147:             ts = (u.u_tsize + 127) & ~0177;
 148:         nb = ((int)iov->iov_base >> 6) & 01777;
 149:         /*
 150: 		 * Check overlap with text. (ts and nb now
 151: 		 * in 64-byte clicks)
 152: 		 */
 153:         if (nb < ts) {
 154:             error = EFAULT;
 155:             break;
 156:         }
 157:         /*
 158: 		 * Check that transfer is either entirely in the
 159: 		 * data or in the stack: that is, either
 160: 		 * the end is in the data or the start is in the stack
 161: 		 * (remember wraparound was already checked).
 162: 		 */
 163:         if (((((int)iov->iov_base + iov->iov_len) >> 6) & 01777) >=
 164:             ts + u.u_dsize && nb < 1024 - u.u_ssize) {
 165:             error = EFAULT;
 166:             break;
 167:         }
 168:         if (!allocbuf) {
 169:             s = splbio();
 170:             while (bp->b_flags & B_BUSY) {
 171:                 bp->b_flags |= B_WANTED;
 172:                 sleep((caddr_t)bp, PRIBIO+1);
 173:             }
 174:             splx(s);
 175:         }
 176:         bp->b_error = 0;
 177:         while (iov->iov_len) {
 178:             bp->b_flags = B_BUSY|B_PHYS|B_INVAL|rw;
 179:             bp->b_dev = dev;
 180:             nb = ((int)iov->iov_base >> 6) & 01777;
 181:             ts = (u.u_sep ? UDSA : UISA)[nb >> 7] + (nb & 0177);
 182:             bp->b_un.b_addr = (caddr_t)((ts << 6) + ((int)iov->iov_base & 077));
 183:             bp->b_xmem = (ts >> 10) & 077;
 184:             bp->b_blkno = uio->uio_offset >> PGSHIFT;
 185:             bp->b_bcount = iov->iov_len;
 186:             c = bp->b_bcount;
 187:             (*strat)(bp);
 188:             s = splbio();
 189:             while ((bp->b_flags & B_DONE) == 0)
 190:                 sleep((caddr_t)bp, PRIBIO);
 191:             if (bp->b_flags & B_WANTED) /* rare */
 192:                 wakeup((caddr_t)bp);
 193:             splx(s);
 194:             c -= bp->b_resid;
 195:             iov->iov_base += c;
 196:             iov->iov_len -= c;
 197:             uio->uio_resid -= c;
 198:             uio->uio_offset += c;
 199:             /* temp kludge for tape drives */
 200:             if (bp->b_resid || (bp->b_flags & B_ERROR))
 201:                 break;
 202:         }
 203:         bp->b_flags &= ~(B_BUSY|B_WANTED);
 204:         error = geterror(bp);
 205:         /* temp kludge for tape drives */
 206:         if (bp->b_resid || error)
 207:             break;
 208:     }
 209:     if (allocbuf)
 210:         brelse(bp);
 211:     u.u_procp->p_flag &= ~SLOCK;
 212:     return(error);
 213: }
 214: 
 215: rawrw(dev, uio, flag)
 216:     dev_t dev;
 217:     register struct uio *uio;
 218:     int flag;
 219:     {
 220:     return(physio(cdevsw[major(dev)].d_strategy, (struct buf *)NULL, dev,
 221:         uio->uio_rw == UIO_READ ? B_READ : B_WRITE, uio));
 222:     }

Defined functions

physio defined in line 123; used 1 times
rawrw defined in line 215; used 27 times
swap defined in line 24; used 10 times
swkill defined in line 73; used 2 times
Last modified: 1994-12-01
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3010
Valid CSS Valid XHTML 1.0 Strict