summaryrefslogtreecommitdiffstats
path: root/sys/kern
diff options
context:
space:
mode:
authordyson <dyson@FreeBSD.org>1998-01-22 17:30:44 +0000
committerdyson <dyson@FreeBSD.org>1998-01-22 17:30:44 +0000
commit197bd655c435302ddb4156bc654705dfef1d9143 (patch)
treea91dcc7eb7507f4d0088eb5e1b2e6872c51fd3ea /sys/kern
parentf95fe9806cd36e8b1fa77d590b5d1c2d48482618 (diff)
downloadFreeBSD-src-197bd655c435302ddb4156bc654705dfef1d9143.zip
FreeBSD-src-197bd655c435302ddb4156bc654705dfef1d9143.tar.gz
VM level code cleanups.
1) Start using TSM. Struct procs continue to point to upages structure, after being freed. Struct vmspace continues to point to pte object and kva space for kstack. u_map is now superfluous. 2) vm_map's don't need to be reference counted. They always exist either in the kernel or in a vmspace. The vmspaces are managed by reference counts. 3) Remove the "wired" vm_map nonsense. 4) No need to keep a cache of kernel stack kva's. 5) Get rid of strange looking ++var, and change to var++. 6) Change more data structures to use our "zone" allocator. Added struct proc, struct vmspace and struct vnode. This saves a significant amount of kva space and physical memory. Additionally, this enables TSM for the zone managed memory. 7) Keep ioopt disabled for now. 8) Remove the now bogus "single use" map concept. 9) Use generation counts or id's for data structures residing in TSM, where it allows us to avoid unneeded restart overhead during traversals, where blocking might occur. 10) Account better for memory deficits, so the pageout daemon will be able to make enough memory available (experimental.) 11) Fix some vnode locking problems. (From Tor, I think.) 12) Add a check in ufs_lookup, to avoid lots of unneeded calls to bcmp. (experimental.) 13) Significantly shrink, cleanup, and make slightly faster the vm_fault.c code. Use generation counts, get rid of unneded collpase operations, and clean up the cluster code. 14) Make vm_zone more suitable for TSM. This commit is partially as a result of discussions and contributions from other people, including DG, Tor Egge, PHK, and probably others that I have forgotten to attribute (so let me know, if I forgot.) This is not the infamous, final cleanup of the vnode stuff, but a necessary step. Vnode mgmt should be correct, but things might still change, and there is still some missing stuff (like ioopt, and physical backing of non-merged cache files, debugging of layering concepts.)
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/init_main.c4
-rw-r--r--sys/kern/kern_exit.c5
-rw-r--r--sys/kern/kern_fork.c5
-rw-r--r--sys/kern/kern_malloc.c5
-rw-r--r--sys/kern/kern_proc.c5
-rw-r--r--sys/kern/kern_subr.c7
-rw-r--r--sys/kern/sys_process.c10
-rw-r--r--sys/kern/vfs_bio.c27
-rw-r--r--sys/kern/vfs_export.c10
-rw-r--r--sys/kern/vfs_subr.c10
10 files changed, 58 insertions, 30 deletions
diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c
index 620e1b9..03f707c 100644
--- a/sys/kern/init_main.c
+++ b/sys/kern/init_main.c
@@ -39,7 +39,7 @@
* SUCH DAMAGE.
*
* @(#)init_main.c 8.9 (Berkeley) 1/21/94
- * $Id: init_main.c,v 1.78 1997/12/12 04:00:57 dyson Exp $
+ * $Id: init_main.c,v 1.79 1997/12/14 02:10:12 dyson Exp $
*/
#include "opt_devfs.h"
@@ -403,7 +403,7 @@ proc0_init(dummy)
vmspace0.vm_refcnt = 1;
pmap_pinit0(&vmspace0.vm_pmap);
vm_map_init(&vmspace0.vm_map, round_page(VM_MIN_ADDRESS),
- trunc_page(VM_MAXUSER_ADDRESS), TRUE);
+ trunc_page(VM_MAXUSER_ADDRESS));
vmspace0.vm_map.pmap = &vmspace0.vm_pmap;
p->p_addr = proc0paddr; /* XXX */
diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c
index 9052225..48e9abc 100644
--- a/sys/kern/kern_exit.c
+++ b/sys/kern/kern_exit.c
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)kern_exit.c 8.7 (Berkeley) 2/12/94
- * $Id: kern_exit.c,v 1.63 1997/12/08 01:06:36 sef Exp $
+ * $Id: kern_exit.c,v 1.64 1997/12/16 17:40:14 eivind Exp $
*/
#include "opt_compat.h"
@@ -71,6 +71,7 @@
#include <sys/lock.h>
#include <vm/pmap.h>
#include <vm/vm_map.h>
+#include <vm/vm_zone.h>
static MALLOC_DEFINE(M_ZOMBIE, "zombie", "zombie proc status");
@@ -492,7 +493,7 @@ loop:
* release while still running in process context.
*/
cpu_wait(p);
- FREE(p, M_PROC);
+ zfree(proc_zone, p);
nprocs--;
return (0);
}
diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c
index df7b863..26cbe47 100644
--- a/sys/kern/kern_fork.c
+++ b/sys/kern/kern_fork.c
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)kern_fork.c 8.6 (Berkeley) 4/8/94
- * $Id: kern_fork.c,v 1.49 1997/11/20 16:36:17 bde Exp $
+ * $Id: kern_fork.c,v 1.50 1997/12/12 04:00:58 dyson Exp $
*/
#include "opt_ktrace.h"
@@ -60,6 +60,7 @@
#include <vm/pmap.h>
#include <vm/vm_map.h>
#include <vm/vm_extern.h>
+#include <vm/vm_zone.h>
#ifdef SMP
static int fast_vfork = 0; /* Doesn't work on SMP yet. */
@@ -226,7 +227,7 @@ fork1(p1, flags)
}
/* Allocate new proc. */
- MALLOC(newproc, struct proc *, sizeof(struct proc), M_PROC, M_WAITOK);
+ newproc = zalloc(proc_zone);
/*
* Setup linkage for kernel based threading
diff --git a/sys/kern/kern_malloc.c b/sys/kern/kern_malloc.c
index d32a756..02be8ce 100644
--- a/sys/kern/kern_malloc.c
+++ b/sys/kern/kern_malloc.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)kern_malloc.c 8.3 (Berkeley) 1/4/94
- * $Id: kern_malloc.c,v 1.37 1997/10/28 19:00:53 phk Exp $
+ * $Id: kern_malloc.c,v 1.38 1997/12/05 05:36:36 dyson Exp $
*/
#include <sys/param.h>
@@ -387,8 +387,7 @@ kmeminit(dummy)
kmemusage = (struct kmemusage *) kmem_alloc(kernel_map,
(vm_size_t)(npg * sizeof(struct kmemusage)));
kmem_map = kmem_suballoc(kernel_map, (vm_offset_t *)&kmembase,
- (vm_offset_t *)&kmemlimit, (vm_size_t)(npg * PAGE_SIZE),
- FALSE);
+ (vm_offset_t *)&kmemlimit, (vm_size_t)(npg * PAGE_SIZE));
kmem_map->system_map = 1;
for (indx = 0; indx < MINBUCKET + 16; indx++) {
if (1 << indx >= PAGE_SIZE)
diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c
index 35e3046..460e9fb 100644
--- a/sys/kern/kern_proc.c
+++ b/sys/kern/kern_proc.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)kern_proc.c 8.7 (Berkeley) 2/14/95
- * $Id: kern_proc.c,v 1.29 1997/10/11 18:31:23 phk Exp $
+ * $Id: kern_proc.c,v 1.30 1997/10/12 20:23:52 phk Exp $
*/
#include <sys/param.h>
@@ -47,6 +47,7 @@
#include <vm/pmap.h>
#include <vm/vm_map.h>
#include <sys/user.h>
+#include <vm/vm_zone.h>
static MALLOC_DEFINE(M_PGRP, "pgrp", "process group header");
MALLOC_DEFINE(M_SESSION, "session", "session header");
@@ -82,6 +83,7 @@ struct pgrphashhead *pgrphashtbl;
u_long pgrphash;
struct proclist allproc;
struct proclist zombproc;
+vm_zone_t proc_zone;
/*
* Initialize global process hashing structures.
@@ -95,6 +97,7 @@ procinit()
pidhashtbl = hashinit(maxproc / 4, M_PROC, &pidhash);
pgrphashtbl = hashinit(maxproc / 4, M_PROC, &pgrphash);
uihashtbl = hashinit(maxproc / 16, M_PROC, &uihash);
+ proc_zone = zinit("PROC", sizeof (struct proc), 0, 0, 5);
}
/*
diff --git a/sys/kern/kern_subr.c b/sys/kern/kern_subr.c
index 169711d..de1bf7d 100644
--- a/sys/kern/kern_subr.c
+++ b/sys/kern/kern_subr.c
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)kern_subr.c 8.3 (Berkeley) 1/21/94
- * $Id: kern_subr.c,v 1.14 1997/12/19 09:03:23 dyson Exp $
+ * $Id: kern_subr.c,v 1.15 1998/01/06 05:15:41 dyson Exp $
*/
#include <sys/param.h>
@@ -44,6 +44,7 @@
#include <sys/proc.h>
#include <sys/malloc.h>
#include <sys/lock.h>
+#include <sys/vnode.h>
#include <vm/vm.h>
#include <vm/vm_prot.h>
@@ -141,7 +142,7 @@ uiomoveco(cp, n, uio, obj)
case UIO_USERSPACE:
case UIO_USERISPACE:
if (uio->uio_rw == UIO_READ) {
- if (((cnt & PAGE_MASK) == 0) &&
+ if (vfs_ioopt && ((cnt & PAGE_MASK) == 0) &&
((((int) iov->iov_base) & PAGE_MASK) == 0) &&
((uio->uio_offset & PAGE_MASK) == 0) &&
((((int) cp) & PAGE_MASK) == 0)) {
@@ -190,6 +191,8 @@ uioread(n, uio, obj, nread)
int error;
*nread = 0;
+ if (vfs_ioopt > 1)
+ return 0;
error = 0;
while (n > 0 && uio->uio_resid) {
diff --git a/sys/kern/sys_process.c b/sys/kern/sys_process.c
index c289115..ac779bc 100644
--- a/sys/kern/sys_process.c
+++ b/sys/kern/sys_process.c
@@ -28,7 +28,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: sys_process.c,v 1.32 1997/11/12 12:28:12 tegge Exp $
+ * $Id: sys_process.c,v 1.33 1997/12/06 04:11:10 sef Exp $
*/
#include <sys/param.h>
@@ -62,7 +62,7 @@ pread (struct proc *procp, unsigned int addr, unsigned int *retval) {
vm_offset_t pageno; /* page number */
vm_map_entry_t out_entry;
vm_prot_t out_prot;
- boolean_t wired, single_use;
+ boolean_t wired;
vm_pindex_t pindex;
/* Map page into kernel space */
@@ -74,7 +74,7 @@ pread (struct proc *procp, unsigned int addr, unsigned int *retval) {
tmap = map;
rv = vm_map_lookup (&tmap, pageno, VM_PROT_READ, &out_entry,
- &object, &pindex, &out_prot, &wired, &single_use);
+ &object, &pindex, &out_prot, &wired);
if (rv != KERN_SUCCESS)
return EINVAL;
@@ -110,7 +110,7 @@ pwrite (struct proc *procp, unsigned int addr, unsigned int datum) {
vm_offset_t pageno; /* page number */
vm_map_entry_t out_entry;
vm_prot_t out_prot;
- boolean_t wired, single_use;
+ boolean_t wired;
vm_pindex_t pindex;
boolean_t fix_prot = 0;
@@ -148,7 +148,7 @@ pwrite (struct proc *procp, unsigned int addr, unsigned int datum) {
tmap = map;
rv = vm_map_lookup (&tmap, pageno, VM_PROT_WRITE, &out_entry,
- &object, &pindex, &out_prot, &wired, &single_use);
+ &object, &pindex, &out_prot, &wired);
if (rv != KERN_SUCCESS) {
return EINVAL;
}
diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c
index d00bffe..22acde6 100644
--- a/sys/kern/vfs_bio.c
+++ b/sys/kern/vfs_bio.c
@@ -11,7 +11,7 @@
* 2. Absolutely no warranty of function or purpose is made by the author
* John S. Dyson.
*
- * $Id: vfs_bio.c,v 1.142 1998/01/12 01:46:25 dyson Exp $
+ * $Id: vfs_bio.c,v 1.143 1998/01/17 09:16:26 dyson Exp $
*/
/*
@@ -177,6 +177,7 @@ bufinit()
bp->b_wcred = NOCRED;
bp->b_qindex = QUEUE_EMPTY;
bp->b_vnbufs.le_next = NOLIST;
+ bp->b_generation = 0;
TAILQ_INSERT_TAIL(&bufqueues[QUEUE_EMPTY], bp, b_freelist);
LIST_INSERT_HEAD(&invalhash, bp, b_hash);
}
@@ -654,6 +655,7 @@ brelse(struct buf * bp)
LIST_INSERT_HEAD(&invalhash, bp, b_hash);
bp->b_dev = NODEV;
kvafreespace += bp->b_kvasize;
+ bp->b_generation++;
/* buffers with junk contents */
} else if (bp->b_flags & (B_ERROR | B_INVAL | B_NOCACHE | B_RELBUF)) {
@@ -663,6 +665,7 @@ brelse(struct buf * bp)
LIST_REMOVE(bp, b_hash);
LIST_INSERT_HEAD(&invalhash, bp, b_hash);
bp->b_dev = NODEV;
+ bp->b_generation++;
/* buffers that are locked */
} else if (bp->b_flags & B_LOCKED) {
@@ -1083,6 +1086,7 @@ trytofreespace:
brelvp(bp);
fillbuf:
+ bp->b_generation++;
/* we are not free, nor do we contain interesting data */
if (bp->b_rcred != NOCRED) {
@@ -1348,6 +1352,7 @@ getblk(struct vnode * vp, daddr_t blkno, int size, int slpflag, int slptimeo)
int s;
struct bufhashhdr *bh;
int maxsize;
+ int generation;
if (vp->v_mount) {
maxsize = vp->v_mount->mnt_stat.f_iosize;
@@ -1370,18 +1375,23 @@ loop:
if (numfreebuffers < lofreebuffers) {
waitfreebuffers(slpflag, slptimeo);
}
-
+
if ((bp = gbincore(vp, blkno))) {
+loop1:
+ generation = bp->b_generation;
if (bp->b_flags & B_BUSY) {
bp->b_flags |= B_WANTED;
if (bp->b_usecount < BUF_MAXUSE)
++bp->b_usecount;
if (!tsleep(bp,
- (PRIBIO + 1) | slpflag, "getblk", slptimeo))
- goto loop;
-
- splx(s);
- return (struct buf *) NULL;
+ (PRIBIO + 1) | slpflag, "getblk", slptimeo)) {
+ if (bp->b_generation != generation)
+ goto loop;
+ goto loop1;
+ } else {
+ splx(s);
+ return (struct buf *) NULL;
+ }
}
bp->b_flags |= B_BUSY | B_CACHE;
bremfree(bp);
@@ -1394,6 +1404,7 @@ loop:
*/
if (bp->b_bcount != size) {
+ bp->b_generation++;
if ((bp->b_flags & B_VMIO) && (size <= bp->b_kvasize)) {
allocbuf(bp, size);
} else {
@@ -1683,6 +1694,7 @@ allocbuf(struct buf * bp, int size)
m = vm_page_alloc(obj, objoff, VM_ALLOC_NORMAL);
if (!m) {
VM_WAIT;
+ vm_pageout_deficit += (desiredpages - bp->b_npages);
goto doretry;
}
/*
@@ -2240,6 +2252,7 @@ tryagain:
((pg - VM_MIN_KERNEL_ADDRESS) >> PAGE_SHIFT),
VM_ALLOC_NORMAL);
if (!p) {
+ vm_pageout_deficit += (to - from) >> PAGE_SHIFT;
VM_WAIT;
goto tryagain;
}
diff --git a/sys/kern/vfs_export.c b/sys/kern/vfs_export.c
index 3b0eb61..2bfc934 100644
--- a/sys/kern/vfs_export.c
+++ b/sys/kern/vfs_export.c
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)vfs_subr.c 8.31 (Berkeley) 5/26/95
- * $Id: vfs_subr.c,v 1.123 1998/01/12 03:15:01 dyson Exp $
+ * $Id: vfs_subr.c,v 1.124 1998/01/17 09:16:28 dyson Exp $
*/
/*
@@ -68,6 +68,7 @@
#include <vm/vm_map.h>
#include <vm/vm_pager.h>
#include <vm/vnode_pager.h>
+#include <vm/vm_zone.h>
#include <sys/sysctl.h>
#include <miscfs/specfs/specdev.h>
@@ -120,6 +121,7 @@ struct simplelock mntvnode_slock;
struct simplelock vnode_free_list_slock;
static struct simplelock spechash_slock;
struct nfs_public nfs_pub; /* publicly exported FS */
+static vm_zone_t vnode_zone;
int desiredvnodes;
SYSCTL_INT(_kern, KERN_MAXVNODES, maxvnodes, CTLFLAG_RW, &desiredvnodes, 0, "");
@@ -144,6 +146,7 @@ vntblinit()
TAILQ_INIT(&vnode_tobefree_list);
simple_lock_init(&vnode_free_list_slock);
CIRCLEQ_INIT(&mountlist);
+ vnode_zone = zinit("VNODE", sizeof (struct vnode), 0, 0, 5);
}
/*
@@ -457,8 +460,7 @@ getnewvnode(tag, mp, vops, vpp)
vp->v_writecount = 0; /* XXX */
} else {
simple_unlock(&vnode_free_list_slock);
- vp = (struct vnode *) malloc((u_long) sizeof *vp,
- M_VNODE, M_WAITOK);
+ vp = (struct vnode *) zalloc(vnode_zone);
bzero((char *) vp, sizeof *vp);
simple_lock_init(&vp->v_interlock);
vp->v_dd = vp;
@@ -917,6 +919,7 @@ vget(vp, flags, p)
((vp->v_object == NULL) ||
(vp->v_object->flags & OBJ_DEAD))) {
vfs_object_create(vp, curproc, curproc->p_ucred, 0);
+ simple_lock(&vp->v_interlock);
}
if (flags & LK_TYPE_MASK) {
if (error = vn_lock(vp, flags | LK_INTERLOCK, p))
@@ -1390,6 +1393,7 @@ vgonel(vp, p)
* Clean out the filesystem specific data.
*/
vclean(vp, DOCLOSE, p);
+ simple_lock(&vp->v_interlock);
/*
* Delete from old mount point vnode list, if on one.
diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c
index 3b0eb61..2bfc934 100644
--- a/sys/kern/vfs_subr.c
+++ b/sys/kern/vfs_subr.c
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)vfs_subr.c 8.31 (Berkeley) 5/26/95
- * $Id: vfs_subr.c,v 1.123 1998/01/12 03:15:01 dyson Exp $
+ * $Id: vfs_subr.c,v 1.124 1998/01/17 09:16:28 dyson Exp $
*/
/*
@@ -68,6 +68,7 @@
#include <vm/vm_map.h>
#include <vm/vm_pager.h>
#include <vm/vnode_pager.h>
+#include <vm/vm_zone.h>
#include <sys/sysctl.h>
#include <miscfs/specfs/specdev.h>
@@ -120,6 +121,7 @@ struct simplelock mntvnode_slock;
struct simplelock vnode_free_list_slock;
static struct simplelock spechash_slock;
struct nfs_public nfs_pub; /* publicly exported FS */
+static vm_zone_t vnode_zone;
int desiredvnodes;
SYSCTL_INT(_kern, KERN_MAXVNODES, maxvnodes, CTLFLAG_RW, &desiredvnodes, 0, "");
@@ -144,6 +146,7 @@ vntblinit()
TAILQ_INIT(&vnode_tobefree_list);
simple_lock_init(&vnode_free_list_slock);
CIRCLEQ_INIT(&mountlist);
+ vnode_zone = zinit("VNODE", sizeof (struct vnode), 0, 0, 5);
}
/*
@@ -457,8 +460,7 @@ getnewvnode(tag, mp, vops, vpp)
vp->v_writecount = 0; /* XXX */
} else {
simple_unlock(&vnode_free_list_slock);
- vp = (struct vnode *) malloc((u_long) sizeof *vp,
- M_VNODE, M_WAITOK);
+ vp = (struct vnode *) zalloc(vnode_zone);
bzero((char *) vp, sizeof *vp);
simple_lock_init(&vp->v_interlock);
vp->v_dd = vp;
@@ -917,6 +919,7 @@ vget(vp, flags, p)
((vp->v_object == NULL) ||
(vp->v_object->flags & OBJ_DEAD))) {
vfs_object_create(vp, curproc, curproc->p_ucred, 0);
+ simple_lock(&vp->v_interlock);
}
if (flags & LK_TYPE_MASK) {
if (error = vn_lock(vp, flags | LK_INTERLOCK, p))
@@ -1390,6 +1393,7 @@ vgonel(vp, p)
* Clean out the filesystem specific data.
*/
vclean(vp, DOCLOSE, p);
+ simple_lock(&vp->v_interlock);
/*
* Delete from old mount point vnode list, if on one.
OpenPOWER on IntegriCloud