Are any of these client-side performance upgrades as well as bug fixes? On Wed, 12 Dec 2001, Matthew Dillon wrote:
> Ok, here is the latest patch for -stable. Note that Kirk comitted a > slightly modified version of the softupdates fix to -current already > (the VOP_FSYNC stuff), which I will be MFCing in 3 days. > > This still doesn't fix all the problems the nfstest program that Jordan > posted finds, but it sure runs a hellofalot longer now before reporting > an error. 10,000+ tests now before failing (NFSv2 and NFSv3). > > Bugs fixed: > > * Possible SMP database corruption due to vm_pager_unmap_page() > not clearing the TLB for the other cpu's. > > * When flusing a dirty buffer due to B_CACHE getting cleared, > we were accidently setting B_CACHE again (that is, bwrite() sets > B_CACHE), when we really want it to stay clear after the write > is complete. This resulted in a corrupt buffer. > > * We have to call vtruncbuf() when ftruncate()ing to remove > any buffer cache buffers. This is still tentitive, I may > be able to remove it due to the second bug fix. > > * vnode_pager_setsize() race against nfs_vinvalbuf()... we have > to set n_size before calling nfs_vinvalbuf or the NFS code > may recursively vnode_pager_setsize() to the original value > before the truncate. This is what was causing the user mmap > bus faults in the nfs tester program. > > * Fix to softupdates (old version) > > There are some general comments in there too. After I do more tests > and cleanups (maybe remove the vtruncbuf()) I will port it all to > -current, test, and commit. So far the stuff is simple enough that > a 3-day MFC will probably suffice. > > All I can say is... holy shit! > > -Matt > > > Index: kern/vfs_bio.c > =================================================================== > RCS file: /home/ncvs/src/sys/kern/vfs_bio.c,v > retrieving revision 1.242.2.13 > diff -u -r1.242.2.13 vfs_bio.c > --- kern/vfs_bio.c 2001/11/18 07:10:59 1.242.2.13 > +++ kern/vfs_bio.c 2001/12/13 05:52:55 > @@ -2189,9 +2189,22 @@ > * to softupdates re-dirtying the buffer. In the latter > * case, B_CACHE is set after the first write completes, > * preventing further loops. > + * > + * NOTE! b*write() sets B_CACHE. If we cleared B_CACHE > + * above while extending the buffer, we cannot allow the > + * buffer to remain with B_CACHE set after the write > + * completes or it will represent a corrupt state. To > + * deal with this we set B_NOCACHE to scrap the buffer > + * after the write. > + * > + * We might be able to do something fancy, like setting > + * B_CACHE in bwrite() except if B_DELWRI is already set, > + * so the below call doesn't set B_CACHE, but that gets real > + * confusing. This is much easier. > */ > > if ((bp->b_flags & (B_CACHE|B_DELWRI)) == B_DELWRI) { > + bp->b_flags |= B_NOCACHE; > VOP_BWRITE(bp->b_vp, bp); > goto loop; > } > Index: nfs/nfs_bio.c > =================================================================== > RCS file: /home/ncvs/src/sys/nfs/Attic/nfs_bio.c,v > retrieving revision 1.83.2.1 > diff -u -r1.83.2.1 nfs_bio.c > --- nfs/nfs_bio.c 2001/11/18 07:10:59 1.83.2.1 > +++ nfs/nfs_bio.c 2001/12/13 05:52:10 > @@ -193,8 +193,14 @@ > vm_page_set_validclean(m, 0, size - toff); > /* handled by vm_fault now */ > /* vm_page_zero_invalid(m, TRUE); */ > + } else { > + /* > + * Read operation was short. If no error occured > + * we may have hit a zero-fill section. We simply > + * leave valid set to 0. > + */ > + ; > } > - > if (i != ap->a_reqpage) { > /* > * Whether or not to leave the page activated is up in > @@ -896,14 +902,12 @@ > else > bcount = np->n_size - (off_t)lbn * biosize; > } > - > - bp = nfs_getcacheblk(vp, lbn, bcount, p); > - > if (uio->uio_offset + n > np->n_size) { > np->n_size = uio->uio_offset + n; > np->n_flag |= NMODIFIED; > vnode_pager_setsize(vp, np->n_size); > } > + bp = nfs_getcacheblk(vp, lbn, bcount, p); > } > > if (!bp) { > @@ -1409,11 +1413,13 @@ > io.iov_len = uiop->uio_resid = bp->b_bcount; > io.iov_base = bp->b_data; > uiop->uio_rw = UIO_READ; > + > switch (vp->v_type) { > case VREG: > uiop->uio_offset = ((off_t)bp->b_blkno) * DEV_BSIZE; > nfsstats.read_bios++; > error = nfs_readrpc(vp, uiop, cr); > + > if (!error) { > if (uiop->uio_resid) { > /* > @@ -1425,7 +1431,7 @@ > * writes, but that is not possible any longer. > */ > int nread = bp->b_bcount - uiop->uio_resid; > - int left = bp->b_bcount - nread; > + int left = uiop->uio_resid; > > if (left > 0) > bzero((char *)bp->b_data + nread, left); > Index: nfs/nfs_vnops.c > =================================================================== > RCS file: /home/ncvs/src/sys/nfs/Attic/nfs_vnops.c,v > retrieving revision 1.150.2.4 > diff -u -r1.150.2.4 nfs_vnops.c > --- nfs/nfs_vnops.c 2001/08/05 00:23:58 1.150.2.4 > +++ nfs/nfs_vnops.c 2001/12/13 04:23:51 > @@ -710,7 +710,22 @@ > */ > if (vp->v_mount->mnt_flag & MNT_RDONLY) > return (EROFS); > - vnode_pager_setsize(vp, vap->va_size); > + > + /* > + * We run vnode_pager_setsize() early (why?), > + * we must set np->n_size now to avoid vinvalbuf > + * V_SAVE races that might setsize a lower > + * value. > + */ > + tsize = np->n_size; > + np->n_size = vap->va_size; > +#if 1 > + if (np->n_size < tsize) > + error = vtruncbuf(vp, ap->a_cred, ap->a_p, vap->va_size, >vp->v_mount->mnt_stat.f_iosize); > + else > +#endif > + vnode_pager_setsize(vp, vap->va_size); > + > if (np->n_flag & NMODIFIED) { > if (vap->va_size == 0) > error = nfs_vinvalbuf(vp, 0, > @@ -719,12 +734,12 @@ > error = nfs_vinvalbuf(vp, V_SAVE, > ap->a_cred, ap->a_p, 1); > if (error) { > + np->n_size = tsize; > vnode_pager_setsize(vp, np->n_size); > return (error); > } > } > - tsize = np->n_size; > - np->n_size = np->n_vattr.va_size = vap->va_size; > + np->n_vattr.va_size = vap->va_size; > }; > } else if ((vap->va_mtime.tv_sec != VNOVAL || > vap->va_atime.tv_sec != VNOVAL) && (np->n_flag & NMODIFIED) && > @@ -1119,10 +1134,12 @@ > m_freem(mrep); > tsiz -= retlen; > if (v3) { > - if (eof || retlen == 0) > + if (eof || retlen == 0) { > tsiz = 0; > - } else if (retlen < len) > + } > + } else if (retlen < len) { > tsiz = 0; > + } > } > nfsmout: > return (error); > Index: ufs/ffs/ffs_inode.c > =================================================================== > RCS file: /home/ncvs/src/sys/ufs/ffs/ffs_inode.c,v > retrieving revision 1.56.2.3 > diff -u -r1.56.2.3 ffs_inode.c > --- ufs/ffs/ffs_inode.c 2001/11/20 20:27:27 1.56.2.3 > +++ ufs/ffs/ffs_inode.c 2001/12/12 23:43:36 > @@ -244,6 +244,10 @@ > if (error) { > return (error); > } > + if (length > 0 && DOINGSOFTDEP(ovp)) { > + if ((error = VOP_FSYNC(ovp, cred, MNT_WAIT, p)) != 0) > + return (error); > + } > oip->i_size = length; > size = blksize(fs, oip, lbn); > if (ovp->v_type != VDIR) > @@ -359,6 +363,10 @@ > if (newspace == 0) > panic("ffs_truncate: newspace"); > if (oldspace - newspace > 0) { > + /* > + * XXX Softupdates, adjust queued directblock > + * in place rather then the second FSYNC above? > + */ > /* > * Block number of space to be free'd is > * the old block # plus the number of frags > Index: vm/vnode_pager.c > =================================================================== > RCS file: /home/ncvs/src/sys/vm/vnode_pager.c,v > retrieving revision 1.116.2.5 > diff -u -r1.116.2.5 vnode_pager.c > --- vm/vnode_pager.c 2001/11/09 03:21:22 1.116.2.5 > +++ vm/vnode_pager.c 2001/12/13 02:49:39 > @@ -310,6 +310,20 @@ > vm_pager_unmap_page(kva); > > /* > + * XXX work around SMP data integrity race > + * by unmapping the page from user processes. > + * The garbage we just cleared may be mapped > + * to a user process running on another cpu > + * and this code is not running through normal > + * I/O channels which handle SMP issues for > + * us, so unmap page to synchronize all cpus. > + * > + * XXX should vm_pager_unmap_page() have > + * dealt with this? > + */ > + vm_page_protect(m, VM_PROT_NONE); > + > + /* > * Clear out partial-page dirty bits. This > * has the side effect of setting the valid > * bits, but that is ok. There are a bunch > > To Unsubscribe: send mail to [EMAIL PROTECTED] > with "unsubscribe freebsd-hackers" in the body of the message > --- Geoff Mohler To Unsubscribe: send mail to [EMAIL PROTECTED] with "unsubscribe freebsd-hackers" in the body of the message