diff options
author | dillon <dillon@FreeBSD.org> | 1999-01-21 08:29:12 +0000 |
---|---|---|
committer | dillon <dillon@FreeBSD.org> | 1999-01-21 08:29:12 +0000 |
commit | df24433bbe29112b4b9c9f38e80ba6cfb6988cb0 (patch) | |
tree | b0a91cf38166034e837b98d5edacd8177a14aba6 /sys/ufs | |
parent | bae5debf723220e076d6a9696e417805639cdc3a (diff) | |
download | FreeBSD-src-df24433bbe29112b4b9c9f38e80ba6cfb6988cb0.zip FreeBSD-src-df24433bbe29112b4b9c9f38e80ba6cfb6988cb0.tar.gz |
This is a rather large commit that encompasses the new swapper,
changes to the VM system to support the new swapper, VM bug
fixes, several VM optimizations, and some additional revamping of the
VM code. The specific bug fixes will be documented with additional
forced commits. This commit is somewhat rough in regards to code
cleanup issues.
Reviewed by: "John S. Dyson" <root@dyson.iquest.net>, "David Greenman" <dg@root.com>
Diffstat (limited to 'sys/ufs')
-rw-r--r-- | sys/ufs/mfs/mfs_extern.h | 5 | ||||
-rw-r--r-- | sys/ufs/mfs/mfs_vfsops.c | 22 | ||||
-rw-r--r-- | sys/ufs/mfs/mfs_vnops.c | 120 | ||||
-rw-r--r-- | sys/ufs/ufs/ufs_readwrite.c | 12 | ||||
-rw-r--r-- | sys/ufs/ufs/ufs_vnops.c | 5 |
5 files changed, 141 insertions, 23 deletions
diff --git a/sys/ufs/mfs/mfs_extern.h b/sys/ufs/mfs/mfs_extern.h index ca19cc4..ae5b7af 100644 --- a/sys/ufs/mfs/mfs_extern.h +++ b/sys/ufs/mfs/mfs_extern.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)mfs_extern.h 8.4 (Berkeley) 3/30/95 - * $Id: mfs_extern.h,v 1.10 1997/10/16 10:50:00 phk Exp $ + * $Id: mfs_extern.h,v 1.11 1998/02/03 21:52:02 bde Exp $ */ #ifndef _UFS_MFS_MFS_EXTERN_H_ @@ -41,8 +41,9 @@ struct buf; struct mount; struct proc; struct vnode; +struct mfsnode; -void mfs_doio __P((struct buf *bp, caddr_t base)); +void mfs_doio __P((struct buf *bp, struct mfsnode *mfsnode)); int mfs_mountfs __P((struct vnode *, struct mount *, struct proc *)); int mfs_mountroot __P((void)); diff --git a/sys/ufs/mfs/mfs_vfsops.c b/sys/ufs/mfs/mfs_vfsops.c index 1ea0804..73ab75a 100644 --- a/sys/ufs/mfs/mfs_vfsops.c +++ b/sys/ufs/mfs/mfs_vfsops.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)mfs_vfsops.c 8.11 (Berkeley) 6/19/95 - * $Id: mfs_vfsops.c,v 1.52 1998/12/07 21:58:49 archie Exp $ + * $Id: mfs_vfsops.c,v 1.53 1999/01/01 04:14:11 dillon Exp $ */ @@ -64,8 +64,10 @@ MALLOC_DEFINE(M_MFSNODE, "MFS node", "MFS vnode private part"); u_char * mfs_getimage __P((void)); +#ifdef MFS_ROOT static caddr_t mfs_rootbase; /* address of mini-root in kernel virtual memory */ static u_long mfs_rootsize; /* size of mini-root in bytes */ +#endif static int mfs_minor; /* used for building internal dev_t */ @@ -178,7 +180,9 @@ mfs_mount(mp, path, data, ndp, p) struct mfs_args args; struct ufsmount *ump; struct fs *fs; +#ifdef MFS_ROOT u_char *base; +#endif struct mfsnode *mfsp; u_int size; int flags, err; @@ -344,7 +348,9 @@ mfs_mount(mp, path, data, ndp, p) goto error_2; } +#ifdef MFS_ROOT dostatfs: +#endif /* * Initialize FS stat information in mount struct; uses both * mp->mnt_stat.f_mntonname and mp->mnt_stat.f_mntfromname @@ -387,11 +393,8 @@ mfs_start(mp, flags, p) register struct vnode *vp = VFSTOUFS(mp)->um_devvp; register struct mfsnode *mfsp = VTOMFS(vp); register struct buf *bp; - register caddr_t base; register int gotsig = 0; - base = mfsp->mfs_baseoff; - /* * Must set P_SYSTEM to prevent system from trying to kill * this process. What happens is that the process is unkillable, @@ -402,11 +405,20 @@ mfs_start(mp, flags, p) curproc->p_flag |= P_SYSTEM; while (mfsp->mfs_active) { + int s; + + s = splbio(); + while (bp = bufq_first(&mfsp->buf_queue)) { bufq_remove(&mfsp->buf_queue, bp); - mfs_doio(bp, base); + splx(s); + mfs_doio(bp, mfsp); wakeup((caddr_t)bp); + s = splbio(); } + + splx(s); + /* * If a non-ignored signal is received, try to unmount. * If that fails, clear the signal (it has been "processed"), diff --git a/sys/ufs/mfs/mfs_vnops.c b/sys/ufs/mfs/mfs_vnops.c index 88cfec6..083843c 100644 --- a/sys/ufs/mfs/mfs_vnops.c +++ b/sys/ufs/mfs/mfs_vnops.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)mfs_vnops.c 8.11 (Berkeley) 5/22/95 - * $Id: mfs_vnops.c,v 1.37 1998/07/11 07:46:05 bde Exp $ + * $Id: mfs_vnops.c,v 1.38 1998/09/07 06:52:01 phk Exp $ */ #include <sys/param.h> @@ -41,6 +41,8 @@ #include <sys/buf.h> #include <sys/vnode.h> #include <sys/malloc.h> +#include <sys/sysproto.h> +#include <sys/mman.h> #include <miscfs/specfs/specdev.h> @@ -51,6 +53,7 @@ static int mfs_badop __P((struct vop_generic_args *)); static int mfs_bmap __P((struct vop_bmap_args *)); static int mfs_close __P((struct vop_close_args *)); static int mfs_fsync __P((struct vop_fsync_args *)); +static int mfs_freeblks __P((struct vop_freeblks_args *)); static int mfs_inactive __P((struct vop_inactive_args *)); /* XXX */ static int mfs_open __P((struct vop_open_args *)); static int mfs_reclaim __P((struct vop_reclaim_args *)); /* XXX */ @@ -66,7 +69,7 @@ static struct vnodeopv_entry_desc mfs_vnodeop_entries[] = { { &vop_bmap_desc, (vop_t *) mfs_bmap }, { &vop_bwrite_desc, (vop_t *) vop_defaultop }, { &vop_close_desc, (vop_t *) mfs_close }, - { &vop_freeblks_desc, (vop_t *) vop_defaultop }, + { &vop_freeblks_desc, (vop_t *) mfs_freeblks }, { &vop_fsync_desc, (vop_t *) mfs_fsync }, { &vop_getpages_desc, (vop_t *) mfs_getpages }, { &vop_inactive_desc, (vop_t *) mfs_inactive }, @@ -119,6 +122,38 @@ mfs_fsync(ap) } /* + * mfs_freeblks() - hook to allow us to free physical memory. + * + * We implement the B_FREEBUF strategy. We can't just madvise() + * here because we have to do it in the correct order vs other bio + * requests, so we queue it. + */ + +static int +mfs_freeblks(ap) + struct vop_freeblks_args /* { + struct vnode *a_vp; + daddr_t a_addr; + daddr_t a_length; + } */ *ap; +{ + struct buf *bp; + struct vnode *vp; + + if (!vfinddev(ap->a_vp->v_rdev, VBLK, &vp) || vp->v_usecount == 0) + panic("mfs_strategy: bad dev"); + + bp = geteblk(ap->a_length); + bp->b_flags |= B_FREEBUF | B_BUSY; + bp->b_dev = ap->a_vp->v_rdev; + bp->b_blkno = ap->a_addr; + bp->b_offset = dbtob(ap->a_addr); + bp->b_bcount = ap->a_length; + VOP_STRATEGY(vp, bp); + return(0); +} + +/* * Pass I/O requests to the memory filesystem process. */ static int @@ -132,26 +167,50 @@ mfs_strategy(ap) register struct mfsnode *mfsp; struct vnode *vp; struct proc *p = curproc; /* XXX */ + int s; if (!vfinddev(bp->b_dev, VBLK, &vp) || vp->v_usecount == 0) panic("mfs_strategy: bad dev"); mfsp = VTOMFS(vp); - /* check for mini-root access */ + + /* + * splbio required for queueing/dequeueing, in case of forwarded + * BPs from bio interrupts (??). It may not be necessary. + */ + + s = splbio(); + if (mfsp->mfs_pid == 0) { + /* + * mini-root. Note: B_FREEBUF not supported at the moment, + * I'm not sure what kind of dataspace b_data is in. + */ caddr_t base; base = mfsp->mfs_baseoff + (bp->b_blkno << DEV_BSHIFT); + if (bp->b_flags & B_FREEBUF) + ; if (bp->b_flags & B_READ) bcopy(base, bp->b_data, bp->b_bcount); else bcopy(bp->b_data, base, bp->b_bcount); biodone(bp); } else if (mfsp->mfs_pid == p->p_pid) { - mfs_doio(bp, mfsp->mfs_baseoff); + /* + * VOP to self + */ + splx(s); + mfs_doio(bp, mfsp); + s = splbio(); } else { + /* + * VOP from some other process, queue to MFS process and + * wake it up. + */ bufq_insert_tail(&mfsp->buf_queue, bp); wakeup((caddr_t)vp); } + splx(s); return (0); } @@ -159,18 +218,59 @@ mfs_strategy(ap) * Memory file system I/O. * * Trivial on the HP since buffer has already been mapping into KVA space. + * + * Read and Write are handled with a simple copyin and copyout. + * + * We also partially support VOP_FREEBLKS() via B_FREEBUF. We can't implement + * completely -- for example, on fragments or inode metadata, but we can + * implement it for page-aligned requests. */ void -mfs_doio(bp, base) +mfs_doio(bp, mfsp) register struct buf *bp; - caddr_t base; + struct mfsnode *mfsp; { + caddr_t base = mfsp->mfs_baseoff + (bp->b_blkno << DEV_BSHIFT); + + if (bp->b_flags & B_FREEBUF) { + /* + * Implement B_FREEBUF, which allows the filesystem to tell + * a block device when blocks are no longer needed (like when + * a file is deleted). We use the hook to MADV_FREE the VM. + * This makes an MFS filesystem work as well or better then + * a sun-style swap-mounted filesystem. + */ + int bytes = bp->b_bcount; + + if ((vm_offset_t)base & PAGE_MASK) { + int n = PAGE_SIZE - ((vm_offset_t)base & PAGE_MASK); + bytes -= n; + base += n; + } + if (bytes > 0) { + struct madvise_args uap; - base += (bp->b_blkno << DEV_BSHIFT); - if (bp->b_flags & B_READ) + bytes &= ~PAGE_MASK; + if (bytes != 0) { + bzero(&uap, sizeof(uap)); + uap.addr = base; + uap.len = bytes; + uap.behav = MADV_FREE; + madvise(curproc, &uap); + } + } + bp->b_error = 0; + } else if (bp->b_flags & B_READ) { + /* + * Read data from our 'memory' disk + */ bp->b_error = copyin(base, bp->b_data, bp->b_bcount); - else + } else { + /* + * Write data to our 'memory' disk + */ bp->b_error = copyout(bp->b_data, base, bp->b_bcount); + } if (bp->b_error) bp->b_flags |= B_ERROR; biodone(bp); @@ -222,7 +322,7 @@ mfs_close(ap) */ while (bp = bufq_first(&mfsp->buf_queue)) { bufq_remove(&mfsp->buf_queue, bp); - mfs_doio(bp, mfsp->mfs_baseoff); + mfs_doio(bp, mfsp); wakeup((caddr_t)bp); } /* diff --git a/sys/ufs/ufs/ufs_readwrite.c b/sys/ufs/ufs/ufs_readwrite.c index 026d3486..fd3555a 100644 --- a/sys/ufs/ufs/ufs_readwrite.c +++ b/sys/ufs/ufs/ufs_readwrite.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)ufs_readwrite.c 8.11 (Berkeley) 5/8/95 - * $Id: ufs_readwrite.c,v 1.54 1998/12/15 03:29:52 julian Exp $ + * $Id: ufs_readwrite.c,v 1.55 1999/01/07 16:14:19 bde Exp $ */ #define BLKSIZE(a, b, c) blksize(a, b, c) @@ -392,7 +392,10 @@ WRITE(ap) panic("%s: nonsync dir write", WRITE_S); break; default: - panic("%s: type", WRITE_S); + panic("%s: type %p %d (%d,%d)", WRITE_S, vp, (int)vp->v_type, + (int)uio->uio_offset, + (int)uio->uio_resid + ); } fs = ip->I_FS; @@ -598,9 +601,8 @@ ffs_getpages(ap) vm_page_busy(m); vm_page_free(m); } else if (m == mreq) { - while (m->flags & PG_BUSY) { - vm_page_sleep(m, "ffspwt", NULL); - } + while (vm_page_sleep_busy(m, FALSE, "ffspwt")) + ; vm_page_busy(m); vp->v_lastr = m->pindex + 1; } else { diff --git a/sys/ufs/ufs/ufs_vnops.c b/sys/ufs/ufs/ufs_vnops.c index 1010085..49e1a29 100644 --- a/sys/ufs/ufs/ufs_vnops.c +++ b/sys/ufs/ufs/ufs_vnops.c @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * @(#)ufs_vnops.c 8.27 (Berkeley) 5/27/95 - * $Id: ufs_vnops.c,v 1.103 1998/12/24 09:45:10 bde Exp $ + * $Id: ufs_vnops.c,v 1.104 1999/01/07 16:14:19 bde Exp $ */ #include "opt_quota.h" @@ -1731,6 +1731,9 @@ ufs_abortop(ap) /* * Calculate the logical to physical mapping if not done already, * then call the device strategy routine. + * + * In order to be able to swap to a file, the VOP_BMAP operation may not + * deadlock on memory. See ufs_bmap() for details. */ int ufs_strategy(ap) |