Subject: 1. physio() changes, 2. physstrat inlined, 3. save ~40bytes of Dspace Index: sys/{sys,pdp}/ 2.11BSD Description: Files sys/{kern_exec,vm_swp,vm_text}.c and sys/pdp/machdep.c are modified in this patch. The physio() and swap() routines were changed to more closely resemble their recent 4BSD counterparts. Also, a minor bit of unnecessary overhead was removed from physio(). The swkill() routine was altered to use 'tprintf()' instead of 'uprintf()'. This removes the need for a separate 'printf()' to place the message in the console and /dev/klog buffers. The common message suffix in the two references to 'swkill()' was removed and the text placed in the single 'tprintf' statement in 'swkill'. This saves about 40 bytes of D space. Repeat-By: Examine the code. Fix: Apply the following patch and rebuild the kernel at your leisure. *** /usr/src/sys/sys/vm_swp.c.old Sat May 18 22:03:16 1991 --- /usr/src/sys/sys/vm_swp.c Thu Jun 6 20:00:24 1991 *************** *** 3,9 **** * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. * ! * @(#)vm_swp.c 2.0 (2.11BSD) 5/18/91 */ #include "param.h" --- 3,9 ---- * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. * ! * @(#)vm_swp.c 2.1 (2.11BSD) 6/6/91 */ #include "param.h" *************** *** 53,61 **** bp->b_un.b_addr = (caddr_t)(coreaddr<<6); bp->b_xmem = (coreaddr>>10) & 077; trace(TR_SWAPIO); ! physstrat(bp, bdevsw[major(swapdev)].d_strategy, PSWP); if ((bp->b_flags & B_ERROR) || bp->b_resid) ! panic("hard IO err in swap"); count -= tcount; coreaddr += tcount; blkno += ctod(tcount); --- 53,65 ---- bp->b_un.b_addr = (caddr_t)(coreaddr<<6); bp->b_xmem = (coreaddr>>10) & 077; trace(TR_SWAPIO); ! (*bdevsw[major(swapdev)].d_strategy)(bp); ! s = splbio(); ! while ((bp->b_flags & B_DONE) == 0) ! sleep((caddr_t)bp, PSWP); ! splx(s); if ((bp->b_flags & B_ERROR) || bp->b_resid) ! panic("hard err: swap"); count -= tcount; coreaddr += tcount; blkno += ctod(tcount); *************** *** 64,80 **** } /* ! * If rout == 0 then killed on swap error, else ! * rout is the name of the routine where we ran out of ! * swap space. */ swkill(p, rout) register struct proc *p; ! register char *rout; { ! printf("pid %d: %s\n", p->p_pid, rout); ! uprintf("sorry, pid %d was killed in %s\n", p->p_pid, rout); /* * To be sure no looping (e.g. in vmsched trying to * swap out) mark process locked in core (as though --- 68,82 ---- } /* ! * rout is the name of the routine where we ran out of swap space. */ swkill(p, rout) register struct proc *p; ! char *rout; { ! tprintf(u.u_ttyp, "sorry, pid %d killed in %s: no swap space\n", ! p->p_pid, rout); /* * To be sure no looping (e.g. in vmsched trying to * swap out) mark process locked in core (as though *************** *** 109,114 **** --- 111,120 ---- * besides, 4.3BSD doesn't do the byte/word check and noone could remember * why the byte/word check was added in the first place - likely historical * paranoia. chkphys() inlined. 5/91 sms + * + * Refined (and streamlined) the flow by using a 'for' construct + * (a la 4.3Reno). Avoid allocating/freeing the buffer for each iovec + * element (i must have been confused at the time). 6/91-sms */ physio(strat, bp, dev, rw, kind, uio) int (*strat)(); *************** *** 117,134 **** int rw, kind; register struct uio *uio; { ! int error, s, nb, ts, c, alloc = 0; register struct iovec *iov; ! if (!bp) ! alloc++; u.u_procp->p_flag |= SLOCK; ! nextiov: ! error = 0; ! if (uio->uio_iovcnt == 0) ! goto out; ! iov = uio->uio_iov; ! #ifdef whybother /* * Check odd base, odd count, and address wraparound --- 123,138 ---- int rw, kind; register struct uio *uio; { ! int error = 0, s, nb, ts, c, allocbuf = 0; register struct iovec *iov; ! if (!bp) { ! allocbuf++; ! bp = geteblk(); ! } u.u_procp->p_flag |= SLOCK; ! for ( ; uio->uio_iovcnt; uio->uio_iov++, uio->uio_iovcnt--) { ! iov = uio->uio_iov; #ifdef whybother /* * Check odd base, odd count, and address wraparound *************** *** 135,215 **** * Odd base and count not allowed if flag = WORD, * allowed if flag = BYTE. */ ! if (kind == WORD && (((int)iov->iov_base|iov->iov_len) & 01)) ! goto efault; #endif ! if (iov->iov_base >= iov->iov_base + iov->iov_len) ! goto efault; ! if (u.u_sep) ! ts = 0; ! else ! ts = (u.u_tsize + 127) & ~0177; ! nb = ((int)iov->iov_base >> 6) & 01777; ! /* ! * Check overlap with text. (ts and nb now ! * in 64-byte clicks) ! */ ! if (nb < ts) ! goto efault; ! /* ! * Check that transfer is either entirely in the ! * data or in the stack: that is, either ! * the end is in the data or the start is in the stack ! * (remember wraparound was already checked). ! */ ! if (((((int)iov->iov_base + iov->iov_len) >> 6) & 01777) >= ts + u.u_dsize && ! nb < 1024 - u.u_ssize) ! goto efault; ! ! if (alloc) ! bp = geteblk(); ! else { ! s = splbio(); ! while (bp->b_flags & B_BUSY) { ! bp->b_flags |= B_WANTED; ! sleep((caddr_t)bp, PRIBIO+1); } ! splx(s); ! } ! while (iov->iov_len) { ! bp->b_flags = B_BUSY|B_PHYS|B_INVAL|rw; ! bp->b_dev = dev; nb = ((int)iov->iov_base >> 6) & 01777; ! ts = (u.u_sep ? UDSA : UISA)[nb >> 7] + (nb & 0177); ! bp->b_un.b_addr = (caddr_t)((ts << 6) + ((int)iov->iov_base & 077)); ! bp->b_xmem = (ts >> 10) & 077; ! bp->b_blkno = uio->uio_offset >> PGSHIFT; ! bp->b_bcount = iov->iov_len; ! c = bp->b_bcount; bp->b_error = 0; ! physstrat(bp, strat, PRIBIO); ! c -= bp->b_resid; ! iov->iov_base += c; ! iov->iov_len -= c; ! uio->uio_resid -= c; ! uio->uio_offset += c; /* temp kludge for tape drives */ ! if (bp->b_resid || (bp->b_flags & B_ERROR)) break; } ! error = geterror(bp); ! c = bp->b_resid; ! if (!alloc) { ! if (bp->b_flags & B_WANTED) ! wakeup((caddr_t)bp); ! bp->b_flags &= ~(B_BUSY|B_WANTED); ! } ! else brelse(bp); - /* temp kludge for tape drives */ - if (c || error) - goto out; - uio->uio_iov++; - uio->uio_iovcnt--; - goto nextiov; - efault: - error = EFAULT; - out: u.u_procp->p_flag &= ~SLOCK; return(error); } --- 139,220 ---- * Odd base and count not allowed if flag = WORD, * allowed if flag = BYTE. */ ! if (kind == WORD && (((int)iov->iov_base|iov->iov_len) & 01)) { ! error = EFAULT; ! break; ! } #endif ! if (iov->iov_base >= iov->iov_base + iov->iov_len) { ! error = EFAULT; ! break; } ! if (u.u_sep) ! ts = 0; ! else ! ts = (u.u_tsize + 127) & ~0177; nb = ((int)iov->iov_base >> 6) & 01777; ! /* ! * Check overlap with text. (ts and nb now ! * in 64-byte clicks) ! */ ! if (nb < ts) { ! error = EFAULT; ! break; ! } ! /* ! * Check that transfer is either entirely in the ! * data or in the stack: that is, either ! * the end is in the data or the start is in the stack ! * (remember wraparound was already checked). ! */ ! if (((((int)iov->iov_base + iov->iov_len) >> 6) & 01777) >= ! ts + u.u_dsize && nb < 1024 - u.u_ssize) { ! error = EFAULT; ! break; ! } ! if (!allocbuf) { ! s = splbio(); ! while (bp->b_flags & B_BUSY) { ! bp->b_flags |= B_WANTED; ! sleep((caddr_t)bp, PRIBIO+1); ! } ! splx(s); ! } bp->b_error = 0; ! while (iov->iov_len) { ! bp->b_flags = B_BUSY|B_PHYS|B_INVAL|rw; ! bp->b_dev = dev; ! nb = ((int)iov->iov_base >> 6) & 01777; ! ts = (u.u_sep ? UDSA : UISA)[nb >> 7] + (nb & 0177); ! bp->b_un.b_addr = (caddr_t)((ts << 6) + ((int)iov->iov_base & 077)); ! bp->b_xmem = (ts >> 10) & 077; ! bp->b_blkno = uio->uio_offset >> PGSHIFT; ! bp->b_bcount = iov->iov_len; ! c = bp->b_bcount; ! (*strat)(bp); ! s = splbio(); ! while ((bp->b_flags & B_DONE) == 0) ! sleep((caddr_t)bp, PRIBIO); ! if (bp->b_flags & B_WANTED) /* rare */ ! wakeup((caddr_t)bp); ! splx(s); ! c -= bp->b_resid; ! iov->iov_base += c; ! iov->iov_len -= c; ! uio->uio_resid -= c; ! uio->uio_offset += c; ! /* temp kludge for tape drives */ ! if (bp->b_resid || (bp->b_flags & B_ERROR)) ! break; ! } ! bp->b_flags &= ~(B_BUSY|B_WANTED); ! error = geterror(bp); /* temp kludge for tape drives */ ! if (bp->b_resid || error) break; } ! if (allocbuf) brelse(bp); u.u_procp->p_flag &= ~SLOCK; return(error); } *** /usr/src/sys/sys/kern_exec.c.old Sat Apr 7 20:07:25 1990 --- /usr/src/sys/sys/kern_exec.c Thu Jun 6 19:59:43 1991 *************** *** 181,187 **** uap = (struct execa *)u.u_ap; bno = malloc(swapmap, ctod((int)btoc(NCARGS + MAXBSIZE))); if (bno == 0) { ! swkill(u.u_procp, "exec: no swap space"); goto bad; } /* --- 181,187 ---- uap = (struct execa *)u.u_ap; bno = malloc(swapmap, ctod((int)btoc(NCARGS + MAXBSIZE))); if (bno == 0) { ! swkill(u.u_procp, "exec"); goto bad; } /* *** /usr/src/sys/sys/vm_text.c.old Sat Apr 7 20:00:00 1990 --- /usr/src/sys/sys/vm_text.c Thu Jun 6 20:01:19 1991 *************** *** 202,208 **** else xp->x_size = ts; if ((xp->x_daddr = malloc(swapmap, (size_t)ctod(xp->x_size))) == NULL) { ! swkill(u.u_procp, "xalloc: no swap space"); return; } xp->x_count = 1; --- 202,208 ---- else xp->x_size = ts; if ((xp->x_daddr = malloc(swapmap, (size_t)ctod(xp->x_size))) == NULL) { ! swkill(u.u_procp, "xalloc"); return; } xp->x_count = 1; *** /usr/src/sys/pdp/machdep.c.old Thu Apr 5 16:15:25 1990 --- /usr/src/sys/pdp/machdep.c Thu Jun 6 20:04:53 1991 *************** *** 3,9 **** * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. * ! * @(#)machdep.c 1.1 (2.10BSD Berkeley) 12/1/86 */ #include "param.h" --- 3,9 ---- * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. * ! * @(#)machdep.c 2.0 (2.11BSD) 6/6/91 */ #include "param.h" *************** *** 144,162 **** regs[R0] = scp->sc_r0; regs[R7] = scp->sc_pc; regs[RPS] = scp->sc_ps; - } - - physstrat(bp, strat, prio) - register struct buf *bp; - int (*strat)(), prio; - { - register int s; - - (*strat)(bp); - s = splbio(); - while ((bp->b_flags & B_DONE) == 0) - sleep((caddr_t)bp, prio); - splx(s); } #ifdef UNIBUS_MAP --- 144,149 ----