rename raw imp stuff and add in raw pup
[unix-history] / usr / src / sys / kern / kern_physio.c
index c88dac9..e5d3a5f 100644 (file)
@@ -1,4 +1,4 @@
-/*     kern_physio.c   4.14    %G%     */
+/*     kern_physio.c   4.25    82/01/17        */
 
 #include "../h/param.h"
 #include "../h/systm.h"
 
 #include "../h/param.h"
 #include "../h/systm.h"
@@ -34,6 +34,9 @@
  *     brelse
  */
 
  *     brelse
  */
 
+struct buf bfreelist[BQUEUES];
+struct buf bswlist, *bclnlist;
+
 #define        BUFHSZ  63
 struct bufhd bufhash[BUFHSZ];
 #define        BUFHASH(dev, dblkno)    \
 #define        BUFHSZ  63
 struct bufhd bufhash[BUFHSZ];
 #define        BUFHASH(dev, dblkno)    \
@@ -102,8 +105,8 @@ daddr_t blkno;
 
        bp = getblk(dev, blkno);
        if (bp->b_flags&B_DONE) {
 
        bp = getblk(dev, blkno);
        if (bp->b_flags&B_DONE) {
-#ifdef EPAWNJ
-               trace(TR_BREAD|TR_HIT, dev, blkno);
+#ifdef TRACE
+               trace(TR_BREADHIT, dev, blkno);
 #endif
 #ifdef DISKMON
                io_info.ncache++;
 #endif
 #ifdef DISKMON
                io_info.ncache++;
@@ -113,8 +116,8 @@ daddr_t blkno;
        bp->b_flags |= B_READ;
        bp->b_bcount = BSIZE;
        (*bdevsw[major(dev)].d_strategy)(bp);
        bp->b_flags |= B_READ;
        bp->b_bcount = BSIZE;
        (*bdevsw[major(dev)].d_strategy)(bp);
-#ifdef EPAWNJ
-       trace(TR_BREAD|TR_MISS, dev, blkno);
+#ifdef TRACE
+       trace(TR_BREADMISS, dev, blkno);
 #endif
 #ifdef DISKMON
        io_info.nread++;
 #endif
 #ifdef DISKMON
        io_info.nread++;
@@ -142,32 +145,32 @@ daddr_t blkno, rablkno;
                        bp->b_flags |= B_READ;
                        bp->b_bcount = BSIZE;
                        (*bdevsw[major(dev)].d_strategy)(bp);
                        bp->b_flags |= B_READ;
                        bp->b_bcount = BSIZE;
                        (*bdevsw[major(dev)].d_strategy)(bp);
-#ifdef EPAWNJ
-                       trace(TR_BREAD|TR_MISS, dev, blkno);
+#ifdef TRACE
+                       trace(TR_BREADMISS, dev, blkno);
 #endif
 #ifdef DISKMON
                        io_info.nread++;
 #endif
                        u.u_vm.vm_inblk++;              /* pay for read */
                }
 #endif
 #ifdef DISKMON
                        io_info.nread++;
 #endif
                        u.u_vm.vm_inblk++;              /* pay for read */
                }
-#ifdef EPAWNJ
+#ifdef TRACE
                else
                else
