# 2.11BSD#431 - /usr/src/sys/sys/vm_swp.c

##### Functions

    physio            X
    rawrw             X
    swap              X
    swkill            X

       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

- in line 220

rawrw defined in line 215; used 27 times

- in /usr/src/sys/pdp/conf.c line 22, 385-393(6), 409-441(18), 453(2)

swap defined in line 24; used 10 times

- in /usr/src/sys/sys/vm_swap.c line 56, 62-69(3), 112-117(2), 142
- in /usr/src/sys/sys/vm_text.c line 258, 315, 378

swkill defined in line 73; used 2 times

- in /usr/src/sys/sys/kern_exec.c line 196
- in /usr/src/sys/sys/vm_text.c line 205

Last modified: 1994-12-01 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 734 |