-                       trace(TR_BREAD|TR_HIT, dev, blkno);
+                       trace(TR_BREADHIT, dev, blkno);
 #endif
        }
        if (rablkno && !incore(dev, rablkno)) {
                rabp = getblk(dev, rablkno);
                if (rabp->b_flags & B_DONE) {
                        brelse(rabp);
 #endif
        }
        if (rablkno && !incore(dev, rablkno)) {
                rabp = getblk(dev, rablkno);
                if (rabp->b_flags & B_DONE) {
                        brelse(rabp);
-#ifdef EPAWNJ
-                       trace(TR_BREAD|TR_HIT|TR_RA, dev, blkno);
+#ifdef TRACE
+                       trace(TR_BREADHITRA, dev, blkno);
 #endif
                } else {
                        rabp->b_flags |= B_READ|B_ASYNC;
                        rabp->b_bcount = BSIZE;
                        (*bdevsw[major(dev)].d_strategy)(rabp);
 #endif
                } else {
                        rabp->b_flags |= B_READ|B_ASYNC;
                        rabp->b_bcount = BSIZE;
                        (*bdevsw[major(dev)].d_strategy)(rabp);
-#ifdef EPAWNJ
-                       trace(TR_BREAD|TR_MISS|TR_RA, dev, rablock);
+#ifdef TRACE
+                       trace(TR_BREADMISSRA, dev, rablock);
 #endif
 #ifdef DISKMON
                        io_info.nreada++;
 #endif
 #ifdef DISKMON
                        io_info.nreada++;
@@ -198,8 +201,8 @@ register struct buf *bp;
 #endif
        if ((flag&B_DELWRI) == 0)
                u.u_vm.vm_oublk++;              /* noone paid yet */
 #endif
        if ((flag&B_DELWRI) == 0)
                u.u_vm.vm_oublk++;              /* noone paid yet */
-#ifdef EPAWNJ
-       trace(TR_BWRITE, bp->b_dev, dbtofsb(bp->b_blkno));
+#ifdef TRACE
+       trace(TR_BWRITE, bp->b_dev, bp->b_blkno);
 #endif
        (*bdevsw[major(bp->b_dev)].d_strategy)(bp);
        if ((flag&B_ASYNC) == 0) {
 #endif
        (*bdevsw[major(bp->b_dev)].d_strategy)(bp);
        if ((flag&B_ASYNC) == 0) {
@@ -325,6 +328,10 @@ daddr_t blkno;
  * Assign a buffer for the given block.  If the appropriate
  * block is already associated, return it; otherwise search
  * for the oldest non-busy buffer and reassign it.
  * Assign a buffer for the given block.  If the appropriate
  * block is already associated, return it; otherwise search
  * for the oldest non-busy buffer and reassign it.
+ *
+ * We use splx here because this routine may be called
+ * on the interrupt stack during a dump, and we don't
+ * want to lower the ipl back to 0.
  */
 struct buf *
 getblk(dev, blkno)
  */
 struct buf *
 getblk(dev, blkno)
@@ -336,24 +343,25 @@ daddr_t blkno;
 #ifdef DISKMON
        register int i;
 #endif
 #ifdef DISKMON
        register int i;
 #endif
+       int s;
 
        if ((unsigned)blkno >= 1 << (sizeof(int)*NBBY-PGSHIFT))
                blkno = 1 << ((sizeof(int)*NBBY-PGSHIFT) + 1);
        dblkno = fsbtodb(blkno);
        dp = BUFHASH(dev, dblkno);
     loop:
 
        if ((unsigned)blkno >= 1 << (sizeof(int)*NBBY-PGSHIFT))
                blkno = 1 << ((sizeof(int)*NBBY-PGSHIFT) + 1);
        dblkno = fsbtodb(blkno);
        dp = BUFHASH(dev, dblkno);
     loop:
-       (void) spl0();
        for (bp = dp->b_forw; bp != dp; bp = bp->b_forw) {
                if (bp->b_blkno != dblkno || bp->b_dev != dev ||
                    bp->b_flags&B_INVAL)
                        continue;
        for (bp = dp->b_forw; bp != dp; bp = bp->b_forw) {
                if (bp->b_blkno != dblkno || bp->b_dev != dev ||
                    bp->b_flags&B_INVAL)
                        continue;
-               (void) spl6();
+               s = spl6();
                if (bp->b_flags&B_BUSY) {
                        bp->b_flags |= B_WANTED;
                        sleep((caddr_t)bp, PRIBIO+1);
                if (bp->b_flags&B_BUSY) {
                        bp->b_flags |= B_WANTED;
                        sleep((caddr_t)bp, PRIBIO+1);
+                       splx(s);
                        goto loop;
                }
                        goto loop;
                }
-               (void) spl0();
+               splx(s);
 #ifdef DISKMON
                i = 0;
                dp = bp->av_forw;
 #ifdef DISKMON
                i = 0;
                dp = bp->av_forw;
@@ -370,16 +378,17 @@ daddr_t blkno;
        }
        if (major(dev) >= nblkdev)
                panic("blkdev");
        }
        if (major(dev) >= nblkdev)
                panic("blkdev");
-       (void) spl6();
+       s = spl6();
        for (ep = &bfreelist[BQUEUES-1]; ep > bfreelist; ep--)
                if (ep->av_forw != ep)
                        break;
        if (ep == bfreelist) {          /* no free blocks at all */
                ep->b_flags |= B_WANTED;
                sleep((caddr_t)ep, PRIBIO+1);
        for (ep = &bfreelist[BQUEUES-1]; ep > bfreelist; ep--)
                if (ep->av_forw != ep)
                        break;
        if (ep == bfreelist) {          /* no free blocks at all */
                ep->b_flags |= B_WANTED;
                sleep((caddr_t)ep, PRIBIO+1);
+               splx(s);
                goto loop;
        }
                goto loop;
        }
-       (void) spl0();
+       splx(s);
        bp = ep->av_forw;
        notavail(bp);
        if (bp->b_flags & B_DELWRI) {
        bp = ep->av_forw;
        notavail(bp);
        if (bp->b_flags & B_DELWRI) {
@@ -387,8 +396,8 @@ daddr_t blkno;
                bwrite(bp);
                goto loop;
        }
                bwrite(bp);
                goto loop;
        }
-#ifdef EPAWNJ
-       trace(TR_BRELSE, bp->b_dev, dbtofsb(bp->b_blkno));
+#ifdef TRACE
+       trace(TR_BRELSE, bp->b_dev, bp->b_blkno);
 #endif
        bp->b_flags = B_BUSY;
        bp->b_back->b_forw = bp->b_forw;
 #endif
        bp->b_flags = B_BUSY;
        bp->b_back->b_forw = bp->b_forw;
@@ -410,9 +419,10 @@ struct buf *
 geteblk()
 {
        register struct buf *bp, *dp;
 geteblk()
 {
        register struct buf *bp, *dp;
+       int s;
 
 loop:
 
 loop:
-       (void) spl6();
+       s = spl6();
        for (dp = &bfreelist[BQUEUES-1]; dp > bfreelist; dp--)
                if (dp->av_forw != dp)
                        break;
        for (dp = &bfreelist[BQUEUES-1]; dp > bfreelist; dp--)
                if (dp->av_forw != dp)
                        break;
@@ -421,7 +431,7 @@ loop:
                sleep((caddr_t)dp, PRIBIO+1);
                goto loop;
        }
                sleep((caddr_t)dp, PRIBIO+1);
                goto loop;
        }
-       (void) spl0();
+       splx(s);
        bp = dp->av_forw;
        notavail(bp);
        if (bp->b_flags & B_DELWRI) {
        bp = dp->av_forw;
        notavail(bp);
        if (bp->b_flags & B_DELWRI) {
@@ -429,8 +439,8 @@ loop:
                bwrite(bp);
                goto loop;
        }
                bwrite(bp);
                goto loop;
        }
-#ifdef EPAWNJ
-       trace(TR_BRELSE, bp->b_dev, dbtofsb(bp->b_blkno));
+#ifdef TRACE
+       trace(TR_BRELSE, bp->b_dev, bp->b_blkno);
 #endif
        bp->b_flags = B_BUSY|B_INVAL;
        bp->b_back->b_forw = bp->b_forw;
 #endif
        bp->b_flags = B_BUSY|B_INVAL;
        bp->b_back->b_forw = bp->b_forw;
@@ -450,11 +460,12 @@ loop:
 iowait(bp)
 register struct buf *bp;
 {
 iowait(bp)
 register struct buf *bp;
 {
+       int s;
 
 
-       (void) spl6();
+       s = spl6();
        while ((bp->b_flags&B_DONE)==0)
                sleep((caddr_t)bp, PRIBIO);
        while ((bp->b_flags&B_DONE)==0)
                sleep((caddr_t)bp, PRIBIO);
-       (void) spl0();
+       splx(s);
        geterror(bp);
 }
 
        geterror(bp);
 }
 
@@ -496,10 +507,11 @@ register struct buf *bp;
                if (bp->b_flags & B_ERROR)
                        panic("IO err in push");
                s = spl6();
                if (bp->b_flags & B_ERROR)
                        panic("IO err in push");
                s = spl6();
-               cnt.v_pgout++;
                bp->av_forw = bclnlist;
                bp->b_bcount = swsize[bp - swbuf];
                bp->b_pfcent = swpf[bp - swbuf];
                bp->av_forw = bclnlist;
                bp->b_bcount = swsize[bp - swbuf];
                bp->b_pfcent = swpf[bp - swbuf];
+               cnt.v_pgout++;
+               cnt.v_pgpgout += bp->b_bcount / NBPG;
                bclnlist = bp;
                if (bswlist.b_flags & B_WANTED)
                        wakeup((caddr_t)&proc[2]);
                bclnlist = bp;
                if (bswlist.b_flags & B_WANTED)
                        wakeup((caddr_t)&proc[2]);
@@ -555,15 +567,16 @@ swap(p, dblkno, addr, nbytes, rdflg, flag, dev, pfcent)
        register int c;
        int p2dp;
        register struct pte *dpte, *vpte;
        register int c;
        int p2dp;
        register struct pte *dpte, *vpte;
+       int s;
 
 
-       (void) spl6();
+       s = spl6();
        while (bswlist.av_forw == NULL) {
                bswlist.b_flags |= B_WANTED;
                sleep((caddr_t)&bswlist, PSWP+1);
        }
        bp = bswlist.av_forw;
        bswlist.av_forw = bp->av_forw;
        while (bswlist.av_forw == NULL) {
                bswlist.b_flags |= B_WANTED;
                sleep((caddr_t)&bswlist, PSWP+1);
        }
        bp = bswlist.av_forw;
        bswlist.av_forw = bp->av_forw;
-       (void) spl0();
+       splx(s);
 
        bp->b_flags = B_BUSY | B_PHYS | rdflg | flag;
        if ((bp->b_flags & (B_DIRTY|B_PGIN)) == 0)
 
        bp->b_flags = B_BUSY | B_PHYS | rdflg | flag;
        if ((bp->b_flags & (B_DIRTY|B_PGIN)) == 0)
@@ -593,16 +606,19 @@ swap(p, dblkno, addr, nbytes, rdflg, flag, dev, pfcent)
                        swpf[bp - swbuf] = pfcent;
                        swsize[bp - swbuf] = nbytes;
                }
                        swpf[bp - swbuf] = pfcent;
                        swsize[bp - swbuf] = nbytes;
                }
+#ifdef TRACE
+               trace(TR_SWAPIO, dev, bp->b_blkno);
+#endif
                (*bdevsw[major(dev)].d_strategy)(bp);
                if (flag & B_DIRTY) {
                        if (c < nbytes)
                                panic("big push");
                        return;
                }
                (*bdevsw[major(dev)].d_strategy)(bp);
                if (flag & B_DIRTY) {
                        if (c < nbytes)
                                panic("big push");
                        return;
                }
-               (void) spl6();
+               s = spl6();
                while((bp->b_flags&B_DONE)==0)
                        sleep((caddr_t)bp, PSWP);
                while((bp->b_flags&B_DONE)==0)
                        sleep((caddr_t)bp, PSWP);
-               (void) spl0();
+               splx(s);
                bp->b_un.b_addr += c;
                bp->b_flags &= ~B_DONE;
                if (bp->b_flags & B_ERROR) {
                bp->b_un.b_addr += c;
                bp->b_flags &= ~B_DONE;
                if (bp->b_flags & B_ERROR) {
@@ -613,7 +629,7 @@ swap(p, dblkno, addr, nbytes, rdflg, flag, dev, pfcent)
                nbytes -= c;
                dblkno += btoc(c);
        }
                nbytes -= c;
                dblkno += btoc(c);
        }
-       (void) spl6();
+       s = spl6();
        bp->b_flags &= ~(B_BUSY|B_WANTED|B_PHYS|B_PAGET|B_UAREA|B_DIRTY);
        bp->av_forw = bswlist.av_forw;
        bswlist.av_forw = bp;
        bp->b_flags &= ~(B_BUSY|B_WANTED|B_PHYS|B_PAGET|B_UAREA|B_DIRTY);
        bp->av_forw = bswlist.av_forw;
        bswlist.av_forw = bp;
@@ -622,7 +638,7 @@ swap(p, dblkno, addr, nbytes, rdflg, flag, dev, pfcent)
                wakeup((caddr_t)&bswlist);
                wakeup((caddr_t)&proc[2]);
        }
                wakeup((caddr_t)&bswlist);
                wakeup((caddr_t)&proc[2]);
        }
-       (void) spl0();
+       splx(s);
 }
 
 /*
 }
 
 /*
@@ -634,12 +650,14 @@ swkill(p, rout)
        struct proc *p;
        char *rout;
 {
        struct proc *p;
        char *rout;
 {
+       char *mesg;
 
 
-       printf("%d: ", p->p_pid);
+       printf("pid %d: ", p->p_pid);
        if (rout)
        if (rout)
-               printf("out of swap space in %s\n", rout);
+               printf(mesg = "killed due to no swap space\n");
        else
        else
-               printf("killed on swap error\n");
+               printf(mesg = "killed on swap error\n");
+       uprintf("sorry, pid %d was %s", p->p_pid, mesg);
        /*
         * To be sure no looping (e.g. in vmsched trying to
         * swap out) mark process locked in core (as though
        /*
         * To be sure no looping (e.g. in vmsched trying to
         * swap out) mark process locked in core (as though
@@ -661,9 +679,10 @@ dev_t dev;
 {
        register struct buf *bp;
        register struct buf *flist;
 {
        register struct buf *bp;
        register struct buf *flist;
+       int s;
 
 loop:
 
 loop:
-       (void) spl6();
+       s = spl6();
        for (flist = bfreelist; flist < &bfreelist[BQUEUES]; flist++)
        for (bp = flist->av_forw; bp != flist; bp = bp->av_forw) {
                if (bp->b_flags&B_DELWRI && (dev == NODEV||dev==bp->b_dev)) {
        for (flist = bfreelist; flist < &bfreelist[BQUEUES]; flist++)
        for (bp = flist->av_forw; bp != flist; bp = bp->av_forw) {
                if (bp->b_flags&B_DELWRI && (dev == NODEV||dev==bp->b_dev)) {
@@ -673,7 +692,7 @@ loop:
                        goto loop;
                }
        }
                        goto loop;
                }
        }
-       (void) spl0();
+       splx(s);
 }
 
 /*
 }
 
 /*
@@ -697,12 +716,13 @@ unsigned (*mincnt)();
 {
        register int c;
        char *a;
 {
        register int c;
        char *a;
+       int s;
 
        if (useracc(u.u_base,u.u_count,rw==B_READ?B_WRITE:B_READ) == NULL) {
                u.u_error = EFAULT;
                return;
        }
 
        if (useracc(u.u_base,u.u_count,rw==B_READ?B_WRITE:B_READ) == NULL) {
                u.u_error = EFAULT;
                return;
        }
-       (void) spl6();
+       s = spl6();
        while (bp->b_flags&B_BUSY) {
                bp->b_flags |= B_WANTED;
                sleep((caddr_t)bp, PRIBIO+1);
        while (bp->b_flags&B_BUSY) {
                bp->b_flags |= B_WANTED;
                sleep((caddr_t)bp, PRIBIO+1);
@@ -710,7 +730,7 @@ unsigned (*mincnt)();
        bp->b_error = 0;
        bp->b_proc = u.u_procp;
        bp->b_un.b_addr = u.u_base;
        bp->b_error = 0;
        bp->b_proc = u.u_procp;
        bp->b_un.b_addr = u.u_base;
-       while (u.u_count != 0 && bp->b_error==0) {
+       while (u.u_count != 0) {
                bp->b_flags = B_BUSY | B_PHYS | rw;
                bp->b_dev = dev;
                bp->b_blkno = u.u_offset >> PGSHIFT;
                bp->b_flags = B_BUSY | B_PHYS | rw;
                bp->b_dev = dev;
                bp->b_blkno = u.u_offset >> PGSHIFT;
@@ -727,10 +747,12 @@ unsigned (*mincnt)();
                u.u_procp->p_flag &= ~SPHYSIO;
                if (bp->b_flags&B_WANTED)
                        wakeup((caddr_t)bp);
                u.u_procp->p_flag &= ~SPHYSIO;
                if (bp->b_flags&B_WANTED)
                        wakeup((caddr_t)bp);
-               (void) spl0();
+               splx(s);
                bp->b_un.b_addr += c;
                u.u_count -= c;
                u.u_offset += c;
                bp->b_un.b_addr += c;
                u.u_count -= c;
                u.u_offset += c;
+               if (bp->b_flags&B_ERROR)
+                       break;
        }
        bp->b_flags &= ~(B_BUSY|B_WANTED|B_PHYS);
        u.u_count = bp->b_resid;
        }
        bp->b_flags &= ~(B_BUSY|B_WANTED|B_PHYS);
        u.u_count = bp->b_resid;