summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/amd64/amd64/machdep.c3
-rw-r--r--sys/amd64/amd64/pmap.c11
-rw-r--r--sys/amd64/amd64/vm_machdep.c3
-rw-r--r--sys/amd64/include/pmap.h3
-rw-r--r--sys/conf/files1
-rw-r--r--sys/fs/procfs/procfs_mem.c4
-rw-r--r--sys/i386/i386/machdep.c3
-rw-r--r--sys/i386/i386/pmap.c11
-rw-r--r--sys/i386/i386/vm_machdep.c3
-rw-r--r--sys/i386/include/pmap.h3
-rw-r--r--sys/kern/vfs_export.c10
-rw-r--r--sys/kern/vfs_extattr.c4
-rw-r--r--sys/kern/vfs_subr.c10
-rw-r--r--sys/kern/vfs_syscalls.c4
-rw-r--r--sys/kern/vfs_vnops.c14
-rw-r--r--sys/miscfs/procfs/procfs_mem.c4
-rw-r--r--sys/nfs/nfs_common.c11
-rw-r--r--sys/nfs/nfs_subs.c11
-rw-r--r--sys/nfs/nfs_vnops.c3
-rw-r--r--sys/nfsclient/nfs_subs.c11
-rw-r--r--sys/nfsclient/nfs_vnops.c3
-rw-r--r--sys/nfsserver/nfs_srvsubs.c11
-rw-r--r--sys/sys/mman.h8
-rw-r--r--sys/sys/proc.h12
-rw-r--r--sys/ufs/ffs/ffs_vfsops.c8
-rw-r--r--sys/ufs/lfs/lfs_vnops.c4
-rw-r--r--sys/vm/device_pager.c241
-rw-r--r--sys/vm/device_pager.h16
-rw-r--r--sys/vm/kern_lock.c205
-rw-r--r--sys/vm/lock.h58
-rw-r--r--sys/vm/swap_pager.c503
-rw-r--r--sys/vm/swap_pager.h35
-rw-r--r--sys/vm/vm.h5
-rw-r--r--sys/vm/vm_extern.h25
-rw-r--r--sys/vm/vm_fault.c290
-rw-r--r--sys/vm/vm_glue.c57
-rw-r--r--sys/vm/vm_inherit.h3
-rw-r--r--sys/vm/vm_init.c3
-rw-r--r--sys/vm/vm_kern.c18
-rw-r--r--sys/vm/vm_map.c413
-rw-r--r--sys/vm/vm_map.h4
-rw-r--r--sys/vm/vm_meter.c27
-rw-r--r--sys/vm/vm_mmap.c195
-rw-r--r--sys/vm/vm_object.c746
-rw-r--r--sys/vm/vm_object.h67
-rw-r--r--sys/vm/vm_page.c84
-rw-r--r--sys/vm/vm_page.h53
-rw-r--r--sys/vm/vm_pageout.c361
-rw-r--r--sys/vm/vm_pageout.h11
-rw-r--r--sys/vm/vm_pager.c130
-rw-r--r--sys/vm/vm_pager.h78
-rw-r--r--sys/vm/vm_swap.c4
-rw-r--r--sys/vm/vnode_pager.c470
-rw-r--r--sys/vm/vnode_pager.h21
54 files changed, 1131 insertions, 3165 deletions
diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c
index c637aff9..37fe7fb 100644
--- a/sys/amd64/amd64/machdep.c
+++ b/sys/amd64/amd64/machdep.c
@@ -35,7 +35,7 @@
* SUCH DAMAGE.
*
* from: @(#)machdep.c 7.4 (Berkeley) 6/3/91
- * $Id: machdep.c,v 1.129 1995/06/26 07:39:52 bde Exp $
+ * $Id: machdep.c,v 1.130 1995/06/28 04:46:11 davidg Exp $
*/
#include "npx.h"
@@ -77,6 +77,7 @@
#include <vm/vm.h>
#include <vm/vm_kern.h>
#include <vm/vm_page.h>
+#include <vm/vm_pager.h>
#include <sys/exec.h>
#include <sys/vnode.h>
diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c
index 9971603..0a84c05 100644
--- a/sys/amd64/amd64/pmap.c
+++ b/sys/amd64/amd64/pmap.c
@@ -39,7 +39,7 @@
* SUCH DAMAGE.
*
* from: @(#)pmap.c 7.7 (Berkeley) 5/12/91
- * $Id: pmap.c,v 1.57 1995/05/11 19:26:11 rgrimes Exp $
+ * $Id: pmap.c,v 1.58 1995/05/30 07:59:38 rgrimes Exp $
*/
/*
@@ -369,7 +369,6 @@ pmap_bootstrap(firstaddr, loadaddr)
kernel_pmap->pm_pdir = (pd_entry_t *) (KERNBASE + IdlePTD);
- simple_lock_init(&kernel_pmap->pm_lock);
kernel_pmap->pm_count = 1;
nkpt = NKPT;
@@ -535,7 +534,6 @@ pmap_pinit(pmap)
((int) pmap_kextract((vm_offset_t) pmap->pm_pdir)) | PG_V | PG_KW;
pmap->pm_count = 1;
- simple_lock_init(&pmap->pm_lock);
}
/*
@@ -605,9 +603,7 @@ pmap_destroy(pmap)
if (pmap == NULL)
return;
- simple_lock(&pmap->pm_lock);
count = --pmap->pm_count;
- simple_unlock(&pmap->pm_lock);
if (count == 0) {
pmap_release(pmap);
free((caddr_t) pmap, M_VMPMAP);
@@ -634,9 +630,7 @@ pmap_reference(pmap)
pmap_t pmap;
{
if (pmap != NULL) {
- simple_lock(&pmap->pm_lock);
pmap->pm_count++;
- simple_unlock(&pmap->pm_lock);
}
}
@@ -1469,8 +1463,6 @@ pmap_object_init_pt(pmap, addr, object, offset, size)
(object->resident_page_count > (MAX_INIT_PT / NBPG)))) {
return;
}
- if (!vm_object_lock_try(object))
- return;
/*
* if we are processing a major portion of the object, then scan the
@@ -1520,7 +1512,6 @@ pmap_object_init_pt(pmap, addr, object, offset, size)
}
}
}
- vm_object_unlock(object);
}
#if 0
diff --git a/sys/amd64/amd64/vm_machdep.c b/sys/amd64/amd64/vm_machdep.c
index 2ff3602..c73e86e 100644
--- a/sys/amd64/amd64/vm_machdep.c
+++ b/sys/amd64/amd64/vm_machdep.c
@@ -38,7 +38,7 @@
*
* from: @(#)vm_machdep.c 7.3 (Berkeley) 5/13/91
* Utah $Hdr: vm_machdep.c 1.16.1.1 89/06/23$
- * $Id: vm_machdep.c,v 1.38 1995/05/18 09:17:07 davidg Exp $
+ * $Id: vm_machdep.c,v 1.39 1995/05/30 07:59:46 rgrimes Exp $
*/
#include "npx.h"
@@ -56,6 +56,7 @@
#include <vm/vm.h>
#include <vm/vm_kern.h>
+#include <vm/vm_page.h>
#include <i386/isa/isa.h>
diff --git a/sys/amd64/include/pmap.h b/sys/amd64/include/pmap.h
index 6a35c05..654f4ba 100644
--- a/sys/amd64/include/pmap.h
+++ b/sys/amd64/include/pmap.h
@@ -42,7 +42,7 @@
*
* from: hp300: @(#)pmap.h 7.2 (Berkeley) 12/16/90
* from: @(#)pmap.h 7.4 (Berkeley) 5/12/91
- * $Id: pmap.h,v 1.25 1995/03/26 23:42:55 davidg Exp $
+ * $Id: pmap.h,v 1.26 1995/05/30 08:00:48 rgrimes Exp $
*/
#ifndef _MACHINE_PMAP_H_
@@ -148,7 +148,6 @@ struct pmap {
boolean_t pm_pdchanged; /* pdir changed */
short pm_dref; /* page directory ref count */
short pm_count; /* pmap reference count */
- simple_lock_data_t pm_lock; /* lock on pmap */
struct pmap_statistics pm_stats; /* pmap statistics */
long pm_ptpages; /* more stats: PT pages */
};
diff --git a/sys/conf/files b/sys/conf/files
index 5de033a..19f7e6e 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -336,6 +336,7 @@ ufs/ufs/ufs_lookup.c standard
ufs/ufs/ufs_quota.c standard
ufs/ufs/ufs_vfsops.c standard
ufs/ufs/ufs_vnops.c standard
+vm/default_pager.c standard
vm/device_pager.c standard
vm/kern_lock.c standard
vm/swap_pager.c standard
diff --git a/sys/fs/procfs/procfs_mem.c b/sys/fs/procfs/procfs_mem.c
index ce2ed22..ab01999 100644
--- a/sys/fs/procfs/procfs_mem.c
+++ b/sys/fs/procfs/procfs_mem.c
@@ -37,7 +37,7 @@
*
* @(#)procfs_mem.c 8.4 (Berkeley) 1/21/94
*
- * $Id: procfs_mem.c,v 1.7 1995/05/30 08:07:09 rgrimes Exp $
+ * $Id: procfs_mem.c,v 1.8 1995/06/28 04:51:06 davidg Exp $
*/
/*
@@ -152,7 +152,7 @@ procfs_rwmem(p, uio)
/*
* Fault the page in...
*/
- if (!error && writing && object->shadow) {
+ if (!error && writing && object->backing_object) {
m = vm_page_lookup(object, off);
if (m == 0 || (m->flags & PG_COPYONWRITE))
error = vm_fault(map, pageno,
diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c
index c637aff9..37fe7fb 100644
--- a/sys/i386/i386/machdep.c
+++ b/sys/i386/i386/machdep.c
@@ -35,7 +35,7 @@
* SUCH DAMAGE.
*
* from: @(#)machdep.c 7.4 (Berkeley) 6/3/91
- * $Id: machdep.c,v 1.129 1995/06/26 07:39:52 bde Exp $
+ * $Id: machdep.c,v 1.130 1995/06/28 04:46:11 davidg Exp $
*/
#include "npx.h"
@@ -77,6 +77,7 @@
#include <vm/vm.h>
#include <vm/vm_kern.h>
#include <vm/vm_page.h>
+#include <vm/vm_pager.h>
#include <sys/exec.h>
#include <sys/vnode.h>
diff --git a/sys/i386/i386/pmap.c b/sys/i386/i386/pmap.c
index 9971603..0a84c05 100644
--- a/sys/i386/i386/pmap.c
+++ b/sys/i386/i386/pmap.c
@@ -39,7 +39,7 @@
* SUCH DAMAGE.
*
* from: @(#)pmap.c 7.7 (Berkeley) 5/12/91
- * $Id: pmap.c,v 1.57 1995/05/11 19:26:11 rgrimes Exp $
+ * $Id: pmap.c,v 1.58 1995/05/30 07:59:38 rgrimes Exp $
*/
/*
@@ -369,7 +369,6 @@ pmap_bootstrap(firstaddr, loadaddr)
kernel_pmap->pm_pdir = (pd_entry_t *) (KERNBASE + IdlePTD);
- simple_lock_init(&kernel_pmap->pm_lock);
kernel_pmap->pm_count = 1;
nkpt = NKPT;
@@ -535,7 +534,6 @@ pmap_pinit(pmap)
((int) pmap_kextract((vm_offset_t) pmap->pm_pdir)) | PG_V | PG_KW;
pmap->pm_count = 1;
- simple_lock_init(&pmap->pm_lock);
}
/*
@@ -605,9 +603,7 @@ pmap_destroy(pmap)
if (pmap == NULL)
return;
- simple_lock(&pmap->pm_lock);
count = --pmap->pm_count;
- simple_unlock(&pmap->pm_lock);
if (count == 0) {
pmap_release(pmap);
free((caddr_t) pmap, M_VMPMAP);
@@ -634,9 +630,7 @@ pmap_reference(pmap)
pmap_t pmap;
{
if (pmap != NULL) {
- simple_lock(&pmap->pm_lock);
pmap->pm_count++;
- simple_unlock(&pmap->pm_lock);
}
}
@@ -1469,8 +1463,6 @@ pmap_object_init_pt(pmap, addr, object, offset, size)
(object->resident_page_count > (MAX_INIT_PT / NBPG)))) {
return;
}
- if (!vm_object_lock_try(object))
- return;
/*
* if we are processing a major portion of the object, then scan the
@@ -1520,7 +1512,6 @@ pmap_object_init_pt(pmap, addr, object, offset, size)
}
}
}
- vm_object_unlock(object);
}
#if 0
diff --git a/sys/i386/i386/vm_machdep.c b/sys/i386/i386/vm_machdep.c
index 2ff3602..c73e86e 100644
--- a/sys/i386/i386/vm_machdep.c
+++ b/sys/i386/i386/vm_machdep.c
@@ -38,7 +38,7 @@
*
* from: @(#)vm_machdep.c 7.3 (Berkeley) 5/13/91
* Utah $Hdr: vm_machdep.c 1.16.1.1 89/06/23$
- * $Id: vm_machdep.c,v 1.38 1995/05/18 09:17:07 davidg Exp $
+ * $Id: vm_machdep.c,v 1.39 1995/05/30 07:59:46 rgrimes Exp $
*/
#include "npx.h"
@@ -56,6 +56,7 @@
#include <vm/vm.h>
#include <vm/vm_kern.h>
+#include <vm/vm_page.h>
#include <i386/isa/isa.h>
diff --git a/sys/i386/include/pmap.h b/sys/i386/include/pmap.h
index 6a35c05..654f4ba 100644
--- a/sys/i386/include/pmap.h
+++ b/sys/i386/include/pmap.h
@@ -42,7 +42,7 @@
*
* from: hp300: @(#)pmap.h 7.2 (Berkeley) 12/16/90
* from: @(#)pmap.h 7.4 (Berkeley) 5/12/91
- * $Id: pmap.h,v 1.25 1995/03/26 23:42:55 davidg Exp $
+ * $Id: pmap.h,v 1.26 1995/05/30 08:00:48 rgrimes Exp $
*/
#ifndef _MACHINE_PMAP_H_
@@ -148,7 +148,6 @@ struct pmap {
boolean_t pm_pdchanged; /* pdir changed */
short pm_dref; /* page directory ref count */
short pm_count; /* pmap reference count */
- simple_lock_data_t pm_lock; /* lock on pmap */
struct pmap_statistics pm_stats; /* pmap statistics */
long pm_ptpages; /* more stats: PT pages */
};
diff --git a/sys/kern/vfs_export.c b/sys/kern/vfs_export.c
index c2b65d8..2b2b7d7 100644
--- a/sys/kern/vfs_export.c
+++ b/sys/kern/vfs_export.c
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)vfs_subr.c 8.13 (Berkeley) 4/18/94
- * $Id: vfs_subr.c,v 1.32 1995/06/28 12:00:55 davidg Exp $
+ * $Id: vfs_subr.c,v 1.33 1995/07/08 04:10:32 davidg Exp $
*/
/*
@@ -512,10 +512,8 @@ vinvalbuf(vp, flags, cred, p, slpflag, slptimeo)
*/
object = vp->v_object;
if (object != NULL) {
- vm_object_lock(object);
vm_object_page_remove(object, 0, object->size,
(flags & V_SAVE) ? TRUE : FALSE);
- vm_object_unlock(object);
}
if (!(flags & V_SAVEMETA) &&
(vp->v_dirtyblkhd.lh_first || vp->v_cleanblkhd.lh_first))
@@ -1533,11 +1531,7 @@ loop:
continue;
if (vp->v_object &&
(((vm_object_t) vp->v_object)->flags & OBJ_WRITEABLE)) {
- if (vget(vp, 1))
- goto loop;
- _vm_object_page_clean(vp->v_object,
- 0, 0, TRUE);
- vput(vp);
+ vm_object_page_clean(vp->v_object, 0, 0, TRUE, TRUE);
}
}
}
diff --git a/sys/kern/vfs_extattr.c b/sys/kern/vfs_extattr.c
index 4bf53a8..401828a 100644
--- a/sys/kern/vfs_extattr.c
+++ b/sys/kern/vfs_extattr.c
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)vfs_syscalls.c 8.13 (Berkeley) 4/15/94
- * $Id: vfs_syscalls.c,v 1.26 1995/06/28 07:06:40 davidg Exp $
+ * $Id: vfs_syscalls.c,v 1.27 1995/06/28 12:00:57 davidg Exp $
*/
#include <sys/param.h>
@@ -1785,7 +1785,7 @@ fsync(p, uap, retval)
vp = (struct vnode *)fp->f_data;
VOP_LOCK(vp);
if (vp->v_object) {
- _vm_object_page_clean(vp->v_object, 0, 0 ,0);
+ vm_object_page_clean(vp->v_object, 0, 0 ,0, FALSE);
}
error = VOP_FSYNC(vp, fp->f_cred, MNT_WAIT, p);
VOP_UNLOCK(vp);
diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c
index c2b65d8..2b2b7d7 100644
--- a/sys/kern/vfs_subr.c
+++ b/sys/kern/vfs_subr.c
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)vfs_subr.c 8.13 (Berkeley) 4/18/94
- * $Id: vfs_subr.c,v 1.32 1995/06/28 12:00:55 davidg Exp $
+ * $Id: vfs_subr.c,v 1.33 1995/07/08 04:10:32 davidg Exp $
*/
/*
@@ -512,10 +512,8 @@ vinvalbuf(vp, flags, cred, p, slpflag, slptimeo)
*/
object = vp->v_object;
if (object != NULL) {
- vm_object_lock(object);
vm_object_page_remove(object, 0, object->size,
(flags & V_SAVE) ? TRUE : FALSE);
- vm_object_unlock(object);
}
if (!(flags & V_SAVEMETA) &&
(vp->v_dirtyblkhd.lh_first || vp->v_cleanblkhd.lh_first))
@@ -1533,11 +1531,7 @@ loop:
continue;
if (vp->v_object &&
(((vm_object_t) vp->v_object)->flags & OBJ_WRITEABLE)) {
- if (vget(vp, 1))
- goto loop;
- _vm_object_page_clean(vp->v_object,
- 0, 0, TRUE);
- vput(vp);
+ vm_object_page_clean(vp->v_object, 0, 0, TRUE, TRUE);
}
}
}
diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c
index 4bf53a8..401828a 100644
--- a/sys/kern/vfs_syscalls.c
+++ b/sys/kern/vfs_syscalls.c
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)vfs_syscalls.c 8.13 (Berkeley) 4/15/94
- * $Id: vfs_syscalls.c,v 1.26 1995/06/28 07:06:40 davidg Exp $
+ * $Id: vfs_syscalls.c,v 1.27 1995/06/28 12:00:57 davidg Exp $
*/
#include <sys/param.h>
@@ -1785,7 +1785,7 @@ fsync(p, uap, retval)
vp = (struct vnode *)fp->f_data;
VOP_LOCK(vp);
if (vp->v_object) {
- _vm_object_page_clean(vp->v_object, 0, 0 ,0);
+ vm_object_page_clean(vp->v_object, 0, 0 ,0, FALSE);
}
error = VOP_FSYNC(vp, fp->f_cred, MNT_WAIT, p);
VOP_UNLOCK(vp);
diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c
index ef457cd..6df4221 100644
--- a/sys/kern/vfs_vnops.c
+++ b/sys/kern/vfs_vnops.c
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)vfs_vnops.c 8.2 (Berkeley) 1/21/94
- * $Id: vfs_vnops.c,v 1.13 1995/06/28 12:32:47 davidg Exp $
+ * $Id: vfs_vnops.c,v 1.14 1995/07/09 06:57:53 davidg Exp $
*/
#include <sys/param.h>
@@ -151,14 +151,10 @@ vn_open(ndp, fmode, cmode)
error = VOP_OPEN(vp, fmode, cred, p);
if (error)
goto bad;
- if (fmode & FWRITE)
- vp->v_writecount++;
/*
* this is here for VMIO support
*/
if (vp->v_type == VREG) {
- vm_object_t object;
- vm_pager_t pager;
retry:
if ((vp->v_flag & VVMIO) == 0) {
error = VOP_GETATTR(vp, vap, cred, p);
@@ -168,6 +164,7 @@ retry:
panic("vn_open: failed to allocate object");
vp->v_flag |= VVMIO;
} else {
+ vm_object_t object;
if ((object = vp->v_object) &&
(object->flags & OBJ_DEAD)) {
VOP_UNLOCK(vp);
@@ -177,12 +174,11 @@ retry:
}
if (!object)
panic("vn_open: VMIO object missing");
- pager = object->pager;
- if (!pager)
- panic("vn_open: VMIO pager missing");
- (void) vm_object_lookup(pager);
+ vm_object_reference(object);
}
}
+ if (fmode & FWRITE)
+ vp->v_writecount++;
return (0);
bad:
vput(vp);
diff --git a/sys/miscfs/procfs/procfs_mem.c b/sys/miscfs/procfs/procfs_mem.c
index ce2ed22..ab01999 100644
--- a/sys/miscfs/procfs/procfs_mem.c
+++ b/sys/miscfs/procfs/procfs_mem.c
@@ -37,7 +37,7 @@
*
* @(#)procfs_mem.c 8.4 (Berkeley) 1/21/94
*
- * $Id: procfs_mem.c,v 1.7 1995/05/30 08:07:09 rgrimes Exp $
+ * $Id: procfs_mem.c,v 1.8 1995/06/28 04:51:06 davidg Exp $
*/
/*
@@ -152,7 +152,7 @@ procfs_rwmem(p, uio)
/*
* Fault the page in...
*/
- if (!error && writing && object->shadow) {
+ if (!error && writing && object->backing_object) {
m = vm_page_lookup(object, off);
if (m == 0 || (m->flags & PG_COPYONWRITE))
error = vm_fault(map, pageno,
diff --git a/sys/nfs/nfs_common.c b/sys/nfs/nfs_common.c
index c47d20d..848c30b 100644
--- a/sys/nfs/nfs_common.c
+++ b/sys/nfs/nfs_common.c
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* @(#)nfs_subs.c 8.3 (Berkeley) 1/4/94
- * $Id: nfs_subs.c,v 1.18 1995/06/28 12:01:05 davidg Exp $
+ * $Id: nfs_subs.c,v 1.19 1995/07/09 06:57:59 davidg Exp $
*/
/*
@@ -59,6 +59,7 @@
#endif
#include <vm/vm.h>
+#include <vm/vnode_pager.h>
#include <nfs/rpcv2.h>
#include <nfs/nfsproto.h>
@@ -72,8 +73,6 @@
#include <miscfs/specfs/specdev.h>
-#include <vm/vnode_pager.h>
-
#include <netinet/in.h>
#ifdef ISO
#include <netiso/iso.h>
@@ -1898,7 +1897,6 @@ nfsrv_errmap(nd, err)
int
nfsrv_vmio(struct vnode *vp) {
vm_object_t object;
- vm_pager_t pager;
if ((vp == NULL) || (vp->v_type != VREG))
return 1;
@@ -1923,10 +1921,7 @@ retry:
}
if (!object)
panic("nfsrv_vmio: VMIO object missing");
- pager = object->pager;
- if (!pager)
- panic("nfsrv_vmio: VMIO pager missing");
- (void) vm_object_lookup(pager);
+ vm_object_reference(object);
}
return 0;
}
diff --git a/sys/nfs/nfs_subs.c b/sys/nfs/nfs_subs.c
index c47d20d..848c30b 100644
--- a/sys/nfs/nfs_subs.c
+++ b/sys/nfs/nfs_subs.c
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* @(#)nfs_subs.c 8.3 (Berkeley) 1/4/94
- * $Id: nfs_subs.c,v 1.18 1995/06/28 12:01:05 davidg Exp $
+ * $Id: nfs_subs.c,v 1.19 1995/07/09 06:57:59 davidg Exp $
*/
/*
@@ -59,6 +59,7 @@
#endif
#include <vm/vm.h>
+#include <vm/vnode_pager.h>
#include <nfs/rpcv2.h>
#include <nfs/nfsproto.h>
@@ -72,8 +73,6 @@
#include <miscfs/specfs/specdev.h>
-#include <vm/vnode_pager.h>
-
#include <netinet/in.h>
#ifdef ISO
#include <netiso/iso.h>
@@ -1898,7 +1897,6 @@ nfsrv_errmap(nd, err)
int
nfsrv_vmio(struct vnode *vp) {
vm_object_t object;
- vm_pager_t pager;
if ((vp == NULL) || (vp->v_type != VREG))
return 1;
@@ -1923,10 +1921,7 @@ retry:
}
if (!object)
panic("nfsrv_vmio: VMIO object missing");
- pager = object->pager;
- if (!pager)
- panic("nfsrv_vmio: VMIO pager missing");
- (void) vm_object_lookup(pager);
+ vm_object_reference(object);
}
return 0;
}
diff --git a/sys/nfs/nfs_vnops.c b/sys/nfs/nfs_vnops.c
index 59ba9b6..f4872fd 100644
--- a/sys/nfs/nfs_vnops.c
+++ b/sys/nfs/nfs_vnops.c
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* @(#)nfs_vnops.c 8.5 (Berkeley) 2/13/94
- * $Id: nfs_vnops.c,v 1.17 1995/06/28 07:06:52 davidg Exp $
+ * $Id: nfs_vnops.c,v 1.18 1995/06/28 17:33:39 dfr Exp $
*/
/*
@@ -59,6 +59,7 @@
#include <ufs/ufs/dir.h>
#include <vm/vm.h>
+#include <vm/vnode_pager.h>
#include <miscfs/specfs/specdev.h>
#include <miscfs/fifofs/fifo.h>
diff --git a/sys/nfsclient/nfs_subs.c b/sys/nfsclient/nfs_subs.c
index c47d20d..848c30b 100644
--- a/sys/nfsclient/nfs_subs.c
+++ b/sys/nfsclient/nfs_subs.c
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* @(#)nfs_subs.c 8.3 (Berkeley) 1/4/94
- * $Id: nfs_subs.c,v 1.18 1995/06/28 12:01:05 davidg Exp $
+ * $Id: nfs_subs.c,v 1.19 1995/07/09 06:57:59 davidg Exp $
*/
/*
@@ -59,6 +59,7 @@
#endif
#include <vm/vm.h>
+#include <vm/vnode_pager.h>
#include <nfs/rpcv2.h>
#include <nfs/nfsproto.h>
@@ -72,8 +73,6 @@
#include <miscfs/specfs/specdev.h>
-#include <vm/vnode_pager.h>
-
#include <netinet/in.h>
#ifdef ISO
#include <netiso/iso.h>
@@ -1898,7 +1897,6 @@ nfsrv_errmap(nd, err)
int
nfsrv_vmio(struct vnode *vp) {
vm_object_t object;
- vm_pager_t pager;
if ((vp == NULL) || (vp->v_type != VREG))
return 1;
@@ -1923,10 +1921,7 @@ retry:
}
if (!object)
panic("nfsrv_vmio: VMIO object missing");
- pager = object->pager;
- if (!pager)
- panic("nfsrv_vmio: VMIO pager missing");
- (void) vm_object_lookup(pager);
+ vm_object_reference(object);
}
return 0;
}
diff --git a/sys/nfsclient/nfs_vnops.c b/sys/nfsclient/nfs_vnops.c
index 59ba9b6..f4872fd 100644
--- a/sys/nfsclient/nfs_vnops.c
+++ b/sys/nfsclient/nfs_vnops.c
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* @(#)nfs_vnops.c 8.5 (Berkeley) 2/13/94
- * $Id: nfs_vnops.c,v 1.17 1995/06/28 07:06:52 davidg Exp $
+ * $Id: nfs_vnops.c,v 1.18 1995/06/28 17:33:39 dfr Exp $
*/
/*
@@ -59,6 +59,7 @@
#include <ufs/ufs/dir.h>
#include <vm/vm.h>
+#include <vm/vnode_pager.h>
#include <miscfs/specfs/specdev.h>
#include <miscfs/fifofs/fifo.h>
diff --git a/sys/nfsserver/nfs_srvsubs.c b/sys/nfsserver/nfs_srvsubs.c
index c47d20d..848c30b 100644
--- a/sys/nfsserver/nfs_srvsubs.c
+++ b/sys/nfsserver/nfs_srvsubs.c
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* @(#)nfs_subs.c 8.3 (Berkeley) 1/4/94
- * $Id: nfs_subs.c,v 1.18 1995/06/28 12:01:05 davidg Exp $
+ * $Id: nfs_subs.c,v 1.19 1995/07/09 06:57:59 davidg Exp $
*/
/*
@@ -59,6 +59,7 @@
#endif
#include <vm/vm.h>
+#include <vm/vnode_pager.h>
#include <nfs/rpcv2.h>
#include <nfs/nfsproto.h>
@@ -72,8 +73,6 @@
#include <miscfs/specfs/specdev.h>
-#include <vm/vnode_pager.h>
-
#include <netinet/in.h>
#ifdef ISO
#include <netiso/iso.h>
@@ -1898,7 +1897,6 @@ nfsrv_errmap(nd, err)
int
nfsrv_vmio(struct vnode *vp) {
vm_object_t object;
- vm_pager_t pager;
if ((vp == NULL) || (vp->v_type != VREG))
return 1;
@@ -1923,10 +1921,7 @@ retry:
}
if (!object)
panic("nfsrv_vmio: VMIO object missing");
- pager = object->pager;
- if (!pager)
- panic("nfsrv_vmio: VMIO pager missing");
- (void) vm_object_lookup(pager);
+ vm_object_reference(object);
}
return 0;
}
diff --git a/sys/sys/mman.h b/sys/sys/mman.h
index a3d4c47..56722c2 100644
--- a/sys/sys/mman.h
+++ b/sys/sys/mman.h
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)mman.h 8.1 (Berkeley) 6/2/93
- * $Id: mman.h,v 1.6 1995/03/25 17:28:30 davidg Exp $
+ * $Id: mman.h,v 1.7 1995/05/14 19:19:07 nate Exp $
*/
#ifndef _SYS_MMAN_H_
@@ -48,9 +48,9 @@
* Flags contain sharing type and options.
* Sharing types; choose one.
*/
-#define MAP_SHARED 0x0001 /* share changes */
-#define MAP_PRIVATE 0x0002 /* changes are private */
-#define MAP_COPY 0x0004 /* "copy" region at mmap time */
+#define MAP_SHARED 0x0001 /* share changes */
+#define MAP_PRIVATE 0x0002 /* changes are private */
+#define MAP_COPY MAP_PRIVATE /* Obsolete */
/*
* Other flags
diff --git a/sys/sys/proc.h b/sys/sys/proc.h
index 9097d0b..49b1b52 100644
--- a/sys/sys/proc.h
+++ b/sys/sys/proc.h
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)proc.h 8.8 (Berkeley) 1/21/94
- * $Id: proc.h,v 1.16 1995/02/21 00:37:31 davidg Exp $
+ * $Id: proc.h,v 1.17 1995/03/16 18:16:22 bde Exp $
*/
#ifndef _SYS_PROC_H_
@@ -136,9 +136,8 @@ struct proc {
struct vnode *p_textvp; /* Vnode of executable. */
- char p_lock; /* Process lock count. */
+ char p_lock; /* Process lock (prevent swap) count. */
char p_pad2[3]; /* alignment */
- long p_spare[2]; /* Pad to 256, avoid shifting eproc. XXX */
/* End area that is zeroed on creation. */
#define p_endzero p_startcopy
@@ -161,8 +160,7 @@ struct proc {
struct rtprio p_rtprio; /* Realtime priority. */
/* End area that is copied on creation. */
-#define p_endcopy p_thread
- int p_thread; /* Id for this "thread"; Mach glue. XXX */
+#define p_endcopy p_addr
struct user *p_addr; /* Kernel virtual addr of u-area (PROC ONLY). */
struct mdproc p_md; /* Any machine-dependent fields. */
@@ -198,9 +196,7 @@ struct proc {
#define P_WEXIT 0x02000 /* Working on exiting. */
#define P_EXEC 0x04000 /* Process called exec. */
#define P_SWAPPING 0x40000 /* Process is being swapped. */
-
-/* Should probably be changed into a hold count (They have. -DG). */
-#define P_NOSWAP 0x08000 /* Another flag to prevent swap out. */
+#define P_NOSWAP 0x08000 /* Flag to prevent swap out. */
#define P_PHYSIO 0x10000 /* Doing physical I/O. */
/* Should be moved to machine-dependent areas. */
diff --git a/sys/ufs/ffs/ffs_vfsops.c b/sys/ufs/ffs/ffs_vfsops.c
index aaebccf..f1fdb16 100644
--- a/sys/ufs/ffs/ffs_vfsops.c
+++ b/sys/ufs/ffs/ffs_vfsops.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)ffs_vfsops.c 8.8 (Berkeley) 4/18/94
- * $Id: ffs_vfsops.c,v 1.21 1995/05/30 08:15:03 rgrimes Exp $
+ * $Id: ffs_vfsops.c,v 1.22 1995/06/28 12:01:08 davidg Exp $
*/
#include <sys/param.h>
@@ -700,11 +700,7 @@ loop:
ip = VTOI(vp);
if (vp->v_object &&
(((vm_object_t) vp->v_object)->flags & OBJ_WRITEABLE)) {
- if (vget(vp, 1))
- goto loop;
- _vm_object_page_clean(vp->v_object,
- 0, 0, 0);
- vput(vp);
+ vm_object_page_clean(vp->v_object, 0, 0, 0, TRUE);
}
if ((((ip->i_flag &
diff --git a/sys/ufs/lfs/lfs_vnops.c b/sys/ufs/lfs/lfs_vnops.c
index 644f464..138931e 100644
--- a/sys/ufs/lfs/lfs_vnops.c
+++ b/sys/ufs/lfs/lfs_vnops.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)lfs_vnops.c 8.5 (Berkeley) 12/30/93
- * $Id: lfs_vnops.c,v 1.10 1995/06/28 07:06:53 davidg Exp $
+ * $Id: lfs_vnops.c,v 1.11 1995/06/28 12:01:10 davidg Exp $
*/
#include <sys/param.h>
@@ -239,7 +239,7 @@ lfs_fsync(ap)
* into the buffer cache.
*/
if (ap->a_vp->v_object)
- _vm_object_page_clean(ap->a_vp->v_object, 0, 0, 0);
+ vm_object_page_clean(ap->a_vp->v_object, 0, 0, 0, TRUE);
error = (VOP_UPDATE(ap->a_vp, &tv, &tv,
ap->a_waitfor == MNT_WAIT ? LFS_SYNC : 0));
diff --git a/sys/vm/device_pager.c b/sys/vm/device_pager.c
index 8ce0bc16..a7b0a9b 100644
--- a/sys/vm/device_pager.c
+++ b/sys/vm/device_pager.c
@@ -36,11 +36,7 @@
* SUCH DAMAGE.
*
* @(#)device_pager.c 8.1 (Berkeley) 6/11/93
- * $Id: device_pager.c,v 1.10 1995/05/18 02:59:18 davidg Exp $
- */
-
-/*
- * Page to/from special files.
+ * $Id: device_pager.c,v 1.11 1995/05/30 08:15:46 rgrimes Exp $
*/
#include <sys/param.h>
@@ -53,52 +49,35 @@
#include <vm/vm.h>
#include <vm/vm_kern.h>
#include <vm/vm_page.h>
+#include <vm/vm_pager.h>
#include <vm/device_pager.h>
-struct pagerlst dev_pager_list; /* list of managed devices */
-struct pglist dev_pager_fakelist; /* list of available vm_page_t's */
-
-#ifdef DEBUG
-int dpagerdebug;
+struct pagerlst dev_pager_object_list; /* list of device pager objects */
+TAILQ_HEAD(, vm_page) dev_pager_fakelist; /* list of available vm_page_t's */
-#define DDB_FOLLOW 0x01
-#define DDB_INIT 0x02
-#define DDB_ALLOC 0x04
-#define DDB_FAIL 0x08
-#endif
-
-static vm_pager_t dev_pager_alloc __P((void *, vm_size_t, vm_prot_t, vm_offset_t));
-static void dev_pager_dealloc __P((vm_pager_t));
-static int dev_pager_getpage __P((vm_pager_t, vm_page_t, boolean_t));
-static boolean_t dev_pager_haspage __P((vm_pager_t, vm_offset_t));
-static void dev_pager_init __P((void));
-static int dev_pager_putpage __P((vm_pager_t, vm_page_t, boolean_t));
static vm_page_t dev_pager_getfake __P((vm_offset_t));
static void dev_pager_putfake __P((vm_page_t));
+static int dev_pager_alloc_lock, dev_pager_alloc_lock_want;
+
struct pagerops devicepagerops = {
dev_pager_init,
dev_pager_alloc,
dev_pager_dealloc,
- dev_pager_getpage,
- 0,
- dev_pager_putpage,
- 0,
- dev_pager_haspage
+ dev_pager_getpages,
+ dev_pager_putpages,
+ dev_pager_haspage,
+ NULL
};
-static void
+void
dev_pager_init()
{
-#ifdef DEBUG
- if (dpagerdebug & DDB_FOLLOW)
- printf("dev_pager_init()\n");
-#endif
- TAILQ_INIT(&dev_pager_list);
+ TAILQ_INIT(&dev_pager_object_list);
TAILQ_INIT(&dev_pager_fakelist);
}
-static vm_pager_t
+vm_object_t
dev_pager_alloc(handle, size, prot, foff)
void *handle;
vm_size_t size;
@@ -106,25 +85,10 @@ dev_pager_alloc(handle, size, prot, foff)
vm_offset_t foff;
{
dev_t dev;
- vm_pager_t pager;
int (*mapfunc) ();
vm_object_t object;
- dev_pager_t devp;
unsigned int npages, off;
-#ifdef DEBUG
- if (dpagerdebug & DDB_FOLLOW)
- printf("dev_pager_alloc(%x, %x, %x, %x)\n",
- handle, size, prot, foff);
-#endif
-#ifdef DIAGNOSTIC
- /*
- * Pageout to device, should never happen.
- */
- if (handle == NULL)
- panic("dev_pager_alloc called");
-#endif
-
/*
* Make sure this device can be mapped.
*/
@@ -151,124 +115,74 @@ dev_pager_alloc(handle, size, prot, foff)
return (NULL);
/*
+ * Lock to prevent object creation race contion.
+ */
+ while (dev_pager_alloc_lock) {
+ dev_pager_alloc_lock_want++;
+ tsleep(&dev_pager_alloc_lock, PVM, "dvpall", 0);
+ dev_pager_alloc_lock_want--;
+ }
+ dev_pager_alloc_lock = 1;
+
+ /*
* Look up pager, creating as necessary.
*/
-top:
- pager = vm_pager_lookup(&dev_pager_list, handle);
- if (pager == NULL) {
- /*
- * Allocate and initialize pager structs
- */
- pager = (vm_pager_t) malloc(sizeof *pager, M_VMPAGER, M_WAITOK);
- if (pager == NULL)
- return (NULL);
- devp = (dev_pager_t) malloc(sizeof *devp, M_VMPGDATA, M_WAITOK);
- if (devp == NULL) {
- free((caddr_t) pager, M_VMPAGER);
- return (NULL);
- }
- pager->pg_handle = handle;
- pager->pg_ops = &devicepagerops;
- pager->pg_type = PG_DEVICE;
- pager->pg_data = (caddr_t) devp;
- TAILQ_INIT(&devp->devp_pglist);
+ object = vm_pager_object_lookup(&dev_pager_object_list, handle);
+ if (object == NULL) {
/*
* Allocate object and associate it with the pager.
*/
- object = devp->devp_object = vm_object_allocate(foff + size);
- object->flags &= ~OBJ_INTERNAL;
- vm_object_enter(object, pager);
- object->pager = pager;
- /*
- * Finally, put it on the managed list so other can find it.
- * First we re-lookup in case someone else beat us to this
- * point (due to blocking in the various mallocs). If so, we
- * free everything and start over.
- */
- if (vm_pager_lookup(&dev_pager_list, handle)) {
- free((caddr_t) devp, M_VMPGDATA);
- free((caddr_t) pager, M_VMPAGER);
- goto top;
- }
- TAILQ_INSERT_TAIL(&dev_pager_list, pager, pg_list);
-#ifdef DEBUG
- if (dpagerdebug & DDB_ALLOC) {
- printf("dev_pager_alloc: pager %x devp %x object %x\n",
- pager, devp, object);
- vm_object_print(object, FALSE);
- }
-#endif
+ object = vm_object_allocate(OBJT_DEVICE, foff + size);
+ object->handle = handle;
+ TAILQ_INIT(&object->un_pager.devp.devp_pglist);
+ TAILQ_INSERT_TAIL(&dev_pager_object_list, object, pager_object_list);
} else {
/*
* Gain a reference to the object.
*/
- object = vm_object_lookup(pager);
+ vm_object_reference(object);
if (foff + size > object->size)
object->size = foff + size;
-#ifdef DIAGNOSTIC
- devp = (dev_pager_t) pager->pg_data;
- if (object != devp->devp_object)
- panic("dev_pager_setup: bad object");
-#endif
}
- return (pager);
+
+ dev_pager_alloc_lock = 0;
+ if (dev_pager_alloc_lock_want)
+ wakeup(&dev_pager_alloc_lock);
+
+ return (object);
}
-static void
-dev_pager_dealloc(pager)
- vm_pager_t pager;
-{
- dev_pager_t devp;
+void
+dev_pager_dealloc(object)
vm_object_t object;
+{
vm_page_t m;
-#ifdef DEBUG
- if (dpagerdebug & DDB_FOLLOW)
- printf("dev_pager_dealloc(%x)\n", pager);
-#endif
- TAILQ_REMOVE(&dev_pager_list, pager, pg_list);
- /*
- * Get the object. Note: cannot use vm_object_lookup since object has
- * already been removed from the hash chain.
- */
- devp = (dev_pager_t) pager->pg_data;
- object = devp->devp_object;
-#ifdef DEBUG
- if (dpagerdebug & DDB_ALLOC)
- printf("dev_pager_dealloc: devp %x object %x\n", devp, object);
-#endif
+ TAILQ_REMOVE(&dev_pager_object_list, object, pager_object_list);
/*
* Free up our fake pages.
*/
- while ((m = devp->devp_pglist.tqh_first) != 0) {
- TAILQ_REMOVE(&devp->devp_pglist, m, pageq);
+ while ((m = object->un_pager.devp.devp_pglist.tqh_first) != 0) {
+ TAILQ_REMOVE(&object->un_pager.devp.devp_pglist, m, pageq);
dev_pager_putfake(m);
}
- free((caddr_t) devp, M_VMPGDATA);
- free((caddr_t) pager, M_VMPAGER);
}
-static int
-dev_pager_getpage(pager, m, sync)
- vm_pager_t pager;
- vm_page_t m;
- boolean_t sync;
+int
+dev_pager_getpages(object, m, count, reqpage)
+ vm_object_t object;
+ vm_page_t *m;
+ int count;
+ int reqpage;
{
- register vm_object_t object;
vm_offset_t offset, paddr;
vm_page_t page;
dev_t dev;
- int s;
+ int i, s;
int (*mapfunc) (), prot;
-#ifdef DEBUG
- if (dpagerdebug & DDB_FOLLOW)
- printf("dev_pager_getpage(%x, %x)\n", pager, m);
-#endif
-
- object = m->object;
- dev = (dev_t) (u_long) pager->pg_handle;
- offset = m->offset + object->paging_offset;
+ dev = (dev_t) (u_long) object->handle;
+ offset = m[reqpage]->offset + object->paging_offset;
prot = PROT_READ; /* XXX should pass in? */
mapfunc = cdevsw[major(dev)].d_mmap;
@@ -281,49 +195,44 @@ dev_pager_getpage(pager, m, sync)
panic("dev_pager_getpage: map function returns error");
#endif
/*
- * Replace the passed in page with our own fake page and free up the
- * original.
+ * Replace the passed in reqpage page with our own fake page and free up the
+ * all of the original pages.
*/
page = dev_pager_getfake(paddr);
- TAILQ_INSERT_TAIL(&((dev_pager_t) pager->pg_data)->devp_pglist,
- page, pageq);
- vm_object_lock(object);
- vm_page_lock_queues();
- PAGE_WAKEUP(m);
- vm_page_free(m);
- vm_page_unlock_queues();
+ TAILQ_INSERT_TAIL(&object->un_pager.devp.devp_pglist, page, pageq);
+ for (i = 0; i < count; i++) {
+ PAGE_WAKEUP(m[i]);
+ vm_page_free(m[i]);
+ }
s = splhigh();
vm_page_insert(page, object, offset);
splx(s);
- vm_object_unlock(object);
return (VM_PAGER_OK);
}
-static int
-dev_pager_putpage(pager, m, sync)
- vm_pager_t pager;
- vm_page_t m;
+int
+dev_pager_putpages(object, m, count, sync, rtvals)
+ vm_object_t object;
+ vm_page_t *m;
+ int count;
boolean_t sync;
+ int *rtvals;
{
-#ifdef DEBUG
- if (dpagerdebug & DDB_FOLLOW)
- printf("dev_pager_putpage(%x, %x)\n", pager, m);
-#endif
- if (pager == NULL)
- return 0;
panic("dev_pager_putpage called");
}
-static boolean_t
-dev_pager_haspage(pager, offset)
- vm_pager_t pager;
+boolean_t
+dev_pager_haspage(object, offset, before, after)
+ vm_object_t object;
vm_offset_t offset;
+ int *before;
+ int *after;
{
-#ifdef DEBUG
- if (dpagerdebug & DDB_FOLLOW)
- printf("dev_pager_haspage(%x, %x)\n", pager, offset);
-#endif
+ if (before != NULL)
+ *before = 0;
+ if (after != NULL)
+ *after = 0;
return (TRUE);
}
@@ -345,8 +254,8 @@ dev_pager_getfake(paddr)
TAILQ_REMOVE(&dev_pager_fakelist, m, pageq);
m->flags = PG_BUSY | PG_FICTITIOUS;
- m->dirty = 0;
m->valid = VM_PAGE_BITS_ALL;
+ m->dirty = 0;
m->busy = 0;
m->bmapped = 0;
@@ -360,9 +269,7 @@ static void
dev_pager_putfake(m)
vm_page_t m;
{
-#ifdef DIAGNOSTIC
if (!(m->flags & PG_FICTITIOUS))
panic("dev_pager_putfake: bad page");
-#endif
TAILQ_INSERT_TAIL(&dev_pager_fakelist, m, pageq);
}
diff --git a/sys/vm/device_pager.h b/sys/vm/device_pager.h
index 6fa8bfe..928d57f 100644
--- a/sys/vm/device_pager.h
+++ b/sys/vm/device_pager.h
@@ -36,19 +36,17 @@
* SUCH DAMAGE.
*
* @(#)device_pager.h 8.3 (Berkeley) 12/13/93
- * $Id: device_pager.h,v 1.2 1994/08/02 07:55:07 davidg Exp $
+ * $Id: device_pager.h,v 1.3 1995/01/09 16:05:30 davidg Exp $
*/
#ifndef _DEVICE_PAGER_
#define _DEVICE_PAGER_ 1
-/*
- * Device pager private data.
- */
-struct devpager {
- struct pglist devp_pglist; /* list of pages allocated */
- vm_object_t devp_object; /* object representing this device */
-};
-typedef struct devpager *dev_pager_t;
+void dev_pager_init __P((void));
+vm_object_t dev_pager_alloc __P((void *, vm_size_t, vm_prot_t, vm_offset_t));
+void dev_pager_dealloc __P((vm_object_t));
+int dev_pager_getpages __P((vm_object_t, vm_page_t *, int, int));
+int dev_pager_putpages __P((vm_object_t, vm_page_t *, int, boolean_t, int *));
+boolean_t dev_pager_haspage __P((vm_object_t, vm_offset_t, int *, int *));
#endif /* _DEVICE_PAGER_ */
diff --git a/sys/vm/kern_lock.c b/sys/vm/kern_lock.c
index 30be676..e945064 100644
--- a/sys/vm/kern_lock.c
+++ b/sys/vm/kern_lock.c
@@ -61,7 +61,7 @@
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*
- * $Id: kern_lock.c,v 1.5 1995/04/16 12:56:12 davidg Exp $
+ * $Id: kern_lock.c,v 1.6 1995/05/30 08:15:49 rgrimes Exp $
*/
/*
@@ -76,89 +76,6 @@
#include <vm/vm.h>
-typedef int *thread_t;
-
-#define current_thread() ((thread_t)&curproc->p_thread)
-/* XXX */
-
-#if NCPUS > 1
-
-/*
- * Module: lock
- * Function:
- * Provide reader/writer sychronization.
- * Implementation:
- * Simple interlock on a bit. Readers first interlock
- * increment the reader count, then let go. Writers hold
- * the interlock (thus preventing further readers), and
- * wait for already-accepted readers to go away.
- */
-
-/*
- * The simple-lock routines are the primitives out of which
- * the lock package is built. The implementation is left
- * to the machine-dependent code.
- */
-
-#ifdef notdef
-/*
- * A sample implementation of simple locks.
- * assumes:
- * boolean_t test_and_set(boolean_t *)
- * indivisibly sets the boolean to TRUE
- * and returns its old value
- * and that setting a boolean to FALSE is indivisible.
- */
-/*
- * simple_lock_init initializes a simple lock. A simple lock
- * may only be used for exclusive locks.
- */
-
-void
-simple_lock_init(l)
- simple_lock_t l;
-{
- *(boolean_t *) l = FALSE;
-}
-
-void
-simple_lock(l)
- simple_lock_t l;
-{
- while (test_and_set((boolean_t *) l))
- continue;
-}
-
-void
-simple_unlock(l)
- simple_lock_t l;
-{
- *(boolean_t *) l = FALSE;
-}
-
-boolean_t
-simple_lock_try(l)
- simple_lock_t l;
-{
- return (!test_and_set((boolean_t *) l));
-}
-#endif /* notdef */
-#endif /* NCPUS > 1 */
-
-#if NCPUS > 1
-int lock_wait_time = 100;
-
-#else /* NCPUS > 1 */
-
- /*
- * It is silly to spin on a uni-processor as if we thought something magical
- * would happen to the want_write bit while we are executing.
- */
-int lock_wait_time;
-
-#endif /* NCPUS > 1 */
-
-
/*
* Routine: lock_init
* Function:
@@ -172,14 +89,8 @@ lock_init(l, can_sleep)
lock_t l;
boolean_t can_sleep;
{
- bzero(l, sizeof(lock_data_t));
- simple_lock_init(&l->interlock);
- l->want_write = FALSE;
- l->want_upgrade = FALSE;
- l->read_count = 0;
+ bzero(l, sizeof(*l));
l->can_sleep = can_sleep;
- l->thread = (char *) -1; /* XXX */
- l->recursion_depth = 0;
}
void
@@ -187,9 +98,7 @@ lock_sleepable(l, can_sleep)
lock_t l;
boolean_t can_sleep;
{
- simple_lock(&l->interlock);
l->can_sleep = can_sleep;
- simple_unlock(&l->interlock);
}
@@ -203,32 +112,20 @@ void
lock_write(l)
register lock_t l;
{
- register int i;
-
- simple_lock(&l->interlock);
-
- if (((thread_t) l->thread) == current_thread()) {
+ if (l->proc == curproc) {
/*
* Recursive lock.
*/
l->recursion_depth++;
- simple_unlock(&l->interlock);
return;
}
/*
* Try to acquire the want_write bit.
*/
while (l->want_write) {
- if ((i = lock_wait_time) > 0) {
- simple_unlock(&l->interlock);
- while (--i > 0 && l->want_write)
- continue;
- simple_lock(&l->interlock);
- }
if (l->can_sleep && l->want_write) {
l->waiting = TRUE;
- thread_sleep((int) l, &l->interlock, FALSE);
- simple_lock(&l->interlock);
+ tsleep(l, PVM, "lckwt1", 0);
}
}
l->want_write = TRUE;
@@ -236,28 +133,17 @@ lock_write(l)
/* Wait for readers (and upgrades) to finish */
while ((l->read_count != 0) || l->want_upgrade) {
- if ((i = lock_wait_time) > 0) {
- simple_unlock(&l->interlock);
- while (--i > 0 && (l->read_count != 0 ||
- l->want_upgrade))
- continue;
- simple_lock(&l->interlock);
- }
if (l->can_sleep && (l->read_count != 0 || l->want_upgrade)) {
l->waiting = TRUE;
- thread_sleep((int) l, &l->interlock, FALSE);
- simple_lock(&l->interlock);
+ tsleep(l, PVM, "lckwt2", 0);
}
}
- simple_unlock(&l->interlock);
}
void
lock_done(l)
register lock_t l;
{
- simple_lock(&l->interlock);
-
if (l->read_count != 0)
l->read_count--;
else if (l->recursion_depth != 0)
@@ -269,43 +155,29 @@ lock_done(l)
if (l->waiting) {
l->waiting = FALSE;
- thread_wakeup((int) l);
+ wakeup(l);
}
- simple_unlock(&l->interlock);
}
void
lock_read(l)
register lock_t l;
{
- register int i;
-
- simple_lock(&l->interlock);
-
- if (((thread_t) l->thread) == current_thread()) {
+ if (l->proc == curproc) {
/*
* Recursive lock.
*/
l->read_count++;
- simple_unlock(&l->interlock);
return;
}
while (l->want_write || l->want_upgrade) {
- if ((i = lock_wait_time) > 0) {
- simple_unlock(&l->interlock);
- while (--i > 0 && (l->want_write || l->want_upgrade))
- continue;
- simple_lock(&l->interlock);
- }
if (l->can_sleep && (l->want_write || l->want_upgrade)) {
l->waiting = TRUE;
- thread_sleep((int) l, &l->interlock, FALSE);
- simple_lock(&l->interlock);
+ tsleep(l, PVM, "lockrd", 0);
}
}
l->read_count++;
- simple_unlock(&l->interlock);
}
/*
@@ -324,16 +196,13 @@ lock_read_to_write(l)
{
register int i;
- simple_lock(&l->interlock);
-
l->read_count--;
- if (((thread_t) l->thread) == current_thread()) {
+ if (l->proc == curproc) {
/*
* Recursive lock.
*/
l->recursion_depth++;
- simple_unlock(&l->interlock);
return (FALSE);
}
if (l->want_upgrade) {
@@ -343,28 +212,19 @@ lock_read_to_write(l)
*/
if (l->waiting) {
l->waiting = FALSE;
- thread_wakeup((int) l);
+ wakeup(l);
}
- simple_unlock(&l->interlock);
return (TRUE);
}
l->want_upgrade = TRUE;
while (l->read_count != 0) {
- if ((i = lock_wait_time) > 0) {
- simple_unlock(&l->interlock);
- while (--i > 0 && l->read_count != 0)
- continue;
- simple_lock(&l->interlock);
- }
if (l->can_sleep && l->read_count != 0) {
l->waiting = TRUE;
- thread_sleep((int) l, &l->interlock, FALSE);
- simple_lock(&l->interlock);
+ tsleep(l, PVM, "lckrw", 0);
}
}
- simple_unlock(&l->interlock);
return (FALSE);
}
@@ -372,8 +232,6 @@ void
lock_write_to_read(l)
register lock_t l;
{
- simple_lock(&l->interlock);
-
l->read_count++;
if (l->recursion_depth != 0)
l->recursion_depth--;
@@ -384,9 +242,8 @@ lock_write_to_read(l)
if (l->waiting) {
l->waiting = FALSE;
- thread_wakeup((int) l);
+ wakeup(l);
}
- simple_unlock(&l->interlock);
}
@@ -402,22 +259,17 @@ boolean_t
lock_try_write(l)
register lock_t l;
{
-
- simple_lock(&l->interlock);
-
- if (((thread_t) l->thread) == current_thread()) {
+ if (l->proc == curproc) {
/*
* Recursive lock
*/
l->recursion_depth++;
- simple_unlock(&l->interlock);
return (TRUE);
}
if (l->want_write || l->want_upgrade || l->read_count) {
/*
* Can't get lock.
*/
- simple_unlock(&l->interlock);
return (FALSE);
}
/*
@@ -425,7 +277,6 @@ lock_try_write(l)
*/
l->want_write = TRUE;
- simple_unlock(&l->interlock);
return (TRUE);
}
@@ -441,22 +292,17 @@ boolean_t
lock_try_read(l)
register lock_t l;
{
- simple_lock(&l->interlock);
-
- if (((thread_t) l->thread) == current_thread()) {
+ if (l->proc == curproc) {
/*
* Recursive lock
*/
l->read_count++;
- simple_unlock(&l->interlock);
return (TRUE);
}
if (l->want_write || l->want_upgrade) {
- simple_unlock(&l->interlock);
return (FALSE);
}
l->read_count++;
- simple_unlock(&l->interlock);
return (TRUE);
}
@@ -474,20 +320,15 @@ boolean_t
lock_try_read_to_write(l)
register lock_t l;
{
-
- simple_lock(&l->interlock);
-
- if (((thread_t) l->thread) == current_thread()) {
+ if (l->proc == curproc) {
/*
* Recursive lock
*/
l->read_count--;
l->recursion_depth++;
- simple_unlock(&l->interlock);
return (TRUE);
}
if (l->want_upgrade) {
- simple_unlock(&l->interlock);
return (FALSE);
}
l->want_upgrade = TRUE;
@@ -495,11 +336,9 @@ lock_try_read_to_write(l)
while (l->read_count != 0) {
l->waiting = TRUE;
- thread_sleep((int) l, &l->interlock, FALSE);
- simple_lock(&l->interlock);
+ tsleep(l, PVM, "lcktrw", 0);
}
- simple_unlock(&l->interlock);
return (TRUE);
}
@@ -511,12 +350,10 @@ void
lock_set_recursive(l)
lock_t l;
{
- simple_lock(&l->interlock);
if (!l->want_write) {
panic("lock_set_recursive: don't have write lock");
}
- l->thread = (char *) current_thread();
- simple_unlock(&l->interlock);
+ l->proc = curproc;
}
/*
@@ -526,11 +363,9 @@ void
lock_clear_recursive(l)
lock_t l;
{
- simple_lock(&l->interlock);
- if (((thread_t) l->thread) != current_thread()) {
- panic("lock_clear_recursive: wrong thread");
+ if (l->proc != curproc) {
+ panic("lock_clear_recursive: wrong proc");
}
if (l->recursion_depth == 0)
- l->thread = (char *) -1; /* XXX */
- simple_unlock(&l->interlock);
+ l->proc = NULL;
}
diff --git a/sys/vm/lock.h b/sys/vm/lock.h
index 6cd71ed..484182f 100644
--- a/sys/vm/lock.h
+++ b/sys/vm/lock.h
@@ -61,7 +61,7 @@
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*
- * $Id: lock.h,v 1.2 1994/08/02 07:55:11 davidg Exp $
+ * $Id: lock.h,v 1.3 1995/01/09 16:05:31 davidg Exp $
*/
/*
@@ -71,83 +71,29 @@
#ifndef _LOCK_H_
#define _LOCK_H_
-#define NCPUS 1 /* XXX */
-
-/*
- * A simple spin lock.
- */
-
-struct slock {
- int lock_data; /* in general 1 bit is sufficient */
-};
-
-typedef struct slock simple_lock_data_t;
-typedef struct slock *simple_lock_t;
-
/*
* The general lock structure. Provides for multiple readers,
* upgrading from read to write, and sleeping until the lock
* can be gained.
*/
-
struct lock {
-#ifdef vax
- /*
- * Efficient VAX implementation -- see field description below.
- */
- unsigned int read_count:16, want_upgrade:1, want_write:1, waiting:1, can_sleep:1,:0;
-
- simple_lock_data_t interlock;
-#else /* vax */
-#ifdef ns32000
- /*
- * Efficient ns32000 implementation -- see field description below.
- */
- simple_lock_data_t interlock;
- unsigned int read_count:16, want_upgrade:1, want_write:1, waiting:1, can_sleep:1,:0;
-
-#else /* ns32000 */
/*
* Only the "interlock" field is used for hardware exclusion; other
* fields are modified with normal instructions after acquiring the
* interlock bit.
*/
- simple_lock_data_t
- interlock; /* Interlock for remaining fields */
boolean_t want_write; /* Writer is waiting, or locked for write */
boolean_t want_upgrade; /* Read-to-write upgrade waiting */
boolean_t waiting; /* Someone is sleeping on lock */
boolean_t can_sleep; /* Can attempts to lock go to sleep */
int read_count; /* Number of accepted readers */
-#endif /* ns32000 */
-#endif /* vax */
- char *thread; /* Thread that has lock, if recursive locking
- * allowed */
- /*
- * (should be thread_t, but but we then have mutually recursive
- * definitions)
- */
+ struct proc *proc; /* If recursive locking, process that has lock */
int recursion_depth; /* Depth of recursion */
};
typedef struct lock lock_data_t;
typedef struct lock *lock_t;
-#if NCPUS > 1
-__BEGIN_DECLS
-void simple_lock __P((simple_lock_t));
-void simple_lock_init __P((simple_lock_t));
-boolean_t simple_lock_try __P((simple_lock_t));
-void simple_unlock __P((simple_lock_t));
-
-__END_DECLS
-#else /* No multiprocessor locking is necessary. */
-#define simple_lock(l)
-#define simple_lock_init(l)
-#define simple_lock_try(l) (1) /* Always succeeds. */
-#define simple_unlock(l)
-#endif
-
/* Sleep locks must work even if no multiprocessing. */
#define lock_read_done(l) lock_done(l)
diff --git a/sys/vm/swap_pager.c b/sys/vm/swap_pager.c
index 16ec7bb..2f3b268 100644
--- a/sys/vm/swap_pager.c
+++ b/sys/vm/swap_pager.c
@@ -39,7 +39,7 @@
* from: Utah $Hdr: swap_pager.c 1.4 91/04/30$
*
* @(#)swap_pager.c 8.9 (Berkeley) 3/21/94
- * $Id: swap_pager.c,v 1.40 1995/05/18 02:59:20 davidg Exp $
+ * $Id: swap_pager.c,v 1.41 1995/05/30 08:15:55 rgrimes Exp $
*/
/*
@@ -71,9 +71,6 @@
#define NPENDINGIO 10
#endif
-int swap_pager_input __P((sw_pager_t, vm_page_t *, int, int));
-int swap_pager_output __P((sw_pager_t, vm_page_t *, int, int, int *));
-
int nswiodone;
int swap_pager_full;
extern int vm_swap_size;
@@ -106,35 +103,35 @@ struct swpagerclean {
struct swpclean swap_pager_done; /* list of completed page cleans */
struct swpclean swap_pager_inuse; /* list of pending page cleans */
struct swpclean swap_pager_free; /* list of free pager clean structs */
-struct pagerlst swap_pager_list; /* list of "named" anon regions */
-struct pagerlst swap_pager_un_list; /* list of "unnamed" anon pagers */
+struct pagerlst swap_pager_object_list; /* list of "named" anon region objects */
+struct pagerlst swap_pager_un_object_list; /* list of "unnamed" anon region objects */
#define SWAP_FREE_NEEDED 0x1 /* need a swap block */
#define SWAP_FREE_NEEDED_BY_PAGEOUT 0x2
int swap_pager_needflags;
struct pagerlst *swp_qs[] = {
- &swap_pager_list, &swap_pager_un_list, (struct pagerlst *) 0
+ &swap_pager_object_list, &swap_pager_un_object_list, (struct pagerlst *) 0
};
-int swap_pager_putmulti();
-
+/*
+ * pagerops for OBJT_SWAP - "swap pager".
+ */
struct pagerops swappagerops = {
swap_pager_init,
swap_pager_alloc,
swap_pager_dealloc,
- swap_pager_getpage,
- swap_pager_getmulti,
- swap_pager_putpage,
- swap_pager_putmulti,
- swap_pager_haspage
+ swap_pager_getpages,
+ swap_pager_putpages,
+ swap_pager_haspage,
+ swap_pager_sync
};
int npendingio = NPENDINGIO;
-int require_swap_init;
void swap_pager_finish();
int dmmin, dmmax;
+
static inline void
swapsizecheck()
{
@@ -149,10 +146,8 @@ swapsizecheck()
void
swap_pager_init()
{
- dfltpagerops = &swappagerops;
-
- TAILQ_INIT(&swap_pager_list);
- TAILQ_INIT(&swap_pager_un_list);
+ TAILQ_INIT(&swap_pager_object_list);
+ TAILQ_INIT(&swap_pager_un_object_list);
/*
* Initialize clean lists
@@ -161,8 +156,6 @@ swap_pager_init()
TAILQ_INIT(&swap_pager_done);
TAILQ_INIT(&swap_pager_free);
- require_swap_init = 1;
-
/*
* Calculate the swap allocation constants.
*/
@@ -172,88 +165,56 @@ swap_pager_init()
}
-/*
- * Allocate a pager structure and associated resources.
- * Note that if we are called from the pageout daemon (handle == NULL)
- * we should not wait for memory as it could resulting in deadlock.
- */
-vm_pager_t
-swap_pager_alloc(handle, size, prot, offset)
- void *handle;
- register vm_size_t size;
- vm_prot_t prot;
- vm_offset_t offset;
+void
+swap_pager_swap_init()
{
- register vm_pager_t pager;
- register sw_pager_t swp;
- int waitok;
- int i, j;
-
- if (require_swap_init) {
- swp_clean_t spc;
- struct buf *bp;
+ swp_clean_t spc;
+ struct buf *bp;
+ int i;
- /*
- * kva's are allocated here so that we dont need to keep doing
- * kmem_alloc pageables at runtime
- */
- for (i = 0, spc = swcleanlist; i < npendingio; i++, spc++) {
- spc->spc_kva = kmem_alloc_pageable(pager_map, PAGE_SIZE * MAX_PAGEOUT_CLUSTER);
- if (!spc->spc_kva) {
- break;
- }
- spc->spc_bp = malloc(sizeof(*bp), M_TEMP, M_KERNEL);
- if (!spc->spc_bp) {
- kmem_free_wakeup(pager_map, spc->spc_kva, PAGE_SIZE);
- break;
- }
- spc->spc_flags = 0;
- TAILQ_INSERT_TAIL(&swap_pager_free, spc, spc_list);
- }
- require_swap_init = 0;
- if (size == 0)
- return (NULL);
- }
/*
- * If this is a "named" anonymous region, look it up and return the
- * appropriate pager if it exists.
+ * kva's are allocated here so that we dont need to keep doing
+ * kmem_alloc pageables at runtime
*/
- if (handle) {
- pager = vm_pager_lookup(&swap_pager_list, handle);
- if (pager != NULL) {
- /*
- * Use vm_object_lookup to gain a reference to the
- * object and also to remove from the object cache.
- */
- if (vm_object_lookup(pager) == NULL)
- panic("swap_pager_alloc: bad object");
- return (pager);
+ for (i = 0, spc = swcleanlist; i < npendingio; i++, spc++) {
+ spc->spc_kva = kmem_alloc_pageable(pager_map, PAGE_SIZE * MAX_PAGEOUT_CLUSTER);
+ if (!spc->spc_kva) {
+ break;
}
+ spc->spc_bp = malloc(sizeof(*bp), M_TEMP, M_KERNEL);
+ if (!spc->spc_bp) {
+ kmem_free_wakeup(pager_map, spc->spc_kva, PAGE_SIZE);
+ break;
+ }
+ spc->spc_flags = 0;
+ TAILQ_INSERT_TAIL(&swap_pager_free, spc, spc_list);
}
- /*
- * Pager doesn't exist, allocate swap management resources and
- * initialize.
- */
- waitok = handle ? M_WAITOK : M_KERNEL;
- pager = (vm_pager_t) malloc(sizeof *pager, M_VMPAGER, waitok);
- if (pager == NULL)
- return (NULL);
- swp = (sw_pager_t) malloc(sizeof *swp, M_VMPGDATA, waitok);
+}
+
+int
+swap_pager_swp_alloc(object, wait)
+ vm_object_t object;
+ int wait;
+{
+ register sw_pager_t swp;
+ int i, j;
+
+ if (object->pg_data != NULL)
+ panic("swap_pager_swp_alloc: swp already allocated");
+
+ swp = (sw_pager_t) malloc(sizeof *swp, M_VMPGDATA, wait);
if (swp == NULL) {
- free((caddr_t) pager, M_VMPAGER);
- return (NULL);
+ return 1;
}
- size = round_page(size);
- swp->sw_osize = size;
- swp->sw_nblocks = (btodb(size) + btodb(SWB_NPAGES * PAGE_SIZE) - 1) / btodb(SWB_NPAGES * PAGE_SIZE);
- swp->sw_blocks = (sw_blk_t)
- malloc(swp->sw_nblocks * sizeof(*swp->sw_blocks),
- M_VMPGDATA, waitok);
+
+ swp->sw_nblocks = (btodb(object->size) + btodb(SWB_NPAGES * PAGE_SIZE) - 1) / btodb(SWB_NPAGES * PAGE_SIZE);
+
+ swp->sw_blocks = (sw_blk_t) malloc(swp->sw_nblocks * sizeof(*swp->sw_blocks), M_VMPGDATA, wait);
if (swp->sw_blocks == NULL) {
free((caddr_t) swp, M_VMPGDATA);
- free((caddr_t) pager, M_VMPAGER);
- return (NULL);
+ return 1;
}
+
for (i = 0; i < swp->sw_nblocks; i++) {
swp->sw_blocks[i].swb_valid = 0;
swp->sw_blocks[i].swb_locked = 0;
@@ -263,30 +224,59 @@ swap_pager_alloc(handle, size, prot, offset)
swp->sw_poip = 0;
swp->sw_allocsize = 0;
- if (handle) {
- vm_object_t object;
- swp->sw_flags = SW_NAMED;
- TAILQ_INSERT_TAIL(&swap_pager_list, pager, pg_list);
- /*
- * Consistant with other pagers: return with object
- * referenced. Can't do this with handle == NULL since it
- * might be the pageout daemon calling.
- */
- object = vm_object_allocate(offset + size);
- object->flags &= ~OBJ_INTERNAL;
- vm_object_enter(object, pager);
- object->pager = pager;
+ object->pg_data = swp;
+
+ if (object->handle != NULL) {
+ TAILQ_INSERT_TAIL(&swap_pager_object_list, object, pager_object_list);
+ } else {
+ TAILQ_INSERT_TAIL(&swap_pager_un_object_list, object, pager_object_list);
+ }
+
+ return 0;
+}
+
+/*
+ * Allocate a pager structure and associated resources.
+ * Note that if we are called from the pageout daemon (handle == NULL)
+ * we should not wait for memory as it could resulting in deadlock.
+ */
+vm_object_t
+swap_pager_alloc(handle, size, prot, offset)
+ void *handle;
+ register vm_size_t size;
+ vm_prot_t prot;
+ vm_offset_t offset;
+{
+ vm_object_t object;
+ int i;
+
+ /*
+ * If this is a "named" anonymous region, look it up and use the
+ * object if it exists, otherwise allocate a new one.
+ */
+ if (handle) {
+ object = vm_pager_object_lookup(&swap_pager_object_list, handle);
+ if (object != NULL) {
+ vm_object_reference(object);
+ } else {
+ /*
+ * XXX - there is a race condition here. Two processes
+ * can request the same named object simultaneuously,
+ * and if one blocks for memory, the result is a disaster.
+ * Probably quite rare, but is yet another reason to just
+ * rip support of "named anonymous regions" out altogether.
+ */
+ object = vm_object_allocate(OBJT_SWAP, offset + size);
+ object->handle = handle;
+ (void) swap_pager_swp_alloc(object, M_WAITOK);
+ }
} else {
- swp->sw_flags = 0;
- TAILQ_INSERT_TAIL(&swap_pager_un_list, pager, pg_list);
+ object = vm_object_allocate(OBJT_SWAP, offset + size);
+ (void) swap_pager_swp_alloc(object, M_WAITOK);
}
- pager->pg_handle = handle;
- pager->pg_ops = &swappagerops;
- pager->pg_type = PG_SWAP;
- pager->pg_data = (caddr_t) swp;
- return (pager);
+ return (object);
}
/*
@@ -296,11 +286,12 @@ swap_pager_alloc(handle, size, prot, offset)
*/
inline static int *
-swap_pager_diskaddr(swp, offset, valid)
- sw_pager_t swp;
+swap_pager_diskaddr(object, offset, valid)
+ vm_object_t object;
vm_offset_t offset;
int *valid;
{
+ sw_pager_t swp = object->pg_data;
register sw_blk_t swb;
int ix;
@@ -308,7 +299,7 @@ swap_pager_diskaddr(swp, offset, valid)
*valid = 0;
ix = offset / (SWB_NPAGES * PAGE_SIZE);
if ((swp->sw_blocks == NULL) || (ix >= swp->sw_nblocks) ||
- (offset >= swp->sw_osize)) {
+ (offset >= object->size)) {
return (FALSE);
}
swb = &swp->sw_blocks[ix];
@@ -378,18 +369,19 @@ swap_pager_freeswapspace(sw_pager_t swp, unsigned from, unsigned to)
* this routine frees swap blocks from a specified pager
*/
void
-_swap_pager_freespace(swp, start, size)
- sw_pager_t swp;
+swap_pager_freespace(object, start, size)
+ vm_object_t object;
vm_offset_t start;
vm_offset_t size;
{
+ sw_pager_t swp = object->pg_data;
vm_offset_t i;
int s;
s = splbio();
for (i = start; i < round_page(start + size); i += PAGE_SIZE) {
int valid;
- int *addr = swap_pager_diskaddr(swp, i, &valid);
+ int *addr = swap_pager_diskaddr(object, i, &valid);
if (addr && *addr != SWB_EMPTY) {
swap_pager_freeswapspace(swp, *addr, *addr + btodb(PAGE_SIZE) - 1);
@@ -402,15 +394,6 @@ _swap_pager_freespace(swp, start, size)
splx(s);
}
-void
-swap_pager_freespace(pager, start, size)
- vm_pager_t pager;
- vm_offset_t start;
- vm_offset_t size;
-{
- _swap_pager_freespace((sw_pager_t) pager->pg_data, start, size);
-}
-
static void
swap_pager_free_swap(swp)
sw_pager_t swp;
@@ -477,7 +460,7 @@ swap_pager_free_swap(swp)
void
swap_pager_reclaim()
{
- vm_pager_t p;
+ vm_object_t object;
sw_pager_t swp;
int i, j, k;
int s;
@@ -493,7 +476,7 @@ swap_pager_reclaim()
*/
s = splbio();
if (in_reclaim) {
- tsleep((caddr_t) &in_reclaim, PSWP, "swrclm", 0);
+ tsleep(&in_reclaim, PSWP, "swrclm", 0);
splx(s);
return;
}
@@ -503,14 +486,14 @@ swap_pager_reclaim()
/* for each pager queue */
for (k = 0; swp_qs[k]; k++) {
- p = swp_qs[k]->tqh_first;
- while (p && (reclaimcount < MAXRECLAIM)) {
+ object = swp_qs[k]->tqh_first;
+ while (object && (reclaimcount < MAXRECLAIM)) {
/*
* see if any blocks associated with a pager has been
* allocated but not used (written)
*/
- swp = (sw_pager_t) p->pg_data;
+ swp = (sw_pager_t) object->pg_data;
for (i = 0; i < swp->sw_nblocks; i++) {
sw_blk_t swb = &swp->sw_blocks[i];
@@ -527,7 +510,7 @@ swap_pager_reclaim()
}
}
}
- p = p->pg_list.tqe_next;
+ object = object->pager_object_list.tqe_next;
}
}
@@ -541,7 +524,7 @@ rfinished:
}
splx(s);
in_reclaim = 0;
- wakeup((caddr_t) &in_reclaim);
+ wakeup(&in_reclaim);
}
@@ -551,10 +534,10 @@ rfinished:
*/
void
-swap_pager_copy(srcpager, srcoffset, dstpager, dstoffset, offset)
- vm_pager_t srcpager;
+swap_pager_copy(srcobject, srcoffset, dstobject, dstoffset, offset)
+ vm_object_t srcobject;
vm_offset_t srcoffset;
- vm_pager_t dstpager;
+ vm_object_t dstobject;
vm_offset_t dstoffset;
vm_offset_t offset;
{
@@ -566,41 +549,37 @@ swap_pager_copy(srcpager, srcoffset, dstpager, dstoffset, offset)
if (vm_swap_size)
no_swap_space = 0;
- if (no_swap_space)
- return;
-
- srcswp = (sw_pager_t) srcpager->pg_data;
+ srcswp = (sw_pager_t) srcobject->pg_data;
origsize = srcswp->sw_allocsize;
- dstswp = (sw_pager_t) dstpager->pg_data;
+ dstswp = (sw_pager_t) dstobject->pg_data;
/*
- * remove the source pager from the swap_pager internal queue
+ * remove the source object from the swap_pager internal queue
*/
- s = splbio();
- if (srcswp->sw_flags & SW_NAMED) {
- TAILQ_REMOVE(&swap_pager_list, srcpager, pg_list);
- srcswp->sw_flags &= ~SW_NAMED;
+ if (srcobject->handle == NULL) {
+ TAILQ_REMOVE(&swap_pager_un_object_list, srcobject, pager_object_list);
} else {
- TAILQ_REMOVE(&swap_pager_un_list, srcpager, pg_list);
+ TAILQ_REMOVE(&swap_pager_object_list, srcobject, pager_object_list);
}
+ s = splbio();
while (srcswp->sw_poip) {
- tsleep((caddr_t) srcswp, PVM, "spgout", 0);
+ tsleep(srcswp, PVM, "spgout", 0);
}
splx(s);
/*
* clean all of the pages that are currently active and finished
*/
- (void) swap_pager_clean();
+ swap_pager_sync();
s = splbio();
/*
* transfer source to destination
*/
- for (i = 0; i < dstswp->sw_osize; i += PAGE_SIZE) {
+ for (i = 0; i < dstobject->size; i += PAGE_SIZE) {
int srcvalid, dstvalid;
- int *srcaddrp = swap_pager_diskaddr(srcswp, i + offset + srcoffset,
+ int *srcaddrp = swap_pager_diskaddr(srcobject, i + offset + srcoffset,
&srcvalid);
int *dstaddrp;
@@ -614,7 +593,7 @@ swap_pager_copy(srcpager, srcoffset, dstpager, dstoffset, offset)
* dest.
*/
if (srcvalid) {
- dstaddrp = swap_pager_diskaddr(dstswp, i + dstoffset,
+ dstaddrp = swap_pager_diskaddr(dstobject, i + dstoffset,
&dstvalid);
/*
* if the dest already has a valid block,
@@ -657,43 +636,47 @@ swap_pager_copy(srcpager, srcoffset, dstpager, dstoffset, offset)
free((caddr_t) srcswp->sw_blocks, M_VMPGDATA);
srcswp->sw_blocks = 0;
free((caddr_t) srcswp, M_VMPGDATA);
- srcpager->pg_data = 0;
- free((caddr_t) srcpager, M_VMPAGER);
+ srcobject->pg_data = NULL;
return;
}
void
-swap_pager_dealloc(pager)
- vm_pager_t pager;
+swap_pager_dealloc(object)
+ vm_object_t object;
{
register sw_pager_t swp;
int s;
+ swp = (sw_pager_t) object->pg_data;
+
+ /* "Can't" happen. */
+ if (swp == NULL)
+ panic("swap_pager_dealloc: no swp data");
+
/*
* Remove from list right away so lookups will fail if we block for
* pageout completion.
*/
- s = splbio();
- swp = (sw_pager_t) pager->pg_data;
- if (swp->sw_flags & SW_NAMED) {
- TAILQ_REMOVE(&swap_pager_list, pager, pg_list);
- swp->sw_flags &= ~SW_NAMED;
+ if (object->handle == NULL) {
+ TAILQ_REMOVE(&swap_pager_un_object_list, object, pager_object_list);
} else {
- TAILQ_REMOVE(&swap_pager_un_list, pager, pg_list);
+ TAILQ_REMOVE(&swap_pager_object_list, object, pager_object_list);
}
+
/*
* Wait for all pageouts to finish and remove all entries from
* cleaning list.
*/
+ s = splbio();
while (swp->sw_poip) {
- tsleep((caddr_t) swp, PVM, "swpout", 0);
+ tsleep(swp, PVM, "swpout", 0);
}
splx(s);
- (void) swap_pager_clean();
+ swap_pager_sync();
/*
* Free left over swap blocks
@@ -708,88 +691,7 @@ swap_pager_dealloc(pager)
free((caddr_t) swp->sw_blocks, M_VMPGDATA);
swp->sw_blocks = 0;
free((caddr_t) swp, M_VMPGDATA);
- pager->pg_data = 0;
- free((caddr_t) pager, M_VMPAGER);
-}
-
-/*
- * swap_pager_getmulti can get multiple pages.
- */
-int
-swap_pager_getmulti(pager, m, count, reqpage, sync)
- vm_pager_t pager;
- vm_page_t *m;
- int count;
- int reqpage;
- boolean_t sync;
-{
- if (reqpage >= count)
- panic("swap_pager_getmulti: reqpage >= count");
- return swap_pager_input((sw_pager_t) pager->pg_data, m, count, reqpage);
-}
-
-/*
- * swap_pager_getpage gets individual pages
- */
-int
-swap_pager_getpage(pager, m, sync)
- vm_pager_t pager;
- vm_page_t m;
- boolean_t sync;
-{
- vm_page_t marray[1];
-
- marray[0] = m;
- return swap_pager_input((sw_pager_t) pager->pg_data, marray, 1, 0);
-}
-
-int
-swap_pager_putmulti(pager, m, c, sync, rtvals)
- vm_pager_t pager;
- vm_page_t *m;
- int c;
- boolean_t sync;
- int *rtvals;
-{
- int flags;
-
- if (pager == NULL) {
- (void) swap_pager_clean();
- return VM_PAGER_OK;
- }
- flags = B_WRITE;
- if (!sync)
- flags |= B_ASYNC;
-
- return swap_pager_output((sw_pager_t) pager->pg_data, m, c, flags, rtvals);
-}
-
-/*
- * swap_pager_putpage writes individual pages
- */
-int
-swap_pager_putpage(pager, m, sync)
- vm_pager_t pager;
- vm_page_t m;
- boolean_t sync;
-{
- int flags;
- vm_page_t marray[1];
- int rtvals[1];
-
-
- if (pager == NULL) {
- (void) swap_pager_clean();
- return VM_PAGER_OK;
- }
- marray[0] = m;
- flags = B_WRITE;
- if (!sync)
- flags |= B_ASYNC;
-
- swap_pager_output((sw_pager_t) pager->pg_data, marray, 1, flags, rtvals);
-
- return rtvals[0];
+ object->pg_data = 0;
}
static inline int
@@ -811,17 +713,24 @@ swap_pager_block_offset(swp, offset)
}
/*
- * _swap_pager_haspage returns TRUE if the pager has data that has
+ * swap_pager_haspage returns TRUE if the pager has data that has
* been written out.
*/
-static boolean_t
-_swap_pager_haspage(swp, offset)
- sw_pager_t swp;
+boolean_t
+swap_pager_haspage(object, offset, before, after)
+ vm_object_t object;
vm_offset_t offset;
+ int *before;
+ int *after;
{
+ sw_pager_t swp = object->pg_data;
register sw_blk_t swb;
int ix;
+ if (before != NULL)
+ *before = 0;
+ if (after != NULL)
+ *after = 0;
ix = offset / (SWB_NPAGES * PAGE_SIZE);
if (swp->sw_blocks == NULL || ix >= swp->sw_nblocks) {
return (FALSE);
@@ -836,19 +745,6 @@ _swap_pager_haspage(swp, offset)
}
/*
- * swap_pager_haspage is the externally accessible version of
- * _swap_pager_haspage above. this routine takes a vm_pager_t
- * for an argument instead of sw_pager_t.
- */
-boolean_t
-swap_pager_haspage(pager, offset)
- vm_pager_t pager;
- vm_offset_t offset;
-{
- return _swap_pager_haspage((sw_pager_t) pager->pg_data, offset);
-}
-
-/*
* swap_pager_freepage is a convienience routine that clears the busy
* bit and deallocates a page.
*/
@@ -887,16 +783,17 @@ swap_pager_iodone1(bp)
{
bp->b_flags |= B_DONE;
bp->b_flags &= ~B_ASYNC;
- wakeup((caddr_t) bp);
+ wakeup(bp);
}
int
-swap_pager_input(swp, m, count, reqpage)
- register sw_pager_t swp;
+swap_pager_getpages(object, m, count, reqpage)
+ vm_object_t object;
vm_page_t *m;
int count, reqpage;
{
+ register sw_pager_t swp = object->pg_data;
register struct buf *bp;
sw_blk_t swb[count];
register int s;
@@ -905,7 +802,6 @@ swap_pager_input(swp, m, count, reqpage)
vm_offset_t kva, off[count];
swp_clean_t spc;
vm_offset_t paging_offset;
- vm_object_t object;
int reqaddr[count];
int sequential;
@@ -1029,17 +925,17 @@ swap_pager_input(swp, m, count, reqpage)
if (swap_pager_free.tqh_first == NULL) {
s = splbio();
if (curproc == pageproc)
- (void) swap_pager_clean();
+ swap_pager_sync();
else
pagedaemon_wakeup();
while (swap_pager_free.tqh_first == NULL) {
swap_pager_needflags |= SWAP_FREE_NEEDED;
if (curproc == pageproc)
swap_pager_needflags |= SWAP_FREE_NEEDED_BY_PAGEOUT;
- tsleep((caddr_t) &swap_pager_free,
+ tsleep(&swap_pager_free,
PVM, "swpfre", 0);
if (curproc == pageproc)
- (void) swap_pager_clean();
+ swap_pager_sync();
else
pagedaemon_wakeup();
}
@@ -1091,7 +987,7 @@ swap_pager_input(swp, m, count, reqpage)
*/
s = splbio();
while ((bp->b_flags & B_DONE) == 0) {
- tsleep((caddr_t) bp, PVM, "swread", 0);
+ tsleep(bp, PVM, "swread", 0);
}
if (bp->b_flags & B_ERROR) {
@@ -1104,7 +1000,7 @@ swap_pager_input(swp, m, count, reqpage)
--swp->sw_piip;
if (swp->sw_piip == 0)
- wakeup((caddr_t) swp);
+ wakeup(swp);
/*
@@ -1124,7 +1020,7 @@ swap_pager_input(swp, m, count, reqpage)
if (spc) {
m[reqpage]->object->last_read = m[reqpage]->offset;
if (bp->b_flags & B_WANTED)
- wakeup((caddr_t) bp);
+ wakeup(bp);
/*
* if we have used an spc, we need to free it.
*/
@@ -1134,7 +1030,7 @@ swap_pager_input(swp, m, count, reqpage)
crfree(bp->b_wcred);
TAILQ_INSERT_TAIL(&swap_pager_free, spc, spc_list);
if (swap_pager_needflags & SWAP_FREE_NEEDED) {
- wakeup((caddr_t) &swap_pager_free);
+ wakeup(&swap_pager_free);
}
if( swap_pager_needflags & SWAP_FREE_NEEDED_BY_PAGEOUT)
pagedaemon_wakeup();
@@ -1185,7 +1081,7 @@ swap_pager_input(swp, m, count, reqpage)
for (i = 0; i < count; i++) {
m[i]->dirty = VM_PAGE_BITS_ALL;
}
- _swap_pager_freespace(swp, m[0]->offset + paging_offset, count * PAGE_SIZE);
+ swap_pager_freespace(object, m[0]->offset + paging_offset, count * PAGE_SIZE);
}
} else {
swap_pager_ridpages(m, count, reqpage);
@@ -1195,13 +1091,14 @@ swap_pager_input(swp, m, count, reqpage)
}
int
-swap_pager_output(swp, m, count, flags, rtvals)
- register sw_pager_t swp;
+swap_pager_putpages(object, m, count, sync, rtvals)
+ vm_object_t object;
vm_page_t *m;
int count;
- int flags;
+ boolean_t sync;
int *rtvals;
{
+ register sw_pager_t swp = object->pg_data;
register struct buf *bp;
sw_blk_t swb[count];
register int s;
@@ -1210,7 +1107,6 @@ swap_pager_output(swp, m, count, flags, rtvals)
vm_offset_t kva, off, foff;
swp_clean_t spc;
vm_offset_t paging_offset;
- vm_object_t object;
int reqaddr[count];
int failed;
@@ -1341,8 +1237,8 @@ swap_pager_output(swp, m, count, flags, rtvals)
/*
* For synchronous writes, we clean up all completed async pageouts.
*/
- if ((flags & B_ASYNC) == 0) {
- swap_pager_clean();
+ if (sync == TRUE) {
+ swap_pager_sync();
}
kva = 0;
@@ -1354,7 +1250,7 @@ swap_pager_output(swp, m, count, flags, rtvals)
swap_pager_free.tqh_first->spc_list.tqe_next->spc_list.tqe_next == NULL) {
s = splbio();
if (curproc == pageproc) {
- (void) swap_pager_clean();
+ swap_pager_sync();
#if 0
splx(s);
return VM_PAGER_AGAIN;
@@ -1367,14 +1263,13 @@ swap_pager_output(swp, m, count, flags, rtvals)
if (curproc == pageproc) {
swap_pager_needflags |= SWAP_FREE_NEEDED_BY_PAGEOUT;
if((cnt.v_free_count + cnt.v_cache_count) > cnt.v_free_reserved)
- wakeup((caddr_t) &cnt.v_free_count);
+ wakeup(&cnt.v_free_count);
}
swap_pager_needflags |= SWAP_FREE_NEEDED;
- tsleep((caddr_t) &swap_pager_free,
- PVM, "swpfre", 0);
+ tsleep(&swap_pager_free, PVM, "swpfre", 0);
if (curproc == pageproc)
- (void) swap_pager_clean();
+ swap_pager_sync();
else
pagedaemon_wakeup();
}
@@ -1434,7 +1329,7 @@ swap_pager_output(swp, m, count, flags, rtvals)
* place a "cleaning" entry on the inuse queue.
*/
s = splbio();
- if (flags & B_ASYNC) {
+ if (sync == FALSE) {
spc->spc_flags = 0;
spc->spc_swp = swp;
for (i = 0; i < count; i++)
@@ -1461,9 +1356,9 @@ swap_pager_output(swp, m, count, flags, rtvals)
* perform the I/O
*/
VOP_STRATEGY(bp);
- if ((flags & (B_READ | B_ASYNC)) == B_ASYNC) {
+ if (sync == FALSE) {
if ((bp->b_flags & B_DONE) == B_DONE) {
- swap_pager_clean();
+ swap_pager_sync();
}
splx(s);
for (i = 0; i < count; i++) {
@@ -1475,7 +1370,7 @@ swap_pager_output(swp, m, count, flags, rtvals)
* wait for the sync I/O to complete
*/
while ((bp->b_flags & B_DONE) == 0) {
- tsleep((caddr_t) bp, PVM, "swwrt", 0);
+ tsleep(bp, PVM, "swwrt", 0);
}
if (bp->b_flags & B_ERROR) {
printf("swap_pager: I/O error - pageout failed; blkno %d, size %d, error %d\n",
@@ -1487,12 +1382,12 @@ swap_pager_output(swp, m, count, flags, rtvals)
--swp->sw_poip;
if (swp->sw_poip == 0)
- wakeup((caddr_t) swp);
+ wakeup(swp);
if (bp->b_vp)
pbrelvp(bp);
if (bp->b_flags & B_WANTED)
- wakeup((caddr_t) bp);
+ wakeup(bp);
splx(s);
@@ -1532,7 +1427,7 @@ swap_pager_output(swp, m, count, flags, rtvals)
crfree(bp->b_wcred);
TAILQ_INSERT_TAIL(&swap_pager_free, spc, spc_list);
if (swap_pager_needflags & SWAP_FREE_NEEDED) {
- wakeup((caddr_t) &swap_pager_free);
+ wakeup(&swap_pager_free);
}
if( swap_pager_needflags & SWAP_FREE_NEEDED_BY_PAGEOUT)
pagedaemon_wakeup();
@@ -1540,15 +1435,15 @@ swap_pager_output(swp, m, count, flags, rtvals)
return (rv);
}
-boolean_t
-swap_pager_clean()
+void
+swap_pager_sync()
{
register swp_clean_t spc, tspc;
register int s;
tspc = NULL;
if (swap_pager_done.tqh_first == NULL)
- return FALSE;
+ return;
for (;;) {
s = splbio();
/*
@@ -1580,7 +1475,7 @@ doclean:
spc->spc_flags = 0;
TAILQ_INSERT_TAIL(&swap_pager_free, spc, spc_list);
if (swap_pager_needflags & SWAP_FREE_NEEDED) {
- wakeup((caddr_t) &swap_pager_free);
+ wakeup(&swap_pager_free);
}
if( swap_pager_needflags & SWAP_FREE_NEEDED_BY_PAGEOUT)
pagedaemon_wakeup();
@@ -1588,7 +1483,7 @@ doclean:
splx(s);
}
- return (tspc ? TRUE : FALSE);
+ return;
}
void
@@ -1602,7 +1497,7 @@ swap_pager_finish(spc)
if ((object->paging_in_progress == 0) &&
(object->flags & OBJ_PIPWNT)) {
object->flags &= ~OBJ_PIPWNT;
- thread_wakeup((int) object);
+ wakeup(object);
}
/*
@@ -1662,7 +1557,7 @@ swap_pager_iodone(bp)
pbrelvp(bp);
if (bp->b_flags & B_WANTED)
- wakeup((caddr_t) bp);
+ wakeup(bp);
if (bp->b_rcred != NOCRED)
crfree(bp->b_rcred);
@@ -1671,12 +1566,12 @@ swap_pager_iodone(bp)
nswiodone += spc->spc_count;
if (--spc->spc_swp->sw_poip == 0) {
- wakeup((caddr_t) spc->spc_swp);
+ wakeup(spc->spc_swp);
}
if ((swap_pager_needflags & SWAP_FREE_NEEDED) ||
swap_pager_inuse.tqh_first == 0) {
swap_pager_needflags &= ~SWAP_FREE_NEEDED;
- wakeup((caddr_t) &swap_pager_free);
+ wakeup(&swap_pager_free);
}
if( swap_pager_needflags & SWAP_FREE_NEEDED_BY_PAGEOUT) {
@@ -1685,7 +1580,7 @@ swap_pager_iodone(bp)
}
if (vm_pageout_pages_needed) {
- wakeup((caddr_t) &vm_pageout_pages_needed);
+ wakeup(&vm_pageout_pages_needed);
vm_pageout_pages_needed = 0;
}
if ((swap_pager_inuse.tqh_first == NULL) ||
diff --git a/sys/vm/swap_pager.h b/sys/vm/swap_pager.h
index 5a1393f..a2beaa6 100644
--- a/sys/vm/swap_pager.h
+++ b/sys/vm/swap_pager.h
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* from: @(#)swap_pager.h 7.1 (Berkeley) 12/5/90
- * $Id: swap_pager.h,v 1.5 1995/02/02 09:08:09 davidg Exp $
+ * $Id: swap_pager.h,v 1.6 1995/05/10 18:56:04 davidg Exp $
*/
/*
@@ -67,36 +67,27 @@ typedef struct swblock *sw_blk_t;
* Swap pager private data.
*/
struct swpager {
- vm_size_t sw_osize; /* size of object we are backing (bytes) */
int sw_nblocks; /* number of blocks in list (sw_blk_t units) */
int sw_allocsize; /* amount of space actually allocated */
sw_blk_t sw_blocks; /* pointer to list of swap blocks */
- short sw_flags; /* flags */
short sw_poip; /* pageouts in progress */
short sw_piip; /* pageins in progress */
};
typedef struct swpager *sw_pager_t;
-#define SW_WANTED 0x01
-#define SW_NAMED 0x02
-
#ifdef KERNEL
-
-void swap_pager_init(void);
-vm_pager_t swap_pager_alloc(void *, vm_size_t, vm_prot_t, vm_offset_t);
-void swap_pager_dealloc(vm_pager_t);
-boolean_t swap_pager_getpage(vm_pager_t, vm_page_t, boolean_t);
-boolean_t swap_pager_putpage(vm_pager_t, vm_page_t, boolean_t);
-boolean_t swap_pager_getmulti(vm_pager_t, vm_page_t *, int, int, boolean_t);
-boolean_t swap_pager_haspage(vm_pager_t, vm_offset_t);
-int swap_pager_io(sw_pager_t, vm_page_t *, int, int, int);
-void swap_pager_iodone(struct buf *);
-boolean_t swap_pager_clean();
-void swap_pager_copy __P((vm_pager_t, vm_offset_t, vm_pager_t, vm_offset_t, vm_offset_t));
-void swap_pager_freespace __P((vm_pager_t, vm_offset_t, vm_offset_t));
-
-extern struct pagerops swappagerops;
-
+void swap_pager_init __P((void));
+vm_object_t swap_pager_alloc __P((void *, vm_size_t, vm_prot_t, vm_offset_t));
+void swap_pager_dealloc __P((vm_object_t));
+int swap_pager_getpages __P((vm_object_t, vm_page_t *, int, int));
+int swap_pager_putpages __P((vm_object_t, vm_page_t *, int, boolean_t, int *));
+boolean_t swap_pager_haspage __P((vm_object_t, vm_offset_t, int *, int *));
+void swap_pager_sync __P((void));
+void swap_pager_iodone __P((struct buf *));
+int swap_pager_swp_alloc __P((vm_object_t, int));
+void swap_pager_copy __P((vm_object_t, vm_offset_t, vm_object_t, vm_offset_t, vm_offset_t));
+void swap_pager_freespace __P((vm_object_t, vm_offset_t, vm_offset_t));
+void swap_pager_swap_init __P((void));
#endif
#endif /* _SWAP_PAGER_ */
diff --git a/sys/vm/vm.h b/sys/vm/vm.h
index a24ba32..9b26841 100644
--- a/sys/vm/vm.h
+++ b/sys/vm/vm.h
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)vm.h 8.2 (Berkeley) 12/13/93
- * $Id: vm.h,v 1.3 1994/08/02 07:55:16 davidg Exp $
+ * $Id: vm.h,v 1.4 1995/01/09 16:05:37 davidg Exp $
*/
#ifndef VM_H
@@ -54,9 +54,6 @@ typedef struct vm_object *vm_object_t;
struct vm_page;
typedef struct vm_page *vm_page_t;
-struct pager_struct;
-typedef struct pager_struct *vm_pager_t;
-
#include <sys/vmmeter.h>
#include <sys/queue.h>
#include <machine/cpufunc.h>
diff --git a/sys/vm/vm_extern.h b/sys/vm/vm_extern.h
index db93e13..71c5180 100644
--- a/sys/vm/vm_extern.h
+++ b/sys/vm/vm_extern.h
@@ -31,14 +31,13 @@
* SUCH DAMAGE.
*
* @(#)vm_extern.h 8.2 (Berkeley) 1/12/94
- * $Id: vm_extern.h,v 1.15 1995/05/14 03:00:09 davidg Exp $
+ * $Id: vm_extern.h,v 1.16 1995/07/10 08:53:16 davidg Exp $
*/
#ifndef _VM_EXTERN_H_
#define _VM_EXTERN_H_
struct buf;
-struct loadavg;
struct proc;
struct vmspace;
struct vmtotal;
@@ -50,17 +49,6 @@ void chgkprot __P((caddr_t, int, int));
#endif
-/*
- * Try to get semi-meaningful wait messages into thread_sleep...
- */
-void thread_sleep_ __P((int, simple_lock_t, char *));
-
-#if __GNUC__ >= 2
-#define thread_sleep(a,b,c) thread_sleep_((a), (b), __FUNCTION__)
-#else
-#define thread_sleep(a,b,c) thread_sleep_((a), (b), "vmslp")
-#endif
-
#ifdef KERNEL
extern int indent;
@@ -79,13 +67,10 @@ int swapon __P((struct proc *, void *, int *));
#endif
-void assert_wait __P((int, boolean_t));
void faultin __P((struct proc *p));
int grow __P((struct proc *, u_int));
void iprintf __P((const char *,...));
int kernacc __P((caddr_t, int, int));
-int kinfo_loadavg __P((int, char *, int *, int, int *));
-int kinfo_meter __P((int, caddr_t, int *, int, int *));
vm_offset_t kmem_alloc __P((vm_map_t, vm_size_t));
vm_offset_t kmem_alloc_pageable __P((vm_map_t, vm_size_t));
vm_offset_t kmem_alloc_wait __P((vm_map_t, vm_size_t));
@@ -94,17 +79,12 @@ void kmem_free_wakeup __P((vm_map_t, vm_offset_t, vm_size_t));
void kmem_init __P((vm_offset_t, vm_offset_t));
vm_offset_t kmem_malloc __P((vm_map_t, vm_size_t, boolean_t));
vm_map_t kmem_suballoc __P((vm_map_t, vm_offset_t *, vm_offset_t *, vm_size_t, boolean_t));
-void loadav __P((struct loadavg *));
void munmapfd __P((struct proc *, int));
int pager_cache __P((vm_object_t, boolean_t));
-void sched __P((void));
int swaponvp __P((struct proc *, struct vnode *, dev_t , u_long ));
void swapout __P((struct proc *));
void swapout_procs __P((void));
void swstrategy __P((struct buf *));
-void thread_block __P((char *));
-void thread_sleep __P((int, simple_lock_t, boolean_t));
-void thread_wakeup __P((int));
int useracc __P((caddr_t, int, int));
int vm_fault __P((vm_map_t, vm_offset_t, vm_prot_t, boolean_t));
void vm_fault_copy_entry __P((vm_map_t, vm_map_t, vm_map_entry_t, vm_map_entry_t));
@@ -121,10 +101,9 @@ struct vmspace *vmspace_alloc __P((vm_offset_t, vm_offset_t, int));
struct vmspace *vmspace_fork __P((struct vmspace *));
void vmspace_free __P((struct vmspace *));
void vmtotal __P((struct vmtotal *));
-vm_pager_t vnode_pager_alloc __P((void *, vm_offset_t, vm_prot_t, vm_offset_t));
void vnode_pager_setsize __P((struct vnode *, u_long));
void vnode_pager_umount __P((struct mount *));
-boolean_t vnode_pager_uncache __P((struct vnode *));
+void vnode_pager_uncache __P((struct vnode *));
void vslock __P((caddr_t, u_int));
void vsunlock __P((caddr_t, u_int, int));
diff --git a/sys/vm/vm_fault.c b/sys/vm/vm_fault.c
index c061c3e..debb3c9 100644
--- a/sys/vm/vm_fault.c
+++ b/sys/vm/vm_fault.c
@@ -66,7 +66,7 @@
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*
- * $Id: vm_fault.c,v 1.24 1995/05/18 02:59:22 davidg Exp $
+ * $Id: vm_fault.c,v 1.25 1995/05/30 08:15:59 rgrimes Exp $
*/
/*
@@ -76,6 +76,7 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/proc.h>
+#include <sys/vnode.h>
#include <sys/resource.h>
#include <sys/signalvar.h>
#include <sys/resourcevar.h>
@@ -84,19 +85,16 @@
#include <vm/vm_page.h>
#include <vm/vm_pageout.h>
#include <vm/vm_kern.h>
+#include <vm/vm_pager.h>
+#include <vm/vnode_pager.h>
int vm_fault_additional_pages __P((vm_object_t, vm_offset_t, vm_page_t, int, int, vm_page_t *, int *));
#define VM_FAULT_READ_AHEAD 4
-#define VM_FAULT_READ_AHEAD_MIN 1
#define VM_FAULT_READ_BEHIND 3
#define VM_FAULT_READ (VM_FAULT_READ_AHEAD+VM_FAULT_READ_BEHIND+1)
extern int swap_pager_full;
-struct vnode *vnode_pager_lock __P((vm_object_t object));
-void vnode_pager_unlock __P((struct vnode *));
-
-
/*
* vm_fault:
*
@@ -148,16 +146,12 @@ vm_fault(map, vaddr, fault_type, change_wiring)
*/
#define FREE_PAGE(m) { \
PAGE_WAKEUP(m); \
- vm_page_lock_queues(); \
vm_page_free(m); \
- vm_page_unlock_queues(); \
}
#define RELEASE_PAGE(m) { \
PAGE_WAKEUP(m); \
- vm_page_lock_queues(); \
if ((m->flags & PG_ACTIVE) == 0) vm_page_activate(m); \
- vm_page_unlock_queues(); \
}
#define UNLOCK_MAP { \
@@ -169,15 +163,12 @@ vm_fault(map, vaddr, fault_type, change_wiring)
#define UNLOCK_THINGS { \
vm_object_pip_wakeup(object); \
- vm_object_unlock(object); \
if (object != first_object) { \
- vm_object_lock(first_object); \
FREE_PAGE(first_m); \
vm_object_pip_wakeup(first_object); \
- vm_object_unlock(first_object); \
} \
UNLOCK_MAP; \
- if (vp != NULL) vnode_pager_unlock(vp); \
+ if (vp != NULL) VOP_UNLOCK(vp); \
}
#define UNLOCK_AND_DEALLOCATE { \
@@ -198,7 +189,7 @@ RetryFault:;
return (result);
}
- vp = (struct vnode *) vnode_pager_lock(first_object);
+ vp = vnode_pager_lock(first_object);
lookup_still_valid = TRUE;
@@ -214,8 +205,6 @@ RetryFault:;
* they will stay around as well.
*/
- vm_object_lock(first_object);
-
first_object->ref_count++;
first_object->paging_in_progress++;
@@ -223,7 +212,7 @@ RetryFault:;
* INVARIANTS (through entire routine):
*
* 1) At all times, we must either have the object lock or a busy
- * page in some object to prevent some other thread from trying to
+ * page in some object to prevent some other process from trying to
* bring in the same page.
*
* Note that we cannot hold any locks during the pager access or when
@@ -237,7 +226,7 @@ RetryFault:;
* 2) Once we have a busy page, we must remove it from the pageout
* queues, so that the pageout daemon will not grab it away.
*
- * 3) To prevent another thread from racing us down the shadow chain
+ * 3) To prevent another process from racing us down the shadow chain
* and entering a new page in the top object before we do, we must
* keep a busy page in the top object while following the shadow
* chain.
@@ -273,7 +262,7 @@ RetryFault:;
if ((m->flags & PG_BUSY) || m->busy) {
m->flags |= PG_WANTED | PG_REFERENCED;
cnt.v_intrans++;
- tsleep((caddr_t) m, PSWP, "vmpfw", 0);
+ tsleep(m, PSWP, "vmpfw", 0);
}
splx(s);
vm_object_deallocate(first_object);
@@ -288,7 +277,7 @@ RetryFault:;
}
/*
- * Mark page busy for other threads, and the pagedaemon.
+ * Mark page busy for other processes, and the pagedaemon.
*/
m->flags |= PG_BUSY;
if (m->valid && ((m->valid & VM_PAGE_BITS_ALL) != VM_PAGE_BITS_ALL) &&
@@ -297,16 +286,18 @@ RetryFault:;
}
break;
}
- if (((object->pager != NULL) && (!change_wiring || wired))
+ if (((object->type != OBJT_DEFAULT) && (!change_wiring || wired))
|| (object == first_object)) {
if (offset >= object->size) {
UNLOCK_AND_DEALLOCATE;
return (KERN_PROTECTION_FAILURE);
}
- if (swap_pager_full && !object->shadow && (!object->pager ||
- (object->pager && object->pager->pg_type == PG_SWAP &&
- !vm_pager_has_page(object->pager, offset + object->paging_offset)))) {
+#if 0 /* XXX is this really necessary? */
+ if (swap_pager_full && !object->backing_object &&
+ (object->type == OBJT_DEFAULT ||
+ (object->type == OBJT_SWAP &&
+ !vm_pager_has_page(object, offset + object->paging_offset, NULL, NULL)))) {
if (vaddr < VM_MAXUSER_ADDRESS && curproc && curproc->p_pid >= 48) { /* XXX */
printf("Process %lu killed by vm_fault -- out of swap\n", (u_long) curproc->p_pid);
psignal(curproc, SIGKILL);
@@ -315,6 +306,7 @@ RetryFault:;
resetpriority(curproc);
}
}
+#endif
/*
* Allocate a new page for this object/offset pair.
*/
@@ -328,17 +320,12 @@ RetryFault:;
}
}
readrest:
- if (object->pager != NULL && (!change_wiring || wired)) {
+ if (object->type != OBJT_DEFAULT && (!change_wiring || wired)) {
int rv;
int faultcount;
int reqpage;
/*
- * Now that we have a busy page, we can release the
- * object lock.
- */
- vm_object_unlock(object);
- /*
* now we find out if any other pages should be paged
* in at this time this routine checks to see if the
* pages surrounding this fault reside in the same
@@ -362,14 +349,13 @@ readrest:
UNLOCK_MAP;
rv = faultcount ?
- vm_pager_get_pages(object->pager,
- marray, faultcount, reqpage, TRUE) : VM_PAGER_FAIL;
+ vm_pager_get_pages(object, marray, faultcount,
+ reqpage) : VM_PAGER_FAIL;
if (rv == VM_PAGER_OK) {
/*
* Found the page. Leave it busy while we play
* with it.
*/
- vm_object_lock(object);
/*
* Relookup in case pager changed page. Pager
@@ -392,11 +378,11 @@ readrest:
* object/offset); before doing so, we must get back
* our object lock to preserve our invariant.
*
- * Also wake up any other thread that may want to bring
+ * Also wake up any other process that may want to bring
* in this page.
*
* If this is the top-level object, we must leave the
- * busy page to prevent another thread from rushing
+ * busy page to prevent another process from rushing
* past us, and inserting the page in that object at
* the same time that we are.
*/
@@ -404,7 +390,6 @@ readrest:
if (rv == VM_PAGER_ERROR)
printf("vm_fault: pager input (probably hardware) error, PID %d failure\n",
curproc->p_pid);
- vm_object_lock(object);
/*
* Data outside the range of the pager or an I/O error
*/
@@ -427,7 +412,7 @@ readrest:
}
}
/*
- * We get here if the object has no pager (or unwiring) or the
+ * We get here if the object has default pager (or unwiring) or the
* pager doesn't have the page.
*/
if (object == first_object)
@@ -438,8 +423,8 @@ readrest:
* unlocking the current one.
*/
- offset += object->shadow_offset;
- next_object = object->shadow;
+ offset += object->backing_object_offset;
+ next_object = object->backing_object;
if (next_object == NULL) {
/*
* If there's no object left, fill the page in the top
@@ -447,12 +432,10 @@ readrest:
*/
if (object != first_object) {
vm_object_pip_wakeup(object);
- vm_object_unlock(object);
object = first_object;
offset = first_offset;
m = first_m;
- vm_object_lock(object);
}
first_m = NULL;
@@ -461,11 +444,9 @@ readrest:
cnt.v_zfod++;
break;
} else {
- vm_object_lock(next_object);
if (object != first_object) {
vm_object_pip_wakeup(object);
}
- vm_object_unlock(object);
object = next_object;
object->paging_in_progress++;
}
@@ -529,19 +510,15 @@ readrest:
* call.
*/
- vm_page_lock_queues();
-
if ((m->flags & PG_ACTIVE) == 0)
vm_page_activate(m);
vm_page_protect(m, VM_PROT_NONE);
- vm_page_unlock_queues();
/*
* We no longer need the old page or object.
*/
PAGE_WAKEUP(m);
vm_object_pip_wakeup(object);
- vm_object_unlock(object);
/*
* Only use the new page below...
@@ -555,9 +532,7 @@ readrest:
/*
* Now that we've gotten the copy out of the way,
* let's try to collapse the top object.
- */
- vm_object_lock(object);
- /*
+ *
* But we have to play ugly games with
* paging_in_progress to do that...
*/
@@ -571,176 +546,6 @@ readrest:
}
/*
- * If the page is being written, but hasn't been copied to the
- * copy-object, we have to copy it there.
- */
-RetryCopy:
- if (first_object->copy != NULL) {
- vm_object_t copy_object = first_object->copy;
- vm_offset_t copy_offset;
- vm_page_t copy_m;
-
- /*
- * We only need to copy if we want to write it.
- */
- if ((fault_type & VM_PROT_WRITE) == 0) {
- prot &= ~VM_PROT_WRITE;
- m->flags |= PG_COPYONWRITE;
- } else {
- /*
- * Try to get the lock on the copy_object.
- */
- if (!vm_object_lock_try(copy_object)) {
- vm_object_unlock(object);
- /* should spin a bit here... */
- vm_object_lock(object);
- goto RetryCopy;
- }
- /*
- * Make another reference to the copy-object, to keep
- * it from disappearing during the copy.
- */
- copy_object->ref_count++;
-
- /*
- * Does the page exist in the copy?
- */
- copy_offset = first_offset
- - copy_object->shadow_offset;
- copy_m = vm_page_lookup(copy_object, copy_offset);
- page_exists = (copy_m != NULL);
- if (page_exists) {
- if ((copy_m->flags & PG_BUSY) || copy_m->busy) {
- /*
- * If the page is being brought in,
- * wait for it and then retry.
- */
- RELEASE_PAGE(m);
- copy_object->ref_count--;
- vm_object_unlock(copy_object);
- UNLOCK_THINGS;
- spl = splhigh();
- if ((copy_m->flags & PG_BUSY) || copy_m->busy) {
- copy_m->flags |= PG_WANTED | PG_REFERENCED;
- tsleep((caddr_t) copy_m, PSWP, "vmpfwc", 0);
- }
- splx(spl);
- vm_object_deallocate(first_object);
- goto RetryFault;
- }
- }
- /*
- * If the page is not in memory (in the object) and
- * the object has a pager, we have to check if the
- * pager has the data in secondary storage.
- */
- if (!page_exists) {
-
- /*
- * If we don't allocate a (blank) page here...
- * another thread could try to page it in,
- * allocate a page, and then block on the busy
- * page in its shadow (first_object). Then
- * we'd trip over the busy page after we found
- * that the copy_object's pager doesn't have
- * the page...
- */
- copy_m = vm_page_alloc(copy_object, copy_offset, VM_ALLOC_NORMAL);
- if (copy_m == NULL) {
- /*
- * Wait for a page, then retry.
- */
- RELEASE_PAGE(m);
- copy_object->ref_count--;
- vm_object_unlock(copy_object);
- UNLOCK_AND_DEALLOCATE;
- VM_WAIT;
- goto RetryFault;
- }
- if (copy_object->pager != NULL) {
- vm_object_unlock(object);
- vm_object_unlock(copy_object);
- UNLOCK_MAP;
-
- page_exists = vm_pager_has_page(
- copy_object->pager,
- (copy_offset + copy_object->paging_offset));
-
- vm_object_lock(copy_object);
-
- /*
- * Since the map is unlocked, someone
- * else could have copied this object
- * and put a different copy_object
- * between the two. Or, the last
- * reference to the copy-object (other
- * than the one we have) may have
- * disappeared - if that has happened,
- * we don't need to make the copy.
- */
- if (copy_object->shadow != object ||
- copy_object->ref_count == 1) {
- /*
- * Gaah... start over!
- */
- FREE_PAGE(copy_m);
- vm_object_unlock(copy_object);
- vm_object_deallocate(copy_object);
- /* may block */
- vm_object_lock(object);
- goto RetryCopy;
- }
- vm_object_lock(object);
-
- if (page_exists) {
- /*
- * We didn't need the page
- */
- FREE_PAGE(copy_m);
- }
- }
- }
- if (!page_exists) {
- /*
- * Must copy page into copy-object.
- */
- vm_page_copy(m, copy_m);
- copy_m->valid = VM_PAGE_BITS_ALL;
-
- /*
- * Things to remember: 1. The copied page must
- * be marked 'dirty' so it will be paged out
- * to the copy object. 2. If the old page was
- * in use by any users of the copy-object, it
- * must be removed from all pmaps. (We can't
- * know which pmaps use it.)
- */
- vm_page_lock_queues();
-
- if ((old_m->flags & PG_ACTIVE) == 0)
- vm_page_activate(old_m);
-
- vm_page_protect(old_m, VM_PROT_NONE);
- copy_m->dirty = VM_PAGE_BITS_ALL;
- if ((copy_m->flags & PG_ACTIVE) == 0)
- vm_page_activate(copy_m);
- vm_page_unlock_queues();
-
- PAGE_WAKEUP(copy_m);
- }
- /*
- * The reference count on copy_object must be at least
- * 2: one for our extra reference, and at least one
- * from the outside world (we checked that when we
- * last locked copy_object).
- */
- copy_object->ref_count--;
- vm_object_unlock(copy_object);
- m->flags &= ~PG_COPYONWRITE;
- }
- }
-
- /*
* We must verify that the maps have not changed since our last
* lookup.
*/
@@ -754,10 +559,9 @@ RetryCopy:
* Since map entries may be pageable, make sure we can take a
* page fault on them.
*/
- vm_object_unlock(object);
/*
- * To avoid trying to write_lock the map while another thread
+ * To avoid trying to write_lock the map while another process
* has it read_locked (in vm_map_pageable), we do not try for
* write permission. If the page is still writable, we will
* get write permission. If it is not, or has been marked
@@ -767,8 +571,6 @@ RetryCopy:
result = vm_map_lookup(&map, vaddr, fault_type & ~VM_PROT_WRITE,
&entry, &retry_object, &retry_offset, &retry_prot, &wired, &su);
- vm_object_lock(object);
-
/*
* If we don't need the page any longer, put it on the active
* list (the easiest thing to do here). If no one needs it,
@@ -815,8 +617,6 @@ RetryCopy:
* once in each map for which it is wired.
*/
- vm_object_unlock(object);
-
/*
* Put this page into the physical map. We had to do the unlock above
* because pmap_enter may cause other faults. We don't put the page
@@ -849,8 +649,6 @@ RetryCopy:
* If the page is not wired down, then put it where the pageout daemon
* can find it.
*/
- vm_object_lock(object);
- vm_page_lock_queues();
if (change_wiring) {
if (wired)
vm_page_wire(m);
@@ -868,7 +666,6 @@ RetryCopy:
curproc->p_stats->p_ru.ru_minflt++;
}
}
- vm_page_unlock_queues();
/*
* Unlock everything, and return
@@ -948,8 +745,6 @@ vm_fault_unwire(map, start, end)
* mappings from the physical map system.
*/
- vm_page_lock_queues();
-
for (va = start; va < end; va += PAGE_SIZE) {
pa = pmap_extract(pmap, va);
if (pa == (vm_offset_t) 0) {
@@ -958,7 +753,6 @@ vm_fault_unwire(map, start, end)
pmap_change_wiring(pmap, va, FALSE);
vm_page_unwire(PHYS_TO_VM_PAGE(pa));
}
- vm_page_unlock_queues();
/*
* Inform the physical mapping system that the range of addresses may
@@ -1008,7 +802,7 @@ vm_fault_copy_entry(dst_map, src_map, dst_entry, src_entry)
* Create the top-level object for the destination entry. (Doesn't
* actually shadow anything - we copy the pages directly.)
*/
- dst_object = vm_object_allocate(
+ dst_object = vm_object_allocate(OBJT_DEFAULT,
(vm_size_t) (dst_entry->end - dst_entry->start));
dst_entry->object.vm_object = dst_object;
@@ -1028,13 +822,10 @@ vm_fault_copy_entry(dst_map, src_map, dst_entry, src_entry)
/*
* Allocate a page in the destination object
*/
- vm_object_lock(dst_object);
do {
dst_m = vm_page_alloc(dst_object, dst_offset, VM_ALLOC_NORMAL);
if (dst_m == NULL) {
- vm_object_unlock(dst_object);
VM_WAIT;
- vm_object_lock(dst_object);
}
} while (dst_m == NULL);
@@ -1043,7 +834,6 @@ vm_fault_copy_entry(dst_map, src_map, dst_entry, src_entry)
* (Because the source is wired down, the page will be in
* memory.)
*/
- vm_object_lock(src_object);
src_m = vm_page_lookup(src_object, dst_offset + src_offset);
if (src_m == NULL)
panic("vm_fault_copy_wired: page missing");
@@ -1053,8 +843,6 @@ vm_fault_copy_entry(dst_map, src_map, dst_entry, src_entry)
/*
* Enter it in the pmap...
*/
- vm_object_unlock(src_object);
- vm_object_unlock(dst_object);
dst_m->flags |= PG_WRITEABLE;
dst_m->flags |= PG_MAPPED;
@@ -1064,12 +852,8 @@ vm_fault_copy_entry(dst_map, src_map, dst_entry, src_entry)
/*
* Mark it no longer busy, and put it on the active list.
*/
- vm_object_lock(dst_object);
- vm_page_lock_queues();
vm_page_activate(dst_m);
- vm_page_unlock_queues();
PAGE_WAKEUP(dst_m);
- vm_object_unlock(dst_object);
}
}
@@ -1093,18 +877,16 @@ vm_fault_page_lookup(object, offset, rtobject, rtoffset, rtm)
*rtoffset = 0;
while (!(m = vm_page_lookup(object, offset))) {
- if (object->pager) {
- if (vm_pager_has_page(object->pager, object->paging_offset + offset)) {
- *rtobject = object;
- *rtoffset = offset;
- return 1;
- }
+ if (vm_pager_has_page(object, object->paging_offset + offset, NULL, NULL)) {
+ *rtobject = object;
+ *rtoffset = offset;
+ return 1;
}
- if (!object->shadow)
+ if (!object->backing_object)
return 0;
else {
- offset += object->shadow_offset;
- object = object->shadow;
+ offset += object->backing_object_offset;
+ object = object->backing_object;
}
}
*rtobject = object;
@@ -1155,7 +937,7 @@ vm_fault_additional_pages(first_object, first_offset, m, rbehind, raheada, marra
* if the requested page is not available, then give up now
*/
- if (!vm_pager_has_page(object->pager, object->paging_offset + offset))
+ if (!vm_pager_has_page(object, object->paging_offset + offset, NULL, NULL))
return 0;
/*
diff --git a/sys/vm/vm_glue.c b/sys/vm/vm_glue.c
index 90c5d7b..cd4feac 100644
--- a/sys/vm/vm_glue.c
+++ b/sys/vm/vm_glue.c
@@ -59,7 +59,7 @@
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*
- * $Id: vm_glue.c,v 1.21 1995/07/10 08:48:58 davidg Exp $
+ * $Id: vm_glue.c,v 1.22 1995/07/10 08:53:20 davidg Exp $
*/
#include <sys/param.h>
@@ -352,7 +352,7 @@ scheduler()
loop:
while ((cnt.v_free_count + cnt.v_cache_count) < (cnt.v_free_reserved + UPAGES + 2)) {
VM_WAIT;
- tsleep((caddr_t) &proc0, PVM, "schedm", 0);
+ tsleep(&proc0, PVM, "schedm", 0);
}
pp = NULL;
@@ -379,7 +379,7 @@ loop:
* Nothing to do, back to sleep
*/
if ((p = pp) == NULL) {
- tsleep((caddr_t) &proc0, PVM, "sched", 0);
+ tsleep(&proc0, PVM, "sched", 0);
goto loop;
}
/*
@@ -465,7 +465,7 @@ retry:
* then wakeup the sched process.
*/
if (didswap)
- wakeup((caddr_t) &proc0);
+ wakeup(&proc0);
}
void
@@ -505,56 +505,7 @@ swapout(p)
p->p_swtime = 0;
}
-/*
- * The rest of these routines fake thread handling
- */
-
-#ifndef assert_wait
-void
-assert_wait(event, ruptible)
- int event;
- boolean_t ruptible;
-{
-#ifdef lint
- ruptible++;
-#endif
- curproc->p_thread = event;
-}
-#endif
-
-void
-thread_block(char *msg)
-{
- if (curproc->p_thread)
- tsleep((caddr_t) curproc->p_thread, PVM, msg, 0);
-}
-
-
-void
-thread_sleep_(event, lock, wmesg)
- int event;
- simple_lock_t lock;
- char *wmesg;
-{
-
- curproc->p_thread = event;
- simple_unlock(lock);
- if (curproc->p_thread) {
- tsleep((caddr_t) event, PVM, wmesg, 0);
- }
-}
-
-#ifndef thread_wakeup
-void
-thread_wakeup(event)
- int event;
-{
- wakeup((caddr_t) event);
-}
-#endif
-
#ifdef DDB
-
/*
* DEBUG stuff
*/
diff --git a/sys/vm/vm_inherit.h b/sys/vm/vm_inherit.h
index ee212e1..29a213b 100644
--- a/sys/vm/vm_inherit.h
+++ b/sys/vm/vm_inherit.h
@@ -61,7 +61,7 @@
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*
- * $Id: vm_inherit.h,v 1.2 1994/08/02 07:55:20 davidg Exp $
+ * $Id: vm_inherit.h,v 1.3 1995/01/09 16:05:41 davidg Exp $
*/
/*
@@ -78,7 +78,6 @@
#define VM_INHERIT_SHARE ((vm_inherit_t) 0) /* share with child */
#define VM_INHERIT_COPY ((vm_inherit_t) 1) /* copy into child */
#define VM_INHERIT_NONE ((vm_inherit_t) 2) /* absent from child */
-#define VM_INHERIT_DONATE_COPY ((vm_inherit_t) 3) /* copy and delete */
#define VM_INHERIT_DEFAULT VM_INHERIT_COPY
diff --git a/sys/vm/vm_init.c b/sys/vm/vm_init.c
index 64f3814..51fcf30 100644
--- a/sys/vm/vm_init.c
+++ b/sys/vm/vm_init.c
@@ -61,7 +61,7 @@
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*
- * $Id: vm_init.c,v 1.5 1995/01/09 16:05:42 davidg Exp $
+ * $Id: vm_init.c,v 1.6 1995/03/16 18:17:11 bde Exp $
*/
/*
@@ -74,6 +74,7 @@
#include <vm/vm.h>
#include <vm/vm_page.h>
#include <vm/vm_kern.h>
+#include <vm/vm_pager.h>
/*
* vm_init initializes the virtual memory system.
diff --git a/sys/vm/vm_kern.c b/sys/vm/vm_kern.c
index 07b4c49..bf1b90f 100644
--- a/sys/vm/vm_kern.c
+++ b/sys/vm/vm_kern.c
@@ -61,7 +61,7 @@
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*
- * $Id: vm_kern.c,v 1.12 1995/03/15 07:52:06 davidg Exp $
+ * $Id: vm_kern.c,v 1.13 1995/05/30 08:16:04 rgrimes Exp $
*/
/*
@@ -176,20 +176,16 @@ kmem_alloc(map, size)
* race with page-out. vm_map_pageable will wire the pages.
*/
- vm_object_lock(kernel_object);
for (i = 0; i < size; i += PAGE_SIZE) {
vm_page_t mem;
while ((mem = vm_page_alloc(kernel_object, offset + i, VM_ALLOC_NORMAL)) == NULL) {
- vm_object_unlock(kernel_object);
VM_WAIT;
- vm_object_lock(kernel_object);
}
vm_page_zero_fill(mem);
mem->flags &= ~PG_BUSY;
mem->valid = VM_PAGE_BITS_ALL;
}
- vm_object_unlock(kernel_object);
/*
* And finally, mark the data as non-pageable.
@@ -332,7 +328,6 @@ kmem_malloc(map, size, waitflag)
* If we cannot wait then we must allocate all memory up front,
* pulling it off the active queue to prevent pageout.
*/
- vm_object_lock(kmem_object);
for (i = 0; i < size; i += PAGE_SIZE) {
m = vm_page_alloc(kmem_object, offset + i,
(waitflag == M_NOWAIT) ? VM_ALLOC_INTERRUPT : VM_ALLOC_SYSTEM);
@@ -348,7 +343,6 @@ kmem_malloc(map, size, waitflag)
m = vm_page_lookup(kmem_object, offset + i);
vm_page_free(m);
}
- vm_object_unlock(kmem_object);
vm_map_delete(map, addr, addr + size);
vm_map_unlock(map);
return (0);
@@ -359,7 +353,6 @@ kmem_malloc(map, size, waitflag)
m->flags &= ~PG_BUSY;
m->valid = VM_PAGE_BITS_ALL;
}
- vm_object_unlock(kmem_object);
/*
* Mark map entry as non-pageable. Assert: vm_map_insert() will never
@@ -379,9 +372,7 @@ kmem_malloc(map, size, waitflag)
* splimp...)
*/
for (i = 0; i < size; i += PAGE_SIZE) {
- vm_object_lock(kmem_object);
m = vm_page_lookup(kmem_object, offset + i);
- vm_object_unlock(kmem_object);
pmap_kenter(addr + i, VM_PAGE_TO_PHYS(m));
}
vm_map_unlock(map);
@@ -419,9 +410,8 @@ kmem_alloc_wait(map, size)
vm_map_unlock(map);
return (0);
}
- assert_wait((int) map, TRUE);
vm_map_unlock(map);
- thread_block("kmaw");
+ tsleep(map, PVM, "kmaw", 0);
}
vm_map_insert(map, NULL, (vm_offset_t) 0, addr, addr + size);
vm_map_unlock(map);
@@ -431,7 +421,7 @@ kmem_alloc_wait(map, size)
/*
* kmem_free_wakeup
*
- * Returns memory to a submap of the kernel, and wakes up any threads
+ * Returns memory to a submap of the kernel, and wakes up any processes
* waiting for memory in that map.
*/
void
@@ -442,7 +432,7 @@ kmem_free_wakeup(map, addr, size)
{
vm_map_lock(map);
(void) vm_map_delete(map, trunc_page(addr), round_page(addr + size));
- thread_wakeup((int) map);
+ wakeup(map);
vm_map_unlock(map);
}
diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c
index c87fe77..73e5611 100644
--- a/sys/vm/vm_map.c
+++ b/sys/vm/vm_map.c
@@ -61,7 +61,7 @@
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*
- * $Id: vm_map.c,v 1.21 1995/04/16 12:56:17 davidg Exp $
+ * $Id: vm_map.c,v 1.22 1995/05/30 08:16:07 rgrimes Exp $
*/
/*
@@ -77,6 +77,7 @@
#include <vm/vm_page.h>
#include <vm/vm_object.h>
#include <vm/vm_kern.h>
+#include <vm/vm_pager.h>
/*
* Virtual memory maps provide for the mapping, protection,
@@ -290,8 +291,6 @@ vm_map_init(map, min, max, pageable)
map->hint = &map->header;
map->timestamp = 0;
lock_init(&map->lock, TRUE);
- simple_lock_init(&map->ref_lock);
- simple_lock_init(&map->hint_lock);
}
/*
@@ -436,9 +435,7 @@ vm_map_reference(map)
if (map == NULL)
return;
- simple_lock(&map->ref_lock);
map->ref_count++;
- simple_unlock(&map->ref_lock);
}
/*
@@ -457,16 +454,14 @@ vm_map_deallocate(map)
if (map == NULL)
return;
- simple_lock(&map->ref_lock);
c = map->ref_count;
- simple_unlock(&map->ref_lock);
if (c == 0)
panic("vm_map_deallocate: deallocating already freed map");
if (c != 1) {
--map->ref_count;
- wakeup((caddr_t) &map->ref_count);
+ wakeup(&map->ref_count);
return;
}
/*
@@ -609,12 +604,10 @@ vm_map_insert(map, object, offset, start, end)
* SAVE_HINT:
*
* Saves the specified entry as the hint for
- * future lookups. Performs necessary interlocks.
+ * future lookups.
*/
#define SAVE_HINT(map,value) \
- simple_lock(&(map)->hint_lock); \
- (map)->hint = (value); \
- simple_unlock(&(map)->hint_lock);
+ (map)->hint = (value);
/*
* vm_map_lookup_entry: [ internal use only ]
@@ -639,9 +632,7 @@ vm_map_lookup_entry(map, address, entry)
* Start looking either from the head of the list, or from the hint.
*/
- simple_lock(&map->hint_lock);
cur = map->hint;
- simple_unlock(&map->hint_lock);
if (cur == &map->header)
cur = cur->next;
@@ -828,9 +819,7 @@ vm_map_simplify_entry(map, entry)
int count;
my_share_map = entry->object.share_map;
- simple_lock(&my_share_map->ref_lock);
count = my_share_map->ref_count;
- simple_unlock(&my_share_map->ref_lock);
if (count == 1) {
/*
@@ -1291,7 +1280,7 @@ vm_map_pageable(map, start, end, new_pageable)
* 1).
*
* Downgrading to a read lock for vm_fault_wire avoids a possible
- * deadlock with another thread that may have faulted on one
+ * deadlock with another process that may have faulted on one
* of the pages to be wired (it would mark the page busy,
* blocking us, then in turn block on the map lock that we
* hold). Because of problems in the recursive lock package,
@@ -1329,7 +1318,7 @@ vm_map_pageable(map, start, end, new_pageable)
entry->needs_copy = FALSE;
} else if (entry->object.vm_object == NULL) {
entry->object.vm_object =
- vm_object_allocate((vm_size_t) (entry->end
+ vm_object_allocate(OBJT_DEFAULT, (vm_size_t) (entry->end
- entry->start));
entry->offset = (vm_offset_t) 0;
}
@@ -1367,12 +1356,12 @@ vm_map_pageable(map, start, end, new_pageable)
/*
* HACK HACK HACK HACK
*
- * If we are wiring in the kernel map or a submap of it, unlock
- * the map to avoid deadlocks. We trust that the kernel
- * threads are well-behaved, and therefore will not do
- * anything destructive to this region of the map while we
- * have it unlocked. We cannot trust user threads to do the
- * same.
+ * If we are wiring in the kernel map or a submap of it,
+ * unlock the map to avoid deadlocks. We trust that the
+ * kernel is well-behaved, and therefore will not do
+ * anything destructive to this region of the map while
+ * we have it unlocked. We cannot trust user processes
+ * to do the same.
*
* HACK HACK HACK HACK
*/
@@ -1493,9 +1482,7 @@ vm_map_clean(map, start, end, syncio, invalidate)
} else {
object = current->object.vm_object;
}
- if (object && (object->pager != NULL) &&
- (object->pager->pg_type == PG_VNODE)) {
- vm_object_lock(object);
+ if (object && (object->type == OBJT_VNODE)) {
/*
* Flush pages if writing is allowed. XXX should we continue
* on an error?
@@ -1505,10 +1492,9 @@ vm_map_clean(map, start, end, syncio, invalidate)
* idea.
*/
if (current->protection & VM_PROT_WRITE)
- vm_object_page_clean(object, offset, offset + size, syncio);
+ vm_object_page_clean(object, offset, offset + size, syncio, TRUE);
if (invalidate)
vm_object_page_remove(object, offset, offset + size, FALSE);
- vm_object_unlock(object);
}
start += size;
}
@@ -1746,9 +1732,8 @@ vm_map_copy_entry(src_map, dst_map, src_entry, dst_entry)
if (src_entry->is_sub_map || dst_entry->is_sub_map)
return;
- if (dst_entry->object.vm_object != NULL &&
- (dst_entry->object.vm_object->flags & OBJ_INTERNAL) == 0)
- printf("vm_map_copy_entry: copying over permanent data!\n");
+ if (dst_entry->object.vm_object != NULL)
+ printf("vm_map_copy_entry: dst_entry object not NULL!\n");
/*
* If our destination map was wired down, unwire it now.
@@ -1788,9 +1773,7 @@ vm_map_copy_entry(src_map, dst_map, src_entry, dst_entry)
* just protect the virtual address range.
*/
if (!(su = src_map->is_main_map)) {
- simple_lock(&src_map->ref_lock);
su = (src_map->ref_count == 1);
- simple_unlock(&src_map->ref_lock);
}
if (su) {
pmap_protect(src_map->pmap,
@@ -1807,7 +1790,6 @@ vm_map_copy_entry(src_map, dst_map, src_entry, dst_entry)
/*
* Make a copy of the object.
*/
- temp_object = dst_entry->object.vm_object;
vm_object_copy(src_entry->object.vm_object,
src_entry->offset,
(vm_size_t) (src_entry->end -
@@ -1834,10 +1816,6 @@ vm_map_copy_entry(src_map, dst_map, src_entry, dst_entry)
*/
src_entry->copy_on_write = TRUE;
dst_entry->copy_on_write = TRUE;
- /*
- * Get rid of the old object.
- */
- vm_object_deallocate(temp_object);
pmap_copy(dst_map->pmap, src_map->pmap, dst_entry->start,
dst_entry->end - dst_entry->start, src_entry->start);
@@ -1852,292 +1830,6 @@ vm_map_copy_entry(src_map, dst_map, src_entry, dst_entry)
}
/*
- * vm_map_copy:
- *
- * Perform a virtual memory copy from the source
- * address map/range to the destination map/range.
- *
- * If src_destroy or dst_alloc is requested,
- * the source and destination regions should be
- * disjoint, not only in the top-level map, but
- * in the sharing maps as well. [The best way
- * to guarantee this is to use a new intermediate
- * map to make copies. This also reduces map
- * fragmentation.]
- */
-int
-vm_map_copy(dst_map, src_map,
- dst_addr, len, src_addr,
- dst_alloc, src_destroy)
- vm_map_t dst_map;
- vm_map_t src_map;
- vm_offset_t dst_addr;
- vm_size_t len;
- vm_offset_t src_addr;
- boolean_t dst_alloc;
- boolean_t src_destroy;
-{
- register
- vm_map_entry_t src_entry;
- register
- vm_map_entry_t dst_entry;
- vm_map_entry_t tmp_entry;
- vm_offset_t src_start;
- vm_offset_t src_end;
- vm_offset_t dst_start;
- vm_offset_t dst_end;
- vm_offset_t src_clip;
- vm_offset_t dst_clip;
- int result;
- boolean_t old_src_destroy;
-
- /*
- * XXX While we figure out why src_destroy screws up, we'll do it by
- * explicitly vm_map_delete'ing at the end.
- */
-
- old_src_destroy = src_destroy;
- src_destroy = FALSE;
-
- /*
- * Compute start and end of region in both maps
- */
-
- src_start = src_addr;
- src_end = src_start + len;
- dst_start = dst_addr;
- dst_end = dst_start + len;
-
- /*
- * Check that the region can exist in both source and destination.
- */
-
- if ((dst_end < dst_start) || (src_end < src_start))
- return (KERN_NO_SPACE);
-
- /*
- * Lock the maps in question -- we avoid deadlock by ordering lock
- * acquisition by map value
- */
-
- if (src_map == dst_map) {
- vm_map_lock(src_map);
- } else if ((int) src_map < (int) dst_map) {
- vm_map_lock(src_map);
- vm_map_lock(dst_map);
- } else {
- vm_map_lock(dst_map);
- vm_map_lock(src_map);
- }
-
- result = KERN_SUCCESS;
-
- /*
- * Check protections... source must be completely readable and
- * destination must be completely writable. [Note that if we're
- * allocating the destination region, we don't have to worry about
- * protection, but instead about whether the region exists.]
- */
-
- if (src_map->is_main_map && dst_map->is_main_map) {
- if (!vm_map_check_protection(src_map, src_start, src_end,
- VM_PROT_READ)) {
- result = KERN_PROTECTION_FAILURE;
- goto Return;
- }
- if (dst_alloc) {
- /* XXX Consider making this a vm_map_find instead */
- if ((result = vm_map_insert(dst_map, NULL,
- (vm_offset_t) 0, dst_start, dst_end)) != KERN_SUCCESS)
- goto Return;
- } else if (!vm_map_check_protection(dst_map, dst_start, dst_end,
- VM_PROT_WRITE)) {
- result = KERN_PROTECTION_FAILURE;
- goto Return;
- }
- }
- /*
- * Find the start entries and clip.
- *
- * Note that checking protection asserts that the lookup cannot fail.
- *
- * Also note that we wait to do the second lookup until we have done the
- * first clip, as the clip may affect which entry we get!
- */
-
- (void) vm_map_lookup_entry(src_map, src_addr, &tmp_entry);
- src_entry = tmp_entry;
- vm_map_clip_start(src_map, src_entry, src_start);
-
- (void) vm_map_lookup_entry(dst_map, dst_addr, &tmp_entry);
- dst_entry = tmp_entry;
- vm_map_clip_start(dst_map, dst_entry, dst_start);
-
- /*
- * If both source and destination entries are the same, retry the
- * first lookup, as it may have changed.
- */
-
- if (src_entry == dst_entry) {
- (void) vm_map_lookup_entry(src_map, src_addr, &tmp_entry);
- src_entry = tmp_entry;
- }
- /*
- * If source and destination entries are still the same, a null copy
- * is being performed.
- */
-
- if (src_entry == dst_entry)
- goto Return;
-
- /*
- * Go through entries until we get to the end of the region.
- */
-
- while (src_start < src_end) {
- /*
- * Clip the entries to the endpoint of the entire region.
- */
-
- vm_map_clip_end(src_map, src_entry, src_end);
- vm_map_clip_end(dst_map, dst_entry, dst_end);
-
- /*
- * Clip each entry to the endpoint of the other entry.
- */
-
- src_clip = src_entry->start + (dst_entry->end - dst_entry->start);
- vm_map_clip_end(src_map, src_entry, src_clip);
-
- dst_clip = dst_entry->start + (src_entry->end - src_entry->start);
- vm_map_clip_end(dst_map, dst_entry, dst_clip);
-
- /*
- * Both entries now match in size and relative endpoints.
- *
- * If both entries refer to a VM object, we can deal with them
- * now.
- */
-
- if (!src_entry->is_a_map && !dst_entry->is_a_map) {
- vm_map_copy_entry(src_map, dst_map, src_entry,
- dst_entry);
- } else {
- register vm_map_t new_dst_map;
- vm_offset_t new_dst_start;
- vm_size_t new_size;
- vm_map_t new_src_map;
- vm_offset_t new_src_start;
-
- /*
- * We have to follow at least one sharing map.
- */
-
- new_size = (dst_entry->end - dst_entry->start);
-
- if (src_entry->is_a_map) {
- new_src_map = src_entry->object.share_map;
- new_src_start = src_entry->offset;
- } else {
- new_src_map = src_map;
- new_src_start = src_entry->start;
- lock_set_recursive(&src_map->lock);
- }
-
- if (dst_entry->is_a_map) {
- vm_offset_t new_dst_end;
-
- new_dst_map = dst_entry->object.share_map;
- new_dst_start = dst_entry->offset;
-
- /*
- * Since the destination sharing entries will
- * be merely deallocated, we can do that now,
- * and replace the region with a null object.
- * [This prevents splitting the source map to
- * match the form of the destination map.]
- * Note that we can only do so if the source
- * and destination do not overlap.
- */
-
- new_dst_end = new_dst_start + new_size;
-
- if (new_dst_map != new_src_map) {
- vm_map_lock(new_dst_map);
- (void) vm_map_delete(new_dst_map,
- new_dst_start,
- new_dst_end);
- (void) vm_map_insert(new_dst_map,
- NULL,
- (vm_offset_t) 0,
- new_dst_start,
- new_dst_end);
- vm_map_unlock(new_dst_map);
- }
- } else {
- new_dst_map = dst_map;
- new_dst_start = dst_entry->start;
- lock_set_recursive(&dst_map->lock);
- }
-
- /*
- * Recursively copy the sharing map.
- */
-
- (void) vm_map_copy(new_dst_map, new_src_map,
- new_dst_start, new_size, new_src_start,
- FALSE, FALSE);
-
- if (dst_map == new_dst_map)
- lock_clear_recursive(&dst_map->lock);
- if (src_map == new_src_map)
- lock_clear_recursive(&src_map->lock);
- }
-
- /*
- * Update variables for next pass through the loop.
- */
-
- src_start = src_entry->end;
- src_entry = src_entry->next;
- dst_start = dst_entry->end;
- dst_entry = dst_entry->next;
-
- /*
- * If the source is to be destroyed, here is the place to do
- * it.
- */
-
- if (src_destroy && src_map->is_main_map &&
- dst_map->is_main_map)
- vm_map_entry_delete(src_map, src_entry->prev);
- }
-
- /*
- * Update the physical maps as appropriate
- */
-
- if (src_map->is_main_map && dst_map->is_main_map) {
- if (src_destroy)
- pmap_remove(src_map->pmap, src_addr, src_addr + len);
- }
- /*
- * Unlock the maps
- */
-
-Return:;
-
- if (old_src_destroy)
- vm_map_delete(src_map, src_addr, src_addr + len);
-
- vm_map_unlock(src_map);
- if (src_map != dst_map)
- vm_map_unlock(dst_map);
-
- return (result);
-}
-
-/*
* vmspace_fork:
* Create a new process vmspace structure and vm_map
* based on those of an existing process. The new map
@@ -2178,58 +1870,12 @@ vmspace_fork(vm1)
case VM_INHERIT_SHARE:
/*
- * If we don't already have a sharing map:
- */
-
- if (!old_entry->is_a_map) {
- vm_map_t new_share_map;
- vm_map_entry_t new_share_entry;
-
- /*
- * Create a new sharing map
- */
-
- new_share_map = vm_map_create(NULL,
- old_entry->start,
- old_entry->end,
- TRUE);
- new_share_map->is_main_map = FALSE;
-
- /*
- * Create the only sharing entry from the old
- * task map entry.
- */
-
- new_share_entry =
- vm_map_entry_create(new_share_map);
- *new_share_entry = *old_entry;
- new_share_entry->wired_count = 0;
-
- /*
- * Insert the entry into the new sharing map
- */
-
- vm_map_entry_link(new_share_map,
- new_share_map->header.prev,
- new_share_entry);
-
- /*
- * Fix up the task map entry to refer to the
- * sharing map now.
- */
-
- old_entry->is_a_map = TRUE;
- old_entry->object.share_map = new_share_map;
- old_entry->offset = old_entry->start;
- }
- /*
* Clone the entry, referencing the sharing map.
*/
-
new_entry = vm_map_entry_create(new_map);
*new_entry = *old_entry;
new_entry->wired_count = 0;
- vm_map_reference(new_entry->object.share_map);
+ ++new_entry->object.vm_object->ref_count;
/*
* Insert the entry into the new map -- we know we're
@@ -2261,22 +1907,7 @@ vmspace_fork(vm1)
new_entry->is_a_map = FALSE;
vm_map_entry_link(new_map, new_map->header.prev,
new_entry);
- if (old_entry->is_a_map) {
- int check;
-
- check = vm_map_copy(new_map,
- old_entry->object.share_map,
- new_entry->start,
- (vm_size_t) (new_entry->end -
- new_entry->start),
- old_entry->offset,
- FALSE, FALSE);
- if (check != KERN_SUCCESS)
- printf("vm_map_fork: copy in share_map region failed\n");
- } else {
- vm_map_copy_entry(old_map, new_map, old_entry,
- new_entry);
- }
+ vm_map_copy_entry(old_map, new_map, old_entry, new_entry);
break;
}
old_entry = old_entry->next;
@@ -2350,9 +1981,7 @@ RetryLookup:;
* blown lookup routine.
*/
- simple_lock(&map->hint_lock);
entry = map->hint;
- simple_unlock(&map->hint_lock);
*out_entry = entry;
@@ -2483,7 +2112,7 @@ RetryLookup:;
vm_map_unlock_read(map);
goto RetryLookup;
}
- entry->object.vm_object = vm_object_allocate(
+ entry->object.vm_object = vm_object_allocate(OBJT_DEFAULT,
(vm_size_t) (entry->end - entry->start));
entry->offset = 0;
lock_write_to_read(&share_map->lock);
@@ -2501,9 +2130,7 @@ RetryLookup:;
*/
if (!su) {
- simple_lock(&share_map->ref_lock);
su = (share_map->ref_count == 1);
- simple_unlock(&share_map->ref_lock);
}
*out_prot = prot;
*single_use = su;
diff --git a/sys/vm/vm_map.h b/sys/vm/vm_map.h
index f250144..98ecb7e 100644
--- a/sys/vm/vm_map.h
+++ b/sys/vm/vm_map.h
@@ -61,7 +61,7 @@
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*
- * $Id: vm_map.h,v 1.4 1995/01/09 16:05:46 davidg Exp $
+ * $Id: vm_map.h,v 1.5 1995/03/16 18:17:17 bde Exp $
*/
/*
@@ -130,9 +130,7 @@ struct vm_map {
vm_size_t size; /* virtual size */
boolean_t is_main_map; /* Am I a main map? */
int ref_count; /* Reference count */
- simple_lock_data_t ref_lock; /* Lock for ref_count field */
vm_map_entry_t hint; /* hint for quick lookups */
- simple_lock_data_t hint_lock; /* lock for hint storage */
vm_map_entry_t first_free; /* First free space hint */
boolean_t entries_pageable; /* map entries pageable?? */
unsigned int timestamp; /* Version number */
diff --git a/sys/vm/vm_meter.c b/sys/vm/vm_meter.c
index bf65f8c..d85f5db 100644
--- a/sys/vm/vm_meter.c
+++ b/sys/vm/vm_meter.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)vm_meter.c 8.4 (Berkeley) 1/4/94
- * $Id: vm_meter.c,v 1.5 1995/01/09 16:05:47 davidg Exp $
+ * $Id: vm_meter.c,v 1.6 1995/01/10 07:32:47 davidg Exp $
*/
#include <sys/param.h>
@@ -45,16 +45,6 @@ struct loadavg averunnable; /* load average, of runnable procs */
int maxslp = MAXSLP;
-void
-vmmeter()
-{
-
- if (time.tv_sec % 5 == 0)
- loadav(&averunnable);
- if (proc0.p_slptime > maxslp / 2)
- wakeup((caddr_t) &proc0);
-}
-
/*
* Constants for averages over 1, 5, and 15 minutes
* when sampling at 5 second intervals.
@@ -69,7 +59,7 @@ fixpt_t cexp[3] = {
* Compute a tenex style load average of a quantity on
* 1, 5 and 15 minute intervals.
*/
-void
+static void
loadav(avg)
register struct loadavg *avg;
{
@@ -92,6 +82,16 @@ loadav(avg)
nrun * FSCALE * (FSCALE - cexp[i])) >> FSHIFT;
}
+void
+vmmeter()
+{
+
+ if (time.tv_sec % 5 == 0)
+ loadav(&averunnable);
+ if (proc0.p_slptime > maxslp / 2)
+ wakeup(&proc0);
+}
+
/*
* Attributes associated with virtual memory.
*/
@@ -159,12 +159,10 @@ vmtotal(totalp)
/*
* Mark all objects as inactive.
*/
- simple_lock(&vm_object_list_lock);
for (object = vm_object_list.tqh_first;
object != NULL;
object = object->object_list.tqe_next)
object->flags &= ~OBJ_ACTIVE;
- simple_unlock(&vm_object_list_lock);
/*
* Calculate process statistics.
*/
@@ -216,7 +214,6 @@ vmtotal(totalp)
/*
* Calculate object memory usage statistics.
*/
- simple_lock(&vm_object_list_lock);
for (object = vm_object_list.tqh_first;
object != NULL;
object = object->object_list.tqe_next) {
diff --git a/sys/vm/vm_mmap.c b/sys/vm/vm_mmap.c
index 106b62b..3beba3c 100644
--- a/sys/vm/vm_mmap.c
+++ b/sys/vm/vm_mmap.c
@@ -38,7 +38,7 @@
* from: Utah $Hdr: vm_mmap.c 1.6 91/10/21$
*
* @(#)vm_mmap.c 8.4 (Berkeley) 1/12/94
- * $Id: vm_mmap.c,v 1.24 1995/05/30 08:16:09 rgrimes Exp $
+ * $Id: vm_mmap.c,v 1.25 1995/07/09 06:58:01 davidg Exp $
*/
/*
@@ -62,14 +62,6 @@
#include <vm/vm_pageout.h>
#include <vm/vm_prot.h>
-#ifdef DEBUG
-int mmapdebug;
-
-#define MDB_FOLLOW 0x01
-#define MDB_SYNC 0x02
-#define MDB_MAPIT 0x04
-#endif
-
void pmap_object_init_pt();
struct sbrk_args {
@@ -149,12 +141,6 @@ mmap(p, uap, retval)
prot = uap->prot & VM_PROT_ALL;
flags = uap->flags;
-#ifdef DEBUG
- if (mmapdebug & MDB_FOLLOW)
- printf("mmap(%d): addr %x len %x pro %x flg %x fd %d pos %x\n",
- p->p_pid, uap->addr, uap->len, prot,
- flags, uap->fd, (vm_offset_t) uap->pos);
-#endif
/*
* Address (if FIXED) must be page aligned. Size is implicitly rounded
* to a page boundary.
@@ -318,12 +304,6 @@ msync(p, uap, retval)
vm_map_t map;
int rv;
-#ifdef DEBUG
- if (mmapdebug & (MDB_FOLLOW | MDB_SYNC))
- printf("msync(%d): addr %x len %x\n",
- p->p_pid, uap->addr, uap->len);
-#endif
-
map = &p->p_vmspace->vm_map;
addr = (vm_offset_t) uap->addr;
size = (vm_size_t) uap->len;
@@ -352,12 +332,6 @@ msync(p, uap, retval)
size = entry->end - entry->start;
}
-#ifdef DEBUG
- if (mmapdebug & MDB_SYNC)
- printf("msync: cleaning/flushing address range [%x-%x)\n",
- addr, addr + size);
-#endif
-
/*
* Clean the pages and interpret the return value.
*/
@@ -392,12 +366,6 @@ munmap(p, uap, retval)
vm_size_t size;
vm_map_t map;
-#ifdef DEBUG
- if (mmapdebug & MDB_FOLLOW)
- printf("munmap(%d): addr %x len %x\n",
- p->p_pid, uap->addr, uap->len);
-#endif
-
addr = (vm_offset_t) uap->addr;
if ((addr & PAGE_MASK) || uap->len < 0)
return (EINVAL);
@@ -432,11 +400,6 @@ munmapfd(p, fd)
struct proc *p;
int fd;
{
-#ifdef DEBUG
- if (mmapdebug & MDB_FOLLOW)
- printf("munmapfd(%d): fd %d\n", p->p_pid, fd);
-#endif
-
/*
* XXX should unmap any regions mapped to this file
*/
@@ -458,12 +421,6 @@ mprotect(p, uap, retval)
vm_size_t size;
register vm_prot_t prot;
-#ifdef DEBUG
- if (mmapdebug & MDB_FOLLOW)
- printf("mprotect(%d): addr %x len %x prot %d\n",
- p->p_pid, uap->addr, uap->len, uap->prot);
-#endif
-
addr = (vm_offset_t) uap->addr;
if ((addr & PAGE_MASK) || uap->len < 0)
return (EINVAL);
@@ -530,11 +487,6 @@ mlock(p, uap, retval)
vm_size_t size;
int error;
-#ifdef DEBUG
- if (mmapdebug & MDB_FOLLOW)
- printf("mlock(%d): addr %x len %x\n",
- p->p_pid, uap->addr, uap->len);
-#endif
addr = (vm_offset_t) uap->addr;
if ((addr & PAGE_MASK) || uap->addr + uap->len < uap->addr)
return (EINVAL);
@@ -569,11 +521,6 @@ munlock(p, uap, retval)
vm_size_t size;
int error;
-#ifdef DEBUG
- if (mmapdebug & MDB_FOLLOW)
- printf("munlock(%d): addr %x len %x\n",
- p->p_pid, uap->addr, uap->len);
-#endif
addr = (vm_offset_t) uap->addr;
if ((addr & PAGE_MASK) || uap->addr + uap->len < uap->addr)
return (EINVAL);
@@ -603,11 +550,10 @@ vm_mmap(map, addr, size, prot, maxprot, flags, handle, foff)
caddr_t handle; /* XXX should be vp */
vm_offset_t foff;
{
- register vm_pager_t pager;
boolean_t fitit;
vm_object_t object;
struct vnode *vp = NULL;
- int type;
+ objtype_t type;
int rv = KERN_SUCCESS;
vm_size_t objsize;
struct proc *p = curproc;
@@ -639,12 +585,10 @@ vm_mmap(map, addr, size, prot, maxprot, flags, handle, foff)
}
/*
- * Lookup/allocate pager. All except an unnamed anonymous lookup gain
- * a reference to ensure continued existance of the object. (XXX the
- * exception is to appease the pageout daemon)
+ * Lookup/allocate object.
*/
if (flags & MAP_ANON) {
- type = PG_DFLT;
+ type = OBJT_SWAP;
/*
* Unnamed anonymous regions always start at 0.
*/
@@ -653,7 +597,7 @@ vm_mmap(map, addr, size, prot, maxprot, flags, handle, foff)
} else {
vp = (struct vnode *) handle;
if (vp->v_type == VCHR) {
- type = PG_DEVICE;
+ type = OBJT_DEVICE;
handle = (caddr_t) vp->v_rdev;
} else {
struct vattr vat;
@@ -663,45 +607,23 @@ vm_mmap(map, addr, size, prot, maxprot, flags, handle, foff)
if (error)
return (error);
objsize = vat.va_size;
- type = PG_VNODE;
+ type = OBJT_VNODE;
}
}
- pager = vm_pager_allocate(type, handle, objsize, prot, foff);
- if (pager == NULL)
- return (type == PG_DEVICE ? EINVAL : ENOMEM);
- /*
- * Guarantee that the pager has an object.
- */
- object = vm_object_lookup(pager);
- if (object == NULL) {
- if (handle != NULL)
- panic("vm_mmap: pager didn't allocate an object (and should have)");
- /*
- * Should only happen for unnamed anonymous regions.
- */
- object = vm_object_allocate(size);
- object->pager = pager;
- } else {
- /*
- * Lose vm_object_lookup() reference. Retain reference
- * gained by vm_pager_allocate().
- */
- vm_object_deallocate(object);
- }
- /*
- * At this point, our actions above have gained a total of
- * one reference to the object, and we have a pager.
- */
+ object = vm_pager_allocate(type, handle, objsize, prot, foff);
+ if (object == NULL)
+ return (type == OBJT_DEVICE ? EINVAL : ENOMEM);
/*
* Anonymous memory, shared file, or character special file.
*/
- if ((flags & (MAP_ANON|MAP_SHARED)) || (type == PG_DEVICE)) {
+ if ((flags & (MAP_ANON|MAP_SHARED)) || (type == OBJT_DEVICE)) {
rv = vm_map_find(map, object, foff, addr, size, fitit);
if (rv != KERN_SUCCESS) {
/*
- * Lose the object reference. This will also destroy
- * the pager if there are no other references.
+ * Lose the object reference. Will destroy the
+ * object if it's an unnamed anonymous mapping
+ * or named anonymous without other references.
*/
vm_object_deallocate(object);
goto out;
@@ -711,76 +633,31 @@ vm_mmap(map, addr, size, prot, maxprot, flags, handle, foff)
* mmap a COW regular file
*/
else {
- vm_map_t tmap;
- vm_offset_t off;
vm_map_entry_t entry;
+ vm_object_t private_object;
- if (flags & MAP_COPY) {
- /* locate and allocate the target address space */
- rv = vm_map_find(map, NULL, 0, addr, size, fitit);
- if (rv != KERN_SUCCESS) {
- vm_object_deallocate(object);
- goto out;
- }
-
- off = VM_MIN_ADDRESS;
- tmap = vm_map_create(NULL, off, off + size, TRUE);
- rv = vm_map_find(tmap, object, foff, &off, size, FALSE);
- if (rv != KERN_SUCCESS) {
- /*
- * Deallocate and delete the temporary map.
- * Note that since the object insertion
- * above has failed, the vm_map_deallocate
- * doesn't lose the object reference - we
- * must do it explicitly.
- */
- vm_object_deallocate(object);
- vm_map_deallocate(tmap);
- goto out;
- }
- rv = vm_map_copy(map, tmap, *addr, size, off,
- FALSE, FALSE);
- /*
- * Deallocate temporary map. XXX - depending
- * on events, this may leave the object with
- * no net gain in reference count! ...this
- * needs to be looked at!
- */
- vm_map_deallocate(tmap);
- if (rv != KERN_SUCCESS)
- goto out;
-
- } else {
- vm_object_t user_object;
-
- /*
- * Create a new object and make the original object
- * the backing object. NOTE: the object reference gained
- * above is now changed into the reference held by
- * user_object. Since we don't map 'object', we want
- * only this one reference.
- */
- user_object = vm_object_allocate(object->size);
- user_object->shadow = object;
- TAILQ_INSERT_TAIL(&object->reverse_shadow_head,
- user_object, reverse_shadow_list);
-
- rv = vm_map_find(map, user_object, foff, addr, size, fitit);
- if( rv != KERN_SUCCESS) {
- vm_object_deallocate(user_object);
- goto out;
- }
+ /*
+ * Create a new object and make the original object
+ * the backing object. NOTE: the object reference gained
+ * above is now changed into the reference held by
+ * private_object. Since we don't map 'object', we want
+ * only this one reference.
+ */
+ private_object = vm_object_allocate(OBJT_DEFAULT, object->size);
+ private_object->backing_object = object;
+ TAILQ_INSERT_TAIL(&object->shadow_head,
+ private_object, shadow_list);
- /*
- * this is a consistancy check, gets the map entry, and should
- * never fail
- */
- if (!vm_map_lookup_entry(map, *addr, &entry)) {
- panic("vm_mmap: missing map entry!!!");
- }
+ rv = vm_map_find(map, private_object, foff, addr, size, fitit);
+ if (rv != KERN_SUCCESS) {
+ vm_object_deallocate(private_object);
+ goto out;
+ }
- entry->copy_on_write = TRUE;
+ if (!vm_map_lookup_entry(map, *addr, &entry)) {
+ panic("vm_mmap: missing map entry!!!");
}
+ entry->copy_on_write = TRUE;
/*
* set pages COW and protect for read access only
@@ -792,7 +669,7 @@ vm_mmap(map, addr, size, prot, maxprot, flags, handle, foff)
/*
* "Pre-fault" resident pages.
*/
- if ((type == PG_VNODE) && (map->pmap != NULL)) {
+ if ((type == OBJT_VNODE) && (map->pmap != NULL)) {
pmap_object_init_pt(map->pmap, *addr, object, foff, size);
}
@@ -820,10 +697,6 @@ vm_mmap(map, addr, size, prot, maxprot, flags, handle, foff)
}
}
out:
-#ifdef DEBUG
- if (mmapdebug & MDB_MAPIT)
- printf("vm_mmap: rv %d\n", rv);
-#endif
switch (rv) {
case KERN_SUCCESS:
return (0);
diff --git a/sys/vm/vm_object.c b/sys/vm/vm_object.c
index 3c601b4..834f28c 100644
--- a/sys/vm/vm_object.c
+++ b/sys/vm/vm_object.c
@@ -61,7 +61,7 @@
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*
- * $Id: vm_object.c,v 1.47.2.1 1995/06/04 13:53:25 davidg Exp $
+ * $Id: vm_object.c,v 1.48 1995/06/11 19:31:53 rgrimes Exp $
*/
/*
@@ -81,10 +81,9 @@
#include <vm/vm_pageout.h>
#include <vm/vm_pager.h>
#include <vm/swap_pager.h>
-#include <vm/vnode_pager.h>
#include <vm/vm_kern.h>
-static void _vm_object_allocate(vm_size_t, vm_object_t);
+static void _vm_object_allocate(objtype_t, vm_size_t, vm_object_t);
/*
@@ -119,41 +118,34 @@ struct vm_object kmem_object_store;
int vm_object_cache_max;
-#define VM_OBJECT_HASH_COUNT 1021
-
-struct vm_object_hash_head vm_object_hashtable[VM_OBJECT_HASH_COUNT];
-#define OBJECT_HASH(pager) ((unsigned long)(pager) % VM_OBJECT_HASH_COUNT)
-
long object_collapses;
long object_bypasses;
static void
-_vm_object_allocate(size, object)
+_vm_object_allocate(type, size, object)
+ objtype_t type;
vm_size_t size;
register vm_object_t object;
{
TAILQ_INIT(&object->memq);
- TAILQ_INIT(&object->reverse_shadow_head);
+ TAILQ_INIT(&object->shadow_head);
+ object->type = type;
object->size = size;
object->ref_count = 1;
- vm_object_lock_init(object);
- object->flags = OBJ_INTERNAL; /* pager will reset */
+ object->flags = 0;
object->paging_in_progress = 0;
object->resident_page_count = 0;
-
- object->pager = NULL;
+ object->pg_data = NULL;
+ object->handle = NULL;
object->paging_offset = 0;
- object->shadow = NULL;
- object->shadow_offset = (vm_offset_t) 0;
- object->copy = NULL;
+ object->backing_object = NULL;
+ object->backing_object_offset = (vm_offset_t) 0;
object->last_read = 0;
- simple_lock(&vm_object_list_lock);
TAILQ_INSERT_TAIL(&vm_object_list, object, object_list);
vm_object_count++;
- simple_unlock(&vm_object_list_lock);
}
/*
@@ -169,22 +161,17 @@ vm_object_init(vm_offset_t nothing)
TAILQ_INIT(&vm_object_cached_list);
TAILQ_INIT(&vm_object_list);
vm_object_count = 0;
- simple_lock_init(&vm_cache_lock);
- simple_lock_init(&vm_object_list_lock);
-
+
vm_object_cache_max = 84;
if (cnt.v_page_count > 1000)
vm_object_cache_max += (cnt.v_page_count - 1000) / 4;
- for (i = 0; i < VM_OBJECT_HASH_COUNT; i++)
- LIST_INIT(&vm_object_hashtable[i]);
-
kernel_object = &kernel_object_store;
- _vm_object_allocate(VM_MAX_KERNEL_ADDRESS - VM_MIN_KERNEL_ADDRESS,
+ _vm_object_allocate(OBJT_DEFAULT, VM_MAX_KERNEL_ADDRESS - VM_MIN_KERNEL_ADDRESS,
kernel_object);
kmem_object = &kmem_object_store;
- _vm_object_allocate(VM_MAX_KERNEL_ADDRESS - VM_MIN_KERNEL_ADDRESS,
+ _vm_object_allocate(OBJT_DEFAULT, VM_MAX_KERNEL_ADDRESS - VM_MIN_KERNEL_ADDRESS,
kmem_object);
}
@@ -195,7 +182,8 @@ vm_object_init(vm_offset_t nothing)
*/
vm_object_t
-vm_object_allocate(size)
+vm_object_allocate(type, size)
+ objtype_t type;
vm_size_t size;
{
register vm_object_t result;
@@ -204,7 +192,7 @@ vm_object_allocate(size)
malloc((u_long) sizeof *result, M_VMOBJ, M_WAITOK);
- _vm_object_allocate(size, result);
+ _vm_object_allocate(type, size, result);
return (result);
}
@@ -222,9 +210,13 @@ vm_object_reference(object)
if (object == NULL)
return;
- vm_object_lock(object);
+ if (object->ref_count == 0) {
+ if ((object->flags & OBJ_CANPERSIST) == 0)
+ panic("vm_object_reference: non-persistent object with 0 ref_count");
+ TAILQ_REMOVE(&vm_object_cached_list, object, cached_list);
+ vm_object_cached--;
+ }
object->ref_count++;
- vm_object_unlock(object);
}
/*
@@ -243,7 +235,6 @@ vm_object_deallocate(object)
vm_object_t object;
{
vm_object_t temp;
- vm_pager_t pager;
while (object != NULL) {
@@ -251,26 +242,21 @@ vm_object_deallocate(object)
panic("vm_object_deallocate: object deallocated too many times");
/*
- * The cache holds a reference (uncounted) to the object; we
- * must lock it before removing the object.
- */
-
- vm_object_cache_lock();
-
- /*
* Lose the reference
*/
- vm_object_lock(object);
-
object->ref_count--;
if (object->ref_count != 0) {
if ((object->ref_count == 1) &&
- (object->flags & OBJ_INTERNAL)) {
+ (object->handle == NULL) &&
+ (object->type == OBJT_DEFAULT ||
+ object->type == OBJT_SWAP)) {
vm_object_t robject;
- robject = object->reverse_shadow_head.tqh_first;
+ robject = object->shadow_head.tqh_first;
if ((robject != NULL) &&
- (robject->flags & OBJ_INTERNAL)) {
+ (robject->handle == NULL) &&
+ (robject->type == OBJT_DEFAULT ||
+ robject->type == OBJT_SWAP)) {
int s;
robject->ref_count += 2;
object->ref_count += 2;
@@ -293,33 +279,24 @@ vm_object_deallocate(object)
object->ref_count -= 2;
robject->ref_count -= 2;
if( robject->ref_count == 0) {
- vm_object_unlock(object);
- vm_object_cache_unlock();
robject->ref_count += 1;
object = robject;
continue;
}
- vm_object_cache_unlock();
- vm_object_unlock(object);
- vm_object_lock(robject);
vm_object_collapse(robject);
return;
}
}
- vm_object_unlock(object);
/*
* If there are still references, then we are done.
*/
- vm_object_cache_unlock();
return;
}
- pager = object->pager;
-
- if (pager && pager->pg_type == PG_VNODE) {
- vn_pager_t vnp = (vn_pager_t) pager->pg_data;
+ if (object->type == OBJT_VNODE) {
+ struct vnode *vp = object->handle;
- vnp->vnp_vp->v_flag &= ~VTEXT;
+ vp->v_flag &= ~VTEXT;
}
/*
@@ -328,13 +305,10 @@ vm_object_deallocate(object)
*/
if (object->flags & OBJ_CANPERSIST) {
if (object->resident_page_count != 0) {
- vm_object_page_clean(object, 0, 0 ,TRUE);
+ vm_object_page_clean(object, 0, 0 ,TRUE, TRUE);
TAILQ_INSERT_TAIL(&vm_object_cached_list, object,
cached_list);
vm_object_cached++;
- vm_object_cache_unlock();
-
- vm_object_unlock(object);
vm_object_cache_trim();
return;
@@ -344,16 +318,13 @@ vm_object_deallocate(object)
}
/*
- * Make sure no one can look us up now.
+ * Make sure no one uses us.
*/
object->flags |= OBJ_DEAD;
- if ((object->flags & OBJ_INTERNAL) == 0)
- vm_object_remove(pager);
- vm_object_cache_unlock();
- temp = object->shadow;
+ temp = object->backing_object;
if (temp)
- TAILQ_REMOVE(&temp->reverse_shadow_head, object, reverse_shadow_list);
+ TAILQ_REMOVE(&temp->shadow_head, object, shadow_list);
vm_object_terminate(object);
/* unlocks and deallocates object */
object = temp;
@@ -371,28 +342,16 @@ vm_object_terminate(object)
register vm_object_t object;
{
register vm_page_t p, next;
- vm_object_t shadow_object;
+ vm_object_t backing_object;
int s;
/*
- * Detach the object from its shadow if we are the shadow's copy.
- */
- if ((shadow_object = object->shadow) != NULL) {
- vm_object_lock(shadow_object);
- if (shadow_object->copy == object)
- shadow_object->copy = NULL;
- vm_object_unlock(shadow_object);
- }
-
- /*
* wait for the pageout daemon to be done with the object
*/
s = splhigh();
while (object->paging_in_progress) {
- vm_object_unlock(object);
object->flags |= OBJ_PIPWNT;
- tsleep((caddr_t) object, PVM, "objtrm", 0);
- vm_object_lock(object);
+ tsleep(object, PVM, "objtrm", 0);
}
splx(s);
@@ -403,13 +362,11 @@ vm_object_terminate(object)
* Clean and free the pages, as appropriate. All references to the
* object are gone, so we don't need to lock it.
*/
- if (object->pager && (object->pager->pg_type == PG_VNODE)) {
- vn_pager_t vnp = object->pager->pg_data;
- struct vnode *vp;
+ if (object->type == OBJT_VNODE) {
+ struct vnode *vp = object->handle;
- vp = vnp->vnp_vp;
VOP_LOCK(vp);
- (void) _vm_object_page_clean(object, 0, 0, TRUE);
+ vm_object_page_clean(object, 0, 0, TRUE, FALSE);
vinvalbuf(vp, V_SAVE, NOCRED, NULL, 0, 0);
VOP_UNLOCK(vp);
}
@@ -419,27 +376,20 @@ vm_object_terminate(object)
* from paging queues.
*/
while ((p = object->memq.tqh_first) != NULL) {
- VM_PAGE_CHECK(p);
- vm_page_lock_queues();
if (p->flags & PG_BUSY)
printf("vm_object_terminate: freeing busy page\n");
PAGE_WAKEUP(p);
vm_page_free(p);
cnt.v_pfree++;
- vm_page_unlock_queues();
}
- vm_object_unlock(object);
/*
* Let the pager know object is dead.
*/
- if (object->pager != NULL)
- vm_pager_deallocate(object->pager);
+ vm_pager_deallocate(object);
- simple_lock(&vm_object_list_lock);
TAILQ_REMOVE(&vm_object_list, object, object_list);
vm_object_count--;
- simple_unlock(&vm_object_list_lock);
wakeup(object);
@@ -461,11 +411,12 @@ vm_object_terminate(object)
*/
void
-_vm_object_page_clean(object, start, end, syncio)
+vm_object_page_clean(object, start, end, syncio, lockflag)
vm_object_t object;
vm_offset_t start;
vm_offset_t end;
boolean_t syncio;
+ boolean_t lockflag;
{
register vm_page_t p;
register vm_offset_t tstart, tend;
@@ -473,10 +424,16 @@ _vm_object_page_clean(object, start, end, syncio)
int pgcount, s;
int allclean;
int entireobj;
+ struct vnode *vp;
- if (object->pager == NULL || (object->flags & OBJ_WRITEABLE) == 0)
+ if (object->type != OBJT_VNODE || (object->flags & OBJ_WRITEABLE) == 0)
return;
+ vp = object->handle;
+
+ if (lockflag)
+ VOP_LOCK(vp);
+
if (start != end) {
start = trunc_page(start);
end = round_page(end);
@@ -495,17 +452,6 @@ startover:
object->flags &= ~OBJ_WRITEABLE;
entireobj = 1;
}
- /*
- * Wait until potential collapse operation is complete
- */
- if (object->flags & OBJ_INTERNAL) {
- s = splhigh();
- while (object->paging_in_progress) {
- object->flags |= OBJ_PIPWNT;
- tsleep(object, PVM, "objpcw", 0);
- }
- splx(s);
- }
pgcount = object->resident_page_count;
@@ -543,6 +489,8 @@ startover:
pass = 1;
goto startover;
}
+ if (lockflag)
+ VOP_UNLOCK(vp);
return;
}
@@ -599,50 +547,9 @@ startover:
object->flags &= ~OBJ_WRITEABLE;
goto startover;
}
- return;
-}
-
-
-void
-vm_object_page_clean(object, start, end, syncio)
- register vm_object_t object;
- register vm_offset_t start;
- register vm_offset_t end;
- boolean_t syncio;
-{
- if (object->pager && (object->flags & OBJ_WRITEABLE) &&
- (object->pager->pg_type == PG_VNODE)) {
- vn_pager_t vnp = (vn_pager_t) object->pager->pg_data;
- struct vnode *vp;
-
- vp = vnp->vnp_vp;
- VOP_LOCK(vp);
- _vm_object_page_clean(object, start, end, syncio);
+ if (lockflag)
VOP_UNLOCK(vp);
- } else {
- _vm_object_page_clean(object, start, end, syncio);
- }
-}
-
-void
-vm_object_cache_clean()
-{
- vm_object_t object;
- vm_object_cache_lock();
- while(1) {
- object = vm_object_cached_list.tqh_first;
- while( object) {
- if( (object->flags & OBJ_WRITEABLE) &&
- object->pager &&
- object->pager->pg_type == PG_VNODE) {
- vm_object_page_clean(object, 0, 0, 0);
- goto loop;
- }
- object = object->cached_list.tqe_next;
- }
- return;
-loop:
- }
+ return;
}
/*
@@ -661,9 +568,7 @@ vm_object_deactivate_pages(object)
for (p = object->memq.tqh_first; p != NULL; p = next) {
next = p->listq.tqe_next;
- vm_page_lock_queues();
vm_page_deactivate(p);
- vm_page_unlock_queues();
}
}
@@ -675,19 +580,12 @@ vm_object_cache_trim()
{
register vm_object_t object;
- vm_object_cache_lock();
while (vm_object_cached > vm_object_cache_max) {
object = vm_object_cached_list.tqh_first;
- vm_object_cache_unlock();
-
- if (object != vm_object_lookup(object->pager))
- panic("vm_object_cache_trim: I'm sooo confused.");
+ vm_object_reference(object);
pager_cache(object, FALSE);
-
- vm_object_cache_lock();
}
- vm_object_cache_unlock();
}
@@ -711,14 +609,12 @@ vm_object_pmap_copy(object, start, end)
if (object == NULL)
return;
- vm_object_lock(object);
for (p = object->memq.tqh_first; p != NULL; p = p->listq.tqe_next) {
if ((start <= p->offset) && (p->offset < end)) {
vm_page_protect(p, VM_PROT_READ);
p->flags |= PG_COPYONWRITE;
}
}
- vm_object_unlock(object);
}
/*
@@ -742,14 +638,13 @@ vm_object_pmap_remove(object, start, end)
return;
++object->paging_in_progress;
- vm_object_lock(object);
again:
for (p = object->memq.tqh_first; p != NULL; p = p->listq.tqe_next) {
if ((start <= p->offset) && (p->offset < end)) {
s = splhigh();
if ((p->flags & PG_BUSY) || p->busy) {
p->flags |= PG_WANTED;
- tsleep((caddr_t) p, PVM, "vmopmr", 0);
+ tsleep(p, PVM, "vmopmr", 0);
splx(s);
goto again;
}
@@ -757,7 +652,6 @@ again:
vm_page_protect(p, VM_PROT_NONE);
}
}
- vm_object_unlock(object);
vm_object_pip_wakeup(object);
}
@@ -797,160 +691,37 @@ vm_object_copy(src_object, src_offset, size,
*src_needs_copy = FALSE;
return;
}
- /*
- * If the object's pager is null_pager or the default pager, we don't
- * have to make a copy of it. Instead, we set the needs copy flag and
- * make a shadow later.
- */
-
- vm_object_lock(src_object);
/*
* Try to collapse the object before copying it.
*/
+ if (src_object->handle == NULL &&
+ (src_object->type == OBJT_DEFAULT ||
+ src_object->type == OBJT_SWAP))
+ vm_object_collapse(src_object);
- vm_object_collapse(src_object);
-
- if (src_object->pager == NULL ||
- (src_object->flags & OBJ_INTERNAL)) {
-
- /*
- * Make another reference to the object
- */
- src_object->ref_count++;
-
- /*
- * Mark all of the pages copy-on-write.
- */
- for (p = src_object->memq.tqh_first; p; p = p->listq.tqe_next)
- if (src_offset <= p->offset &&
- p->offset < src_offset + size)
- p->flags |= PG_COPYONWRITE;
- vm_object_unlock(src_object);
-
- *dst_object = src_object;
- *dst_offset = src_offset;
-
- /*
- * Must make a shadow when write is desired
- */
- *src_needs_copy = TRUE;
- return;
- }
- /*
- * If the object has a pager, the pager wants to see all of the
- * changes. We need a copy-object for the changed pages.
- *
- * If there is a copy-object, and it is empty, no changes have been made
- * to the object since the copy-object was made. We can use the same
- * copy- object.
- */
-
-Retry1:
- old_copy = src_object->copy;
- if (old_copy != NULL) {
- /*
- * Try to get the locks (out of order)
- */
- if (!vm_object_lock_try(old_copy)) {
- vm_object_unlock(src_object);
-
- /* should spin a bit here... */
- tsleep((caddr_t) old_copy, PVM, "cpylck", 1);
- vm_object_lock(src_object);
- goto Retry1;
- }
- if (old_copy->resident_page_count == 0 &&
- old_copy->pager == NULL) {
- /*
- * Return another reference to the existing
- * copy-object.
- */
- old_copy->ref_count++;
- vm_object_unlock(old_copy);
- vm_object_unlock(src_object);
- *dst_object = old_copy;
- *dst_offset = src_offset;
- *src_needs_copy = FALSE;
- return;
- }
- vm_object_unlock(old_copy);
- }
- vm_object_unlock(src_object);
-
- /*
- * If the object has a pager, the pager wants to see all of the
- * changes. We must make a copy-object and put the changed pages
- * there.
- *
- * The copy-object is always made large enough to completely shadow the
- * original object, since it may have several users who want to shadow
- * the original object at different points.
- */
-
- new_copy = vm_object_allocate(src_object->size);
-
-Retry2:
- vm_object_lock(src_object);
- /*
- * Copy object may have changed while we were unlocked
- */
- old_copy = src_object->copy;
- if (old_copy != NULL) {
- /*
- * Try to get the locks (out of order)
- */
- if (!vm_object_lock_try(old_copy)) {
- vm_object_unlock(src_object);
- tsleep((caddr_t) old_copy, PVM, "cpylck", 1);
- goto Retry2;
- }
- /*
- * Consistency check
- */
- if (old_copy->shadow != src_object ||
- old_copy->shadow_offset != (vm_offset_t) 0)
- panic("vm_object_copy: copy/shadow inconsistency");
-
- /*
- * Make the old copy-object shadow the new one. It will
- * receive no more pages from the original object.
- */
-
- src_object->ref_count--; /* remove ref. from old_copy */
- if (old_copy->shadow)
- TAILQ_REMOVE(&old_copy->shadow->reverse_shadow_head, old_copy, reverse_shadow_list);
- old_copy->shadow = new_copy;
- TAILQ_INSERT_TAIL(&old_copy->shadow->reverse_shadow_head, old_copy, reverse_shadow_list);
- new_copy->ref_count++; /* locking not needed - we have the
- * only pointer */
- vm_object_unlock(old_copy); /* done with old_copy */
- }
- new_start = (vm_offset_t) 0; /* always shadow original at 0 */
- new_end = (vm_offset_t) new_copy->size; /* for the whole object */
/*
- * Point the new copy at the existing object.
+ * Make another reference to the object
*/
-
- new_copy->shadow = src_object;
- TAILQ_INSERT_TAIL(&new_copy->shadow->reverse_shadow_head, new_copy, reverse_shadow_list);
- new_copy->shadow_offset = new_start;
src_object->ref_count++;
- src_object->copy = new_copy;
/*
- * Mark all the affected pages of the existing object copy-on-write.
+ * Mark all of the pages copy-on-write.
*/
- for (p = src_object->memq.tqh_first; p != NULL; p = p->listq.tqe_next)
- if ((new_start <= p->offset) && (p->offset < new_end))
+ for (p = src_object->memq.tqh_first; p; p = p->listq.tqe_next)
+ if (src_offset <= p->offset &&
+ p->offset < src_offset + size)
p->flags |= PG_COPYONWRITE;
- vm_object_unlock(src_object);
+ *dst_object = src_object;
+ *dst_offset = src_offset;
- *dst_object = new_copy;
- *dst_offset = src_offset - new_start;
- *src_needs_copy = FALSE;
+ /*
+ * Must make a shadow when write is desired
+ */
+ *src_needs_copy = TRUE;
+ return;
}
/*
@@ -979,7 +750,7 @@ vm_object_shadow(object, offset, length)
* Allocate a new object with the given length
*/
- if ((result = vm_object_allocate(length)) == NULL)
+ if ((result = vm_object_allocate(OBJT_DEFAULT, length)) == NULL)
panic("vm_object_shadow: no object for shadowing");
/*
@@ -988,16 +759,16 @@ vm_object_shadow(object, offset, length)
* removing a reference to the source object. Net result: no change
* of reference count.
*/
- result->shadow = source;
+ result->backing_object = source;
if (source)
- TAILQ_INSERT_TAIL(&result->shadow->reverse_shadow_head, result, reverse_shadow_list);
+ TAILQ_INSERT_TAIL(&result->backing_object->shadow_head, result, shadow_list);
/*
* Store the offset into the source object, and fix up the offset into
* the new object.
*/
- result->shadow_offset = *offset;
+ result->backing_object_offset = *offset;
/*
* Return the new things
@@ -1009,103 +780,6 @@ vm_object_shadow(object, offset, length)
/*
- * vm_object_lookup looks in the object cache for an object with the
- * specified pager and paging id.
- */
-
-vm_object_t
-vm_object_lookup(pager)
- vm_pager_t pager;
-{
- register vm_object_hash_entry_t entry;
- vm_object_t object;
-
- vm_object_cache_lock();
-
- for (entry = vm_object_hashtable[OBJECT_HASH(pager)].lh_first;
- entry != NULL; entry = entry->hash_links.le_next) {
- object = entry->object;
- if (object->pager == pager) {
- vm_object_lock(object);
- if (object->ref_count == 0) {
- TAILQ_REMOVE(&vm_object_cached_list, object,
- cached_list);
- vm_object_cached--;
- }
- object->ref_count++;
- vm_object_unlock(object);
- vm_object_cache_unlock();
- return (object);
- }
- }
-
- vm_object_cache_unlock();
- return (NULL);
-}
-
-/*
- * vm_object_enter enters the specified object/pager/id into
- * the hash table.
- */
-
-void
-vm_object_enter(object, pager)
- vm_object_t object;
- vm_pager_t pager;
-{
- struct vm_object_hash_head *bucket;
- register vm_object_hash_entry_t entry;
-
- /*
- * We don't cache null objects, and we can't cache objects with the
- * null pager.
- */
-
- if (object == NULL)
- return;
- if (pager == NULL)
- return;
-
- bucket = &vm_object_hashtable[OBJECT_HASH(pager)];
- entry = (vm_object_hash_entry_t)
- malloc((u_long) sizeof *entry, M_VMOBJHASH, M_WAITOK);
- entry->object = object;
-
- vm_object_cache_lock();
- LIST_INSERT_HEAD(bucket, entry, hash_links);
- vm_object_cache_unlock();
-}
-
-/*
- * vm_object_remove:
- *
- * Remove the pager from the hash table.
- * Note: This assumes that the object cache
- * is locked. XXX this should be fixed
- * by reorganizing vm_object_deallocate.
- */
-void
-vm_object_remove(pager)
- register vm_pager_t pager;
-{
- struct vm_object_hash_head *bucket;
- register vm_object_hash_entry_t entry;
- register vm_object_t object;
-
- bucket = &vm_object_hashtable[OBJECT_HASH(pager)];
-
- for (entry = bucket->lh_first;
- entry != NULL; entry = entry->hash_links.le_next) {
- object = entry->object;
- if (object->pager == pager) {
- LIST_REMOVE(entry, hash_links);
- free((caddr_t) entry, M_VMOBJHASH);
- break;
- }
- }
-}
-
-/*
* this version of collapse allows the operation to occur earlier and
* when paging_in_progress is true for an object... This is not a complete
* operation, but should plug 99.9% of the rest of the leaks.
@@ -1119,16 +793,13 @@ vm_object_qcollapse(object)
register vm_page_t p, pp;
register vm_size_t size;
- backing_object = object->shadow;
- if (backing_object->shadow != NULL &&
- backing_object->shadow->copy == backing_object)
- return;
+ backing_object = object->backing_object;
if (backing_object->ref_count != 1)
return;
backing_object->ref_count += 2;
- backing_offset = object->shadow_offset;
+ backing_offset = object->backing_object_offset;
size = object->size;
p = backing_object->memq.tqh_first;
while (p) {
@@ -1144,25 +815,21 @@ vm_object_qcollapse(object)
new_offset = (p->offset - backing_offset);
if (p->offset < backing_offset ||
new_offset >= size) {
- if (backing_object->pager)
- swap_pager_freespace(backing_object->pager,
+ if (backing_object->type == OBJT_SWAP)
+ swap_pager_freespace(backing_object,
backing_object->paging_offset + p->offset, PAGE_SIZE);
- vm_page_lock_queues();
vm_page_free(p);
- vm_page_unlock_queues();
} else {
pp = vm_page_lookup(object, new_offset);
- if (pp != NULL || (object->pager && vm_pager_has_page(object->pager,
- object->paging_offset + new_offset))) {
- if (backing_object->pager)
- swap_pager_freespace(backing_object->pager,
+ if (pp != NULL || (object->type == OBJT_SWAP && vm_pager_has_page(object,
+ object->paging_offset + new_offset, NULL, NULL))) {
+ if (backing_object->type == OBJT_SWAP)
+ swap_pager_freespace(backing_object,
backing_object->paging_offset + p->offset, PAGE_SIZE);
- vm_page_lock_queues();
vm_page_free(p);
- vm_page_unlock_queues();
} else {
- if( backing_object->pager)
- swap_pager_freespace(backing_object->pager,
+ if (backing_object->type == OBJT_SWAP)
+ swap_pager_freespace(backing_object,
backing_object->paging_offset + p->offset, PAGE_SIZE);
vm_page_rename(p, object, new_offset);
p->dirty = VM_PAGE_BITS_ALL;
@@ -1173,35 +840,23 @@ vm_object_qcollapse(object)
backing_object->ref_count -= 2;
}
-boolean_t vm_object_collapse_allowed = TRUE;
-
/*
* vm_object_collapse:
*
* Collapse an object with the object backing it.
* Pages in the backing object are moved into the
* parent, and the backing object is deallocated.
- *
- * Requires that the object be locked and the page
- * queues be unlocked.
- *
- * This routine has significant changes by John S. Dyson
- * to fix some swap memory leaks. 18 Dec 93
- *
*/
void
vm_object_collapse(object)
- register vm_object_t object;
+ vm_object_t object;
{
- register vm_object_t backing_object;
- register vm_offset_t backing_offset;
- register vm_size_t size;
- register vm_offset_t new_offset;
- register vm_page_t p, pp;
-
- if (!vm_object_collapse_allowed)
- return;
+ vm_object_t backing_object;
+ vm_offset_t backing_offset;
+ vm_size_t size;
+ vm_offset_t new_offset;
+ vm_page_t p, pp;
while (TRUE) {
/*
@@ -1216,42 +871,27 @@ vm_object_collapse(object)
/*
* Make sure there is a backing object.
*/
- if ((backing_object = object->shadow) == NULL)
+ if ((backing_object = object->backing_object) == NULL)
return;
/*
* we check the backing object first, because it is most likely
- * !OBJ_INTERNAL.
+ * not collapsable.
*/
- if ((backing_object->flags & OBJ_INTERNAL) == 0 ||
+ if (backing_object->handle != NULL ||
+ (backing_object->type != OBJT_DEFAULT &&
+ backing_object->type != OBJT_SWAP) ||
(backing_object->flags & OBJ_DEAD) ||
- (object->flags & OBJ_INTERNAL) == 0 ||
- (object->flags & OBJ_DEAD))
+ object->handle != NULL ||
+ (object->type != OBJT_DEFAULT &&
+ object->type != OBJT_SWAP) ||
+ (object->flags & OBJ_DEAD)) {
return;
+ }
if (object->paging_in_progress != 0 ||
backing_object->paging_in_progress != 0) {
- if (vm_object_lock_try(backing_object)) {
- vm_object_qcollapse(object);
- vm_object_unlock(backing_object);
- }
- return;
- }
-
- vm_object_lock(backing_object);
-
- /*
- * The backing object can't be a copy-object: the
- * shadow_offset for the copy-object must stay as 0.
- * Furthermore (for the 'we have all the pages' case), if we
- * bypass backing_object and just shadow the next object in
- * the chain, old pages from that object would then have to be
- * copied BOTH into the (former) backing_object and into the
- * parent object.
- */
- if (backing_object->shadow != NULL &&
- backing_object->shadow->copy == backing_object) {
- vm_object_unlock(backing_object);
+ vm_object_qcollapse(object);
return;
}
@@ -1261,7 +901,7 @@ vm_object_collapse(object)
* the parent's reference to it.
*/
- backing_offset = object->shadow_offset;
+ backing_offset = object->backing_object_offset;
size = object->size;
/*
@@ -1295,20 +935,16 @@ vm_object_collapse(object)
if (p->offset < backing_offset ||
new_offset >= size) {
- vm_page_lock_queues();
vm_page_protect(p, VM_PROT_NONE);
PAGE_WAKEUP(p);
vm_page_free(p);
- vm_page_unlock_queues();
} else {
pp = vm_page_lookup(object, new_offset);
- if (pp != NULL || (object->pager && vm_pager_has_page(object->pager,
- object->paging_offset + new_offset))) {
- vm_page_lock_queues();
+ if (pp != NULL || (object->type == OBJT_SWAP && vm_pager_has_page(object,
+ object->paging_offset + new_offset, NULL, NULL))) {
vm_page_protect(p, VM_PROT_NONE);
PAGE_WAKEUP(p);
vm_page_free(p);
- vm_page_unlock_queues();
} else {
vm_page_rename(p, object, new_offset);
}
@@ -1319,36 +955,45 @@ vm_object_collapse(object)
* Move the pager from backing_object to object.
*/
- if (backing_object->pager) {
+ if (backing_object->type == OBJT_SWAP) {
backing_object->paging_in_progress++;
- if (object->pager) {
- vm_pager_t bopager;
-
+ if (object->type == OBJT_SWAP) {
object->paging_in_progress++;
/*
* copy shadow object pages into ours
* and destroy unneeded pages in
* shadow object.
*/
- bopager = backing_object->pager;
- backing_object->pager = NULL;
swap_pager_copy(
- bopager, backing_object->paging_offset,
- object->pager, object->paging_offset,
- object->shadow_offset);
+ backing_object, backing_object->paging_offset,
+ object, object->paging_offset,
+ object->backing_object_offset);
vm_object_pip_wakeup(object);
} else {
+ extern struct pagerlst swap_pager_un_object_list;
+
object->paging_in_progress++;
/*
- * grab the shadow objects pager
+ * move the shadow backing_object's pager data to
+ * "object" and convert "object" type to OBJT_SWAP.
*/
- object->pager = backing_object->pager;
+ object->type = OBJT_SWAP;
+ object->pg_data = backing_object->pg_data;
object->paging_offset = backing_object->paging_offset + backing_offset;
- backing_object->pager = NULL;
+ TAILQ_INSERT_TAIL(&swap_pager_un_object_list, object, pager_object_list);
+
+ /*
+ * Convert backing object from OBJT_SWAP to
+ * OBJT_DEFAULT. XXX - only the TAILQ_REMOVE is
+ * actually necessary.
+ */
+ backing_object->type = OBJT_DEFAULT;
+ backing_object->pg_data = NULL;
+ TAILQ_REMOVE(&swap_pager_un_object_list, backing_object, pager_object_list);
/*
* free unnecessary blocks
*/
- swap_pager_freespace(object->pager, 0, object->paging_offset);
+ swap_pager_freespace(object, 0, object->paging_offset);
vm_object_pip_wakeup(object);
}
@@ -1356,21 +1001,21 @@ vm_object_collapse(object)
}
/*
* Object now shadows whatever backing_object did.
- * Note that the reference to backing_object->shadow
+ * Note that the reference to backing_object->backing_object
* moves from within backing_object to within object.
*/
- TAILQ_REMOVE(&object->shadow->reverse_shadow_head, object,
- reverse_shadow_list);
- if (backing_object->shadow)
- TAILQ_REMOVE(&backing_object->shadow->reverse_shadow_head,
- backing_object, reverse_shadow_list);
- object->shadow = backing_object->shadow;
- if (object->shadow)
- TAILQ_INSERT_TAIL(&object->shadow->reverse_shadow_head,
- object, reverse_shadow_list);
-
- object->shadow_offset += backing_object->shadow_offset;
+ TAILQ_REMOVE(&object->backing_object->shadow_head, object,
+ shadow_list);
+ if (backing_object->backing_object)
+ TAILQ_REMOVE(&backing_object->backing_object->shadow_head,
+ backing_object, shadow_list);
+ object->backing_object = backing_object->backing_object;
+ if (object->backing_object)
+ TAILQ_INSERT_TAIL(&object->backing_object->shadow_head,
+ object, shadow_list);
+
+ object->backing_object_offset += backing_object->backing_object_offset;
/*
* Discard backing_object.
*
@@ -1379,13 +1024,9 @@ vm_object_collapse(object)
* necessary is to dispose of it.
*/
- vm_object_unlock(backing_object);
-
- simple_lock(&vm_object_list_lock);
TAILQ_REMOVE(&vm_object_list, backing_object,
object_list);
vm_object_count--;
- simple_unlock(&vm_object_list_lock);
free((caddr_t) backing_object, M_VMOBJ);
@@ -1401,8 +1042,7 @@ vm_object_collapse(object)
* to check all of the paged-out pages, as well.
*/
- if (backing_object->pager != NULL) {
- vm_object_unlock(backing_object);
+ if (backing_object->type != OBJT_DEFAULT) {
return;
}
/*
@@ -1421,17 +1061,19 @@ vm_object_collapse(object)
* the chain.
*/
- if (p->offset >= backing_offset &&
- new_offset <= size &&
- ((pp = vm_page_lookup(object, new_offset)) == NULL ||
- !pp->valid) &&
- (!object->pager || !vm_pager_has_page(object->pager, object->paging_offset + new_offset))) {
- /*
- * Page still needed. Can't go any
- * further.
- */
- vm_object_unlock(backing_object);
- return;
+ if (p->offset >= backing_offset && new_offset <= size) {
+
+ pp = vm_page_lookup(object, new_offset);
+
+ if ((pp == NULL || pp->valid == 0) &&
+ !vm_pager_has_page(object, object->paging_offset + new_offset, NULL, NULL)) {
+
+ /*
+ * Page still needed. Can't go any
+ * further.
+ */
+ return;
+ }
}
}
@@ -1441,22 +1083,15 @@ vm_object_collapse(object)
* it, since its reference count is at least 2.
*/
- TAILQ_REMOVE(&object->shadow->reverse_shadow_head,
- object, reverse_shadow_list);
- vm_object_reference(object->shadow = backing_object->shadow);
- if (object->shadow)
- TAILQ_INSERT_TAIL(&object->shadow->reverse_shadow_head,
- object, reverse_shadow_list);
- object->shadow_offset += backing_object->shadow_offset;
+ TAILQ_REMOVE(&object->backing_object->shadow_head,
+ object, shadow_list);
+ vm_object_reference(object->backing_object = backing_object->backing_object);
+ if (object->backing_object)
+ TAILQ_INSERT_TAIL(&object->backing_object->shadow_head,
+ object, shadow_list);
+ object->backing_object_offset += backing_object->backing_object_offset;
/*
- * Backing object might have had a copy pointer to us.
- * If it did, clear it.
- */
- if (backing_object->copy == object) {
- backing_object->copy = NULL;
- }
- /*
* Drop the reference count on backing_object. Since
* its ref_count was at least 2, it will not vanish;
* so we don't need to call vm_object_deallocate.
@@ -1464,7 +1099,6 @@ vm_object_collapse(object)
if (backing_object->ref_count == 1)
printf("should have called obj deallocate\n");
backing_object->ref_count--;
- vm_object_unlock(backing_object);
object_bypasses++;
@@ -1514,7 +1148,7 @@ again:
}
if ((p->flags & PG_BUSY) || p->busy) {
p->flags |= PG_WANTED;
- tsleep((caddr_t) p, PVM, "vmopar", 0);
+ tsleep(p, PVM, "vmopar", 0);
splx(s);
goto again;
}
@@ -1525,10 +1159,8 @@ again:
continue;
}
vm_page_protect(p, VM_PROT_NONE);
- vm_page_lock_queues();
PAGE_WAKEUP(p);
vm_page_free(p);
- vm_page_unlock_queues();
}
}
} else {
@@ -1541,7 +1173,7 @@ again:
}
if ((p->flags & PG_BUSY) || p->busy) {
p->flags |= PG_WANTED;
- tsleep((caddr_t) p, PVM, "vmopar", 0);
+ tsleep(p, PVM, "vmopar", 0);
splx(s);
goto again;
}
@@ -1552,10 +1184,8 @@ again:
continue;
}
vm_page_protect(p, VM_PROT_NONE);
- vm_page_lock_queues();
PAGE_WAKEUP(p);
vm_page_free(p);
- vm_page_unlock_queues();
}
start += PAGE_SIZE;
size -= PAGE_SIZE;
@@ -1603,7 +1233,6 @@ vm_object_coalesce(prev_object, next_object,
if (prev_object == NULL) {
return (TRUE);
}
- vm_object_lock(prev_object);
/*
* Try to collapse the object first
@@ -1617,10 +1246,8 @@ vm_object_coalesce(prev_object, next_object,
*/
if (prev_object->ref_count > 1 ||
- prev_object->pager != NULL ||
- prev_object->shadow != NULL ||
- prev_object->copy != NULL) {
- vm_object_unlock(prev_object);
+ prev_object->type != OBJT_DEFAULT ||
+ prev_object->backing_object != NULL) {
return (FALSE);
}
/*
@@ -1639,7 +1266,6 @@ vm_object_coalesce(prev_object, next_object,
if (newsize > prev_object->size)
prev_object->size = newsize;
- vm_object_unlock(prev_object);
return (TRUE);
}
@@ -1655,10 +1281,10 @@ vm_object_page_lookup(object, offset)
vm_page_t m;
if (!(m = vm_page_lookup(object, offset))) {
- if (!object->shadow)
+ if (!object->backing_object)
return 0;
else
- return vm_object_page_lookup(object->shadow, offset + object->shadow_offset);
+ return vm_object_page_lookup(object->backing_object, offset + object->backing_object_offset);
}
return m;
}
@@ -1699,7 +1325,7 @@ _vm_object_in_map(map, object, entry)
tmpe = tmpe->next;
}
} else if (obj = entry->object.vm_object) {
- for(; obj; obj=obj->shadow)
+ for(; obj; obj=obj->backing_object)
if( obj == object) {
return 1;
}
@@ -1748,25 +1374,6 @@ vm_object_check() {
int i;
int maxhash = 0;
vm_object_t object;
- vm_object_hash_entry_t entry;
-
- /*
- * make sure that no internal objs are hashed
- */
- for (i=0; i<VM_OBJECT_HASH_COUNT;i++) {
- int lsize = 0;
- for (entry = vm_object_hashtable[i].lh_first;
- entry != NULL; entry = entry->hash_links.le_next) {
- if( entry->object->flags & OBJ_INTERNAL) {
- printf("vmochk: internal obj on hash: size: %d\n", entry->object->size);
- }
- ++lsize;
- }
- if( lsize > maxhash)
- maxhash = lsize;
- }
-
- printf("maximum object hash queue size: %d\n", maxhash);
/*
* make sure that internal objs are in a map somewhere
@@ -1775,14 +1382,15 @@ vm_object_check() {
for (object = vm_object_list.tqh_first;
object != NULL;
object = object->object_list.tqe_next) {
- if (object->flags & OBJ_INTERNAL) {
+ if (object->handle == NULL &&
+ (object->type == OBJT_DEFAULT || object->type == OBJT_SWAP)) {
if (object->ref_count == 0) {
printf("vmochk: internal obj has zero ref count: %d\n",
object->size);
}
if (!vm_object_in_map(object)) {
- printf("vmochk: internal obj is not in a map: ref: %d, size: %d, pager: 0x%x, shadow: 0x%x\n",
- object->ref_count, object->size, object->pager, object->shadow);
+ printf("vmochk: internal obj is not in a map: ref: %d, size: %d, pg_data: 0x%x, backing_object: 0x%x\n",
+ object->ref_count, object->size, object->pg_data, object->backing_object);
}
}
}
@@ -1806,9 +1414,9 @@ vm_object_print(object, full)
iprintf("Object 0x%x: size=0x%x, res=%d, ref=%d, ",
(int) object, (int) object->size,
object->resident_page_count, object->ref_count);
- printf("pager=0x%x+0x%x, shadow=(0x%x)+0x%x\n",
- (int) object->pager, (int) object->paging_offset,
- (int) object->shadow, (int) object->shadow_offset);
+ printf("pg_data=0x%x+0x%x, backing_object=(0x%x)+0x%x\n",
+ (int) object->pg_data, (int) object->paging_offset,
+ (int) object->backing_object, (int) object->backing_object_offset);
printf("cache: next=%p, prev=%p\n",
object->cached_list.tqe_next, object->cached_list.tqe_prev);
diff --git a/sys/vm/vm_object.h b/sys/vm/vm_object.h
index 18b4e9a..5a89b17 100644
--- a/sys/vm/vm_object.h
+++ b/sys/vm/vm_object.h
@@ -61,7 +61,7 @@
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*
- * $Id: vm_object.h,v 1.17 1995/04/09 06:03:51 davidg Exp $
+ * $Id: vm_object.h,v 1.18 1995/05/02 05:57:11 davidg Exp $
*/
/*
@@ -75,8 +75,8 @@
#include <sys/proc.h> /* XXX for wakeup() */
#endif
-#include <vm/vm_page.h>
-#include <vm/vm_pager.h>
+enum obj_type { OBJT_DEFAULT, OBJT_SWAP, OBJT_VNODE, OBJT_DEVICE };
+typedef enum obj_type objtype_t;
/*
* Types defined:
@@ -85,44 +85,44 @@
*/
struct vm_object {
- struct pglist memq; /* Resident memory */
- TAILQ_HEAD(rslist, vm_object) reverse_shadow_head; /* objects that this is a shadow for */
TAILQ_ENTRY(vm_object) object_list; /* list of all objects */
- TAILQ_ENTRY(vm_object) reverse_shadow_list; /* chain of objects that are shadowed */
- TAILQ_ENTRY(vm_object) cached_list; /* for persistence */
+ TAILQ_ENTRY(vm_object) cached_list; /* list of cached (persistent) objects */
+ TAILQ_HEAD(, vm_object) shadow_head; /* objects that this is a shadow for */
+ TAILQ_ENTRY(vm_object) shadow_list; /* chain of shadow objects */
+ TAILQ_HEAD(, vm_page) memq; /* list of resident pages */
+ objtype_t type; /* type of pager */
vm_size_t size; /* Object size */
int ref_count; /* How many refs?? */
u_short flags; /* see below */
u_short paging_in_progress; /* Paging (in or out) so don't collapse or destroy */
int resident_page_count; /* number of resident pages */
- vm_pager_t pager; /* Where to get data */
vm_offset_t paging_offset; /* Offset into paging space */
- struct vm_object *shadow; /* My shadow */
- vm_offset_t shadow_offset; /* Offset in shadow */
+ struct vm_object *backing_object; /* object that I'm a shadow of */
+ vm_offset_t backing_object_offset;/* Offset in backing object */
struct vm_object *copy; /* Object that holds copies of my changed pages */
vm_offset_t last_read; /* last read in object -- detect seq behavior */
+ TAILQ_ENTRY(vm_object) pager_object_list; /* list of all objects of this pager type */
+ void *handle;
+ void *pg_data;
+ union {
+ struct {
+ vm_size_t vnp_size; /* Current size of file */
+ } vnp;
+ struct {
+ TAILQ_HEAD(, vm_page) devp_pglist; /* list of pages allocated */
+ } devp;
+ } un_pager;
};
/*
* Flags
*/
#define OBJ_CANPERSIST 0x0001 /* allow to persist */
-#define OBJ_INTERNAL 0x0002 /* internally created object */
-#define OBJ_ACTIVE 0x0004 /* used to mark active objects */
-#define OBJ_DEAD 0x0008 /* used to mark dead objects during rundown */
-#define OBJ_ILOCKED 0x0010 /* lock from modification */
-#define OBJ_ILOCKWT 0x0020 /* wait for lock from modification */
+#define OBJ_ACTIVE 0x0004 /* active objects */
+#define OBJ_DEAD 0x0008 /* dead objects (during rundown) */
#define OBJ_PIPWNT 0x0040 /* paging in progress wanted */
-#define OBJ_WRITEABLE 0x0080 /* object has been made writeable */
+#define OBJ_WRITEABLE 0x0080 /* object has been made writable */
-LIST_HEAD(vm_object_hash_head, vm_object_hash_entry);
-
-struct vm_object_hash_entry {
- LIST_ENTRY(vm_object_hash_entry) hash_links; /* hash chain links */
- vm_object_t object; /* object represened */
-};
-
-typedef struct vm_object_hash_entry *vm_object_hash_entry_t;
#ifdef KERNEL
extern int vm_object_cache_max;
@@ -131,28 +131,17 @@ TAILQ_HEAD(object_q, vm_object);
struct object_q vm_object_cached_list; /* list of objects persisting */
int vm_object_cached; /* size of cached list */
-simple_lock_data_t vm_cache_lock; /* lock for object cache */
struct object_q vm_object_list; /* list of allocated objects */
long vm_object_count; /* count of all objects */
-simple_lock_data_t vm_object_list_lock;
/* lock for object list and count */
vm_object_t kernel_object; /* the single kernel object */
vm_object_t kmem_object;
-#define vm_object_cache_lock() simple_lock(&vm_cache_lock)
-#define vm_object_cache_unlock() simple_unlock(&vm_cache_lock)
#endif /* KERNEL */
-#if 1
-#define vm_object_lock_init(object) simple_lock_init(&(object)->Lock)
-#define vm_object_lock(object) simple_lock(&(object)->Lock)
-#define vm_object_unlock(object) simple_unlock(&(object)->Lock)
-#define vm_object_lock_try(object) simple_lock_try(&(object)->Lock)
-#endif
-
#ifdef KERNEL
static __inline void
vm_object_pip_wakeup(vm_object_t object)
@@ -164,7 +153,7 @@ vm_object_pip_wakeup(vm_object_t object)
}
}
-vm_object_t vm_object_allocate __P((vm_size_t));
+vm_object_t vm_object_allocate __P((objtype_t, vm_size_t));
void vm_object_cache_clear __P((void));
void vm_object_cache_trim __P((void));
boolean_t vm_object_coalesce __P((vm_object_t, vm_object_t, vm_offset_t, vm_offset_t, vm_offset_t, vm_size_t));
@@ -172,17 +161,13 @@ void vm_object_collapse __P((vm_object_t));
void vm_object_copy __P((vm_object_t, vm_offset_t, vm_size_t, vm_object_t *, vm_offset_t *, boolean_t *));
void vm_object_deactivate_pages __P((vm_object_t));
void vm_object_deallocate __P((vm_object_t));
-void vm_object_enter __P((vm_object_t, vm_pager_t));
void vm_object_init __P((vm_size_t));
-vm_object_t vm_object_lookup __P((vm_pager_t));
-void _vm_object_page_clean __P((vm_object_t, vm_offset_t, vm_offset_t, boolean_t));
-void vm_object_page_clean __P((vm_object_t, vm_offset_t, vm_offset_t, boolean_t));
+void vm_object_page_clean __P((vm_object_t, vm_offset_t, vm_offset_t, boolean_t, boolean_t));
void vm_object_page_remove __P((vm_object_t, vm_offset_t, vm_offset_t, boolean_t));
void vm_object_pmap_copy __P((vm_object_t, vm_offset_t, vm_offset_t));
void vm_object_pmap_remove __P((vm_object_t, vm_offset_t, vm_offset_t));
void vm_object_print __P((vm_object_t, boolean_t));
void vm_object_reference __P((vm_object_t));
-void vm_object_remove __P((vm_pager_t));
void vm_object_shadow __P((vm_object_t *, vm_offset_t *, vm_size_t));
void vm_object_terminate __P((vm_object_t));
#endif /* KERNEL */
diff --git a/sys/vm/vm_page.c b/sys/vm/vm_page.c
index 30983e1..2f6b8a0 100644
--- a/sys/vm/vm_page.c
+++ b/sys/vm/vm_page.c
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* from: @(#)vm_page.c 7.4 (Berkeley) 5/7/91
- * $Id: vm_page.c,v 1.31 1995/04/16 12:56:21 davidg Exp $
+ * $Id: vm_page.c,v 1.32 1995/05/30 08:16:15 rgrimes Exp $
*/
/*
@@ -86,14 +86,11 @@
struct pglist *vm_page_buckets; /* Array of buckets */
int vm_page_bucket_count; /* How big is array? */
int vm_page_hash_mask; /* Mask for hash function */
-simple_lock_data_t bucket_lock; /* lock for all buckets XXX */
struct pglist vm_page_queue_free;
struct pglist vm_page_queue_active;
struct pglist vm_page_queue_inactive;
struct pglist vm_page_queue_cache;
-simple_lock_data_t vm_page_queue_lock;
-simple_lock_data_t vm_page_queue_free_lock;
/* has physical page allocation been initialized? */
boolean_t vm_page_startup_initialized;
@@ -196,14 +193,6 @@ vm_page_startup(starta, enda, vaddr)
start = phys_avail[biggestone];
-
- /*
- * Initialize the locks
- */
-
- simple_lock_init(&vm_page_queue_free_lock);
- simple_lock_init(&vm_page_queue_lock);
-
/*
* Initialize the queue headers for the free queue, the active queue
* and the inactive queue.
@@ -250,8 +239,6 @@ vm_page_startup(starta, enda, vaddr)
bucket++;
}
- simple_lock_init(&bucket_lock);
-
/*
* round (or truncate) the addresses to our page size.
*/
@@ -290,8 +277,6 @@ vm_page_startup(starta, enda, vaddr)
*/
first_page = phys_avail[0] / PAGE_SIZE;
-
- /* for VM_PAGE_CHECK() */
last_page = phys_avail[(nblocks - 1) * 2 + 1] / PAGE_SIZE;
page_range = last_page - (phys_avail[0] / PAGE_SIZE);
@@ -342,12 +327,6 @@ vm_page_startup(starta, enda, vaddr)
}
}
- /*
- * Initialize vm_pages_needed lock here - don't wait for pageout
- * daemon XXX
- */
- simple_lock_init(&vm_pages_needed_lock);
-
return (mapped);
}
@@ -383,8 +362,6 @@ vm_page_insert(mem, object, offset)
{
register struct pglist *bucket;
- VM_PAGE_CHECK(mem);
-
if (mem->flags & PG_TABLED)
panic("vm_page_insert: already inserted");
@@ -400,9 +377,7 @@ vm_page_insert(mem, object, offset)
*/
bucket = &vm_page_buckets[vm_page_hash(object, offset)];
- simple_lock(&bucket_lock);
TAILQ_INSERT_TAIL(bucket, mem, hashq);
- simple_unlock(&bucket_lock);
/*
* Now link into the object's list of backed pages.
@@ -434,8 +409,6 @@ vm_page_remove(mem)
{
register struct pglist *bucket;
- VM_PAGE_CHECK(mem);
-
if (!(mem->flags & PG_TABLED))
return;
@@ -444,9 +417,7 @@ vm_page_remove(mem)
*/
bucket = &vm_page_buckets[vm_page_hash(mem->object, mem->offset)];
- simple_lock(&bucket_lock);
TAILQ_REMOVE(bucket, mem, hashq);
- simple_unlock(&bucket_lock);
/*
* Now remove from the object's list of backed pages.
@@ -488,17 +459,13 @@ vm_page_lookup(object, offset)
bucket = &vm_page_buckets[vm_page_hash(object, offset)];
s = splhigh();
- simple_lock(&bucket_lock);
for (mem = bucket->tqh_first; mem != NULL; mem = mem->hashq.tqe_next) {
- VM_PAGE_CHECK(mem);
if ((mem->object == object) && (mem->offset == offset)) {
- simple_unlock(&bucket_lock);
splx(s);
return (mem);
}
}
- simple_unlock(&bucket_lock);
splx(s);
return (NULL);
}
@@ -522,12 +489,10 @@ vm_page_rename(mem, new_object, new_offset)
if (mem->object == new_object)
return;
- vm_page_lock_queues(); /* keep page from moving out from under pageout daemon */
s = splhigh();
vm_page_remove(mem);
vm_page_insert(mem, new_object, new_offset);
splx(s);
- vm_page_unlock_queues();
}
/*
@@ -583,12 +548,19 @@ vm_page_alloc(object, offset, page_req)
register vm_page_t mem;
int s;
+#ifdef DIAGNOSTIC
+ if (offset != trunc_page(offset))
+ panic("vm_page_alloc: offset not page aligned");
+
+ mem = vm_page_lookup(object, offset);
+ if (mem)
+ panic("vm_page_alloc: page already allocated");
+#endif
+
if ((curproc == pageproc) && (page_req != VM_ALLOC_INTERRUPT)) {
page_req = VM_ALLOC_SYSTEM;
};
- simple_lock(&vm_page_queue_free_lock);
-
s = splhigh();
mem = vm_page_queue_free.tqh_first;
@@ -605,7 +577,6 @@ vm_page_alloc(object, offset, page_req)
vm_page_remove(mem);
cnt.v_cache_count--;
} else {
- simple_unlock(&vm_page_queue_free_lock);
splx(s);
pagedaemon_wakeup();
return (NULL);
@@ -626,7 +597,6 @@ vm_page_alloc(object, offset, page_req)
vm_page_remove(mem);
cnt.v_cache_count--;
} else {
- simple_unlock(&vm_page_queue_free_lock);
splx(s);
pagedaemon_wakeup();
return (NULL);
@@ -639,7 +609,6 @@ vm_page_alloc(object, offset, page_req)
TAILQ_REMOVE(&vm_page_queue_free, mem, pageq);
cnt.v_free_count--;
} else {
- simple_unlock(&vm_page_queue_free_lock);
splx(s);
pagedaemon_wakeup();
return NULL;
@@ -650,8 +619,6 @@ vm_page_alloc(object, offset, page_req)
panic("vm_page_alloc: invalid allocation class");
}
- simple_unlock(&vm_page_queue_free_lock);
-
mem->flags = PG_BUSY;
mem->wire_count = 0;
mem->hold_count = 0;
@@ -784,10 +751,8 @@ vm_page_free(mem)
}
if ((flags & PG_WANTED) != 0)
- wakeup((caddr_t) mem);
+ wakeup(mem);
if ((flags & PG_FICTITIOUS) == 0) {
-
- simple_lock(&vm_page_queue_free_lock);
if (mem->wire_count) {
if (mem->wire_count > 1) {
printf("vm_page_free: wire count > 1 (%d)", mem->wire_count);
@@ -798,15 +763,13 @@ vm_page_free(mem)
}
mem->flags |= PG_FREE;
TAILQ_INSERT_TAIL(&vm_page_queue_free, mem, pageq);
-
- simple_unlock(&vm_page_queue_free_lock);
splx(s);
/*
* if pageout daemon needs pages, then tell it that there are
* some free.
*/
if (vm_pageout_pages_needed) {
- wakeup((caddr_t) &vm_pageout_pages_needed);
+ wakeup(&vm_pageout_pages_needed);
vm_pageout_pages_needed = 0;
}
@@ -817,8 +780,8 @@ vm_page_free(mem)
* lots of memory. this process will swapin processes.
*/
if ((cnt.v_free_count + cnt.v_cache_count) == cnt.v_free_min) {
- wakeup((caddr_t) &cnt.v_free_count);
- wakeup((caddr_t) &proc0);
+ wakeup(&cnt.v_free_count);
+ wakeup(&proc0);
}
} else {
splx(s);
@@ -841,7 +804,6 @@ vm_page_wire(mem)
register vm_page_t mem;
{
int s;
- VM_PAGE_CHECK(mem);
if (mem->wire_count == 0) {
s = splhigh();
@@ -867,8 +829,6 @@ vm_page_unwire(mem)
{
int s;
- VM_PAGE_CHECK(mem);
-
s = splhigh();
if (mem->wire_count)
@@ -895,8 +855,6 @@ vm_page_activate(m)
{
int s;
- VM_PAGE_CHECK(m);
-
s = splhigh();
if (m->flags & PG_ACTIVE)
panic("vm_page_activate: already active");
@@ -933,8 +891,6 @@ vm_page_deactivate(m)
{
int spl;
- VM_PAGE_CHECK(m);
-
/*
* Only move active pages -- ignore locked or already inactive ones.
*
@@ -969,7 +925,6 @@ vm_page_cache(m)
{
int s;
- VM_PAGE_CHECK(m);
if ((m->flags & (PG_CACHE | PG_BUSY)) || m->busy || m->wire_count ||
m->bmapped)
return;
@@ -982,11 +937,11 @@ vm_page_cache(m)
m->flags |= PG_CACHE;
cnt.v_cache_count++;
if ((cnt.v_free_count + cnt.v_cache_count) == cnt.v_free_min) {
- wakeup((caddr_t) &cnt.v_free_count);
- wakeup((caddr_t) &proc0);
+ wakeup(&cnt.v_free_count);
+ wakeup(&proc0);
}
if (vm_pageout_pages_needed) {
- wakeup((caddr_t) &vm_pageout_pages_needed);
+ wakeup(&vm_pageout_pages_needed);
vm_pageout_pages_needed = 0;
}
@@ -1004,8 +959,6 @@ boolean_t
vm_page_zero_fill(m)
vm_page_t m;
{
- VM_PAGE_CHECK(m);
-
pmap_zero_page(VM_PAGE_TO_PHYS(m));
m->valid = VM_PAGE_BITS_ALL;
return (TRUE);
@@ -1021,9 +974,6 @@ vm_page_copy(src_m, dest_m)
vm_page_t src_m;
vm_page_t dest_m;
{
- VM_PAGE_CHECK(src_m);
- VM_PAGE_CHECK(dest_m);
-
pmap_copy_page(VM_PAGE_TO_PHYS(src_m), VM_PAGE_TO_PHYS(dest_m));
dest_m->valid = VM_PAGE_BITS_ALL;
}
diff --git a/sys/vm/vm_page.h b/sys/vm/vm_page.h
index 4a4e54d..db6d3b3 100644
--- a/sys/vm/vm_page.h
+++ b/sys/vm/vm_page.h
@@ -61,7 +61,7 @@
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*
- * $Id: vm_page.h,v 1.17 1995/03/26 23:33:14 davidg Exp $
+ * $Id: vm_page.h,v 1.18 1995/04/23 08:05:49 bde Exp $
*/
/*
@@ -136,34 +136,38 @@ struct vm_page {
#define PG_CACHE 0x4000 /* On VMIO cache */
#define PG_FREE 0x8000 /* page is in free list */
-#if VM_PAGE_DEBUG
-#define VM_PAGE_CHECK(mem) { \
- if ((((unsigned int) mem) < ((unsigned int) &vm_page_array[0])) || \
- (((unsigned int) mem) > \
- ((unsigned int) &vm_page_array[last_page-first_page])) || \
- ((mem->flags & (PG_ACTIVE | PG_INACTIVE)) == \
- (PG_ACTIVE | PG_INACTIVE))) \
- panic("vm_page_check: not valid!"); \
-}
-#else /* VM_PAGE_DEBUG */
-#define VM_PAGE_CHECK(mem)
-#endif /* VM_PAGE_DEBUG */
+/*
+ * Misc constants.
+ */
+
+#define ACT_DECLINE 1
+#define ACT_ADVANCE 3
+#define ACT_MAX 100
+#define PFCLUSTER_BEHIND 3
+#define PFCLUSTER_AHEAD 3
#ifdef KERNEL
/*
- * Each pageable resident page falls into one of three lists:
+ * Each pageable resident page falls into one of four lists:
*
* free
* Available for allocation now.
+ *
+ * The following are all LRU sorted:
+ *
+ * cache
+ * Almost available for allocation. Still in an
+ * object, but clean and immediately freeable at
+ * non-interrupt times.
+ *
* inactive
- * Not referenced in any map, but still has an
- * object/offset-page mapping, and may be dirty.
+ * Low activity, candidates for reclaimation.
* This is the list of pages that should be
* paged out next.
+ *
* active
- * A list of pages which have been placed in
- * at least one physical map. This list is
- * ordered, in LRU-like fashion.
+ * Pages that are "active" i.e. they have been
+ * recently referenced.
*/
extern struct pglist vm_page_queue_free; /* memory free queue */
@@ -190,9 +194,6 @@ extern vm_offset_t last_phys_addr; /* physical address for last_page */
#define PHYS_TO_VM_PAGE(pa) \
(&vm_page_array[atop(pa) - first_page ])
-extern simple_lock_data_t vm_page_queue_lock; /* lock on active and inactive page queues */
-extern simple_lock_data_t vm_page_queue_free_lock; /* lock on free page queue */
-
/*
* Functions implemented as macros
*/
@@ -210,9 +211,6 @@ extern simple_lock_data_t vm_page_queue_free_lock; /* lock on free page queue */
} \
}
-#define vm_page_lock_queues() simple_lock(&vm_page_queue_lock)
-#define vm_page_unlock_queues() simple_unlock(&vm_page_queue_lock)
-
#if PAGE_SIZE == 4096
#define VM_PAGE_BITS_ALL 0xff
#endif
@@ -293,9 +291,4 @@ vm_page_protect(vm_page_t mem, int prot)
#endif /* KERNEL */
-
-#define ACT_DECLINE 1
-#define ACT_ADVANCE 3
-#define ACT_MAX 100
-
#endif /* !_VM_PAGE_ */
diff --git a/sys/vm/vm_pageout.c b/sys/vm/vm_pageout.c
index 55e7d0e..92e5713 100644
--- a/sys/vm/vm_pageout.c
+++ b/sys/vm/vm_pageout.c
@@ -65,7 +65,7 @@
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*
- * $Id: vm_pageout.c,v 1.51 1995/05/30 08:16:18 rgrimes Exp $
+ * $Id: vm_pageout.c,v 1.52 1995/07/10 08:53:22 davidg Exp $
*/
/*
@@ -86,8 +86,8 @@
#include <vm/vm_page.h>
#include <vm/vm_pageout.h>
#include <vm/vm_kern.h>
+#include <vm/vm_pager.h>
#include <vm/swap_pager.h>
-#include <vm/vnode_pager.h>
int vm_pages_needed; /* Event on which pageout daemon sleeps */
@@ -112,181 +112,163 @@ int vm_page_max_wired; /* XXX max # of wired pages system-wide */
/*
* vm_pageout_clean:
- * cleans a vm_page
+ *
+ * Clean the page and remove it from the laundry.
+ *
+ * We set the busy bit to cause potential page faults on this page to
+ * block.
+ *
+ * And we set pageout-in-progress to keep the object from disappearing
+ * during pageout. This guarantees that the page won't move from the
+ * inactive queue. (However, any other page on the inactive queue may
+ * move!)
*/
int
vm_pageout_clean(m, sync)
- register vm_page_t m;
+ vm_page_t m;
int sync;
{
- /*
- * Clean the page and remove it from the laundry.
- *
- * We set the busy bit to cause potential page faults on this page to
- * block.
- *
- * And we set pageout-in-progress to keep the object from disappearing
- * during pageout. This guarantees that the page won't move from the
- * inactive queue. (However, any other page on the inactive queue may
- * move!)
- */
-
register vm_object_t object;
- register vm_pager_t pager;
int pageout_status[VM_PAGEOUT_PAGE_COUNT];
- vm_page_t ms[VM_PAGEOUT_PAGE_COUNT], mb[VM_PAGEOUT_PAGE_COUNT];
- int pageout_count, b_pageout_count;
+ vm_page_t mc[2*VM_PAGEOUT_PAGE_COUNT];
+ int pageout_count;
int anyok = 0;
- int i;
+ int i, forward_okay, backward_okay, page_base;
vm_offset_t offset = m->offset;
object = m->object;
- if (!object) {
- printf("pager: object missing\n");
- return 0;
- }
- if (!object->pager && (object->flags & OBJ_INTERNAL) == 0) {
- printf("pager: non internal obj without pager\n");
- }
+
/*
- * Try to collapse the object before making a pager for it. We must
- * unlock the page queues first. We try to defer the creation of a
- * pager until all shadows are not paging. This allows
- * vm_object_collapse to work better and helps control swap space
- * size. (J. Dyson 11 Nov 93)
+ * If not OBJT_SWAP, additional memory may be needed to do the pageout.
+ * Try to avoid the deadlock.
*/
-
- if (!object->pager &&
- (cnt.v_free_count + cnt.v_cache_count) < cnt.v_pageout_free_min)
+ if ((sync != VM_PAGEOUT_FORCE) &&
+ (object->type != OBJT_SWAP) &&
+ ((cnt.v_free_count + cnt.v_cache_count) < cnt.v_pageout_free_min))
return 0;
+ /*
+ * Don't mess with the page if it's busy.
+ */
if ((!sync && m->hold_count != 0) ||
((m->busy != 0) || (m->flags & PG_BUSY)))
return 0;
- if (!sync && object->shadow) {
+ /*
+ * Try collapsing before it's too late.
+ */
+ if (!sync && object->backing_object) {
vm_object_collapse(object);
}
+ mc[VM_PAGEOUT_PAGE_COUNT] = m;
pageout_count = 1;
- ms[0] = m;
-
- pager = object->pager;
- if (pager) {
- for (i = 1; i < vm_pageout_page_count; i++) {
- vm_page_t mt;
-
- ms[i] = mt = vm_page_lookup(object, offset + i * NBPG);
- if (mt) {
- if (mt->flags & (PG_BUSY|PG_CACHE) || mt->busy)
- break;
- /*
- * we can cluster ONLY if: ->> the page is NOT
- * busy, and is NOT clean the page is not
- * wired, busy, held, or mapped into a buffer.
- * and one of the following: 1) The page is
- * inactive, or a seldom used active page. 2)
- * or we force the issue.
- */
- vm_page_test_dirty(mt);
- if ((mt->dirty & mt->valid) != 0
- && ((mt->flags & PG_INACTIVE) ||
- (sync == VM_PAGEOUT_FORCE))
- && (mt->wire_count == 0)
- && (mt->hold_count == 0))
- pageout_count++;
- else
- break;
- } else
- break;
- }
-
- if ((pageout_count < vm_pageout_page_count) && (offset != 0)) {
- b_pageout_count = 0;
- for (i = 0; i < vm_pageout_page_count-pageout_count; i++) {
- vm_page_t mt;
+ page_base = VM_PAGEOUT_PAGE_COUNT;
+ forward_okay = TRUE;
+ if (offset != 0)
+ backward_okay = TRUE;
+ else
+ backward_okay = FALSE;
+ /*
+ * Scan object for clusterable pages.
+ *
+ * We can cluster ONLY if: ->> the page is NOT
+ * clean, wired, busy, held, or mapped into a
+ * buffer, and one of the following:
+ * 1) The page is inactive, or a seldom used
+ * active page.
+ * -or-
+ * 2) we force the issue.
+ */
+ for (i = 1; (i < vm_pageout_page_count) && (forward_okay || backward_okay); i++) {
+ vm_page_t p;
- mt = vm_page_lookup(object, offset - (i + 1) * NBPG);
- if (mt) {
- if (mt->flags & (PG_BUSY|PG_CACHE) || mt->busy)
- break;
- vm_page_test_dirty(mt);
- if ((mt->dirty & mt->valid) != 0
- && ((mt->flags & PG_INACTIVE) ||
- (sync == VM_PAGEOUT_FORCE))
- && (mt->wire_count == 0)
- && (mt->hold_count == 0)) {
- mb[b_pageout_count] = mt;
- b_pageout_count++;
- if ((offset - (i + 1) * NBPG) == 0)
- break;
- } else
- break;
- } else
- break;
+ /*
+ * See if forward page is clusterable.
+ */
+ if (forward_okay) {
+ /*
+ * Stop forward scan at end of object.
+ */
+ if ((offset + i * PAGE_SIZE) > object->size) {
+ forward_okay = FALSE;
+ goto do_backward;
}
- if (b_pageout_count > 0) {
- for(i=pageout_count - 1;i>=0;--i) {
- ms[i+b_pageout_count] = ms[i];
+ p = vm_page_lookup(object, offset + i * PAGE_SIZE);
+ if (p) {
+ if ((p->flags & (PG_BUSY|PG_CACHE)) || p->busy) {
+ forward_okay = FALSE;
+ goto do_backward;
}
- for(i=0;i<b_pageout_count;i++) {
- ms[i] = mb[b_pageout_count - (i + 1)];
+ vm_page_test_dirty(p);
+ if ((p->dirty & p->valid) != 0 &&
+ ((p->flags & PG_INACTIVE) ||
+ (sync == VM_PAGEOUT_FORCE)) &&
+ (p->wire_count == 0) &&
+ (p->hold_count == 0)) {
+ mc[VM_PAGEOUT_PAGE_COUNT + i] = p;
+ pageout_count++;
+ if (pageout_count == vm_pageout_page_count)
+ break;
+ } else {
+ forward_okay = FALSE;
}
- pageout_count += b_pageout_count;
+ } else {
+ forward_okay = FALSE;
}
}
-
+do_backward:
/*
- * we allow reads during pageouts...
+ * See if backward page is clusterable.
*/
- for (i = 0; i < pageout_count; i++) {
- ms[i]->flags |= PG_BUSY;
- vm_page_protect(ms[i], VM_PROT_READ);
- }
- object->paging_in_progress += pageout_count;
- } else {
-
- m->flags |= PG_BUSY;
-
- vm_page_protect(m, VM_PROT_READ);
-
- object->paging_in_progress++;
-
- pager = vm_pager_allocate(PG_DFLT, 0,
- object->size, VM_PROT_ALL, 0);
- if (pager != NULL) {
- object->pager = pager;
+ if (backward_okay) {
+ /*
+ * Stop backward scan at beginning of object.
+ */
+ if ((offset - i * PAGE_SIZE) == 0) {
+ backward_okay = FALSE;
+ }
+ p = vm_page_lookup(object, offset - i * PAGE_SIZE);
+ if (p) {
+ if ((p->flags & (PG_BUSY|PG_CACHE)) || p->busy) {
+ backward_okay = FALSE;
+ continue;
+ }
+ vm_page_test_dirty(p);
+ if ((p->dirty & p->valid) != 0 &&
+ ((p->flags & PG_INACTIVE) ||
+ (sync == VM_PAGEOUT_FORCE)) &&
+ (p->wire_count == 0) &&
+ (p->hold_count == 0)) {
+ mc[VM_PAGEOUT_PAGE_COUNT - i] = p;
+ pageout_count++;
+ page_base--;
+ if (pageout_count == vm_pageout_page_count)
+ break;
+ } else {
+ backward_okay = FALSE;
+ }
+ } else {
+ backward_okay = FALSE;
+ }
}
}
/*
- * If there is no pager for the page, use the default pager. If
- * there's no place to put the page at the moment, leave it in the
- * laundry and hope that there will be paging space later.
+ * we allow reads during pageouts...
*/
-
- if ((pager && pager->pg_type == PG_SWAP) ||
- (cnt.v_free_count + cnt.v_cache_count) >= cnt.v_pageout_free_min) {
- if (pageout_count == 1) {
- pageout_status[0] = pager ?
- vm_pager_put(pager, m,
- ((sync || (object == kernel_object)) ? TRUE : FALSE)) :
- VM_PAGER_FAIL;
- } else {
- if (!pager) {
- for (i = 0; i < pageout_count; i++)
- pageout_status[i] = VM_PAGER_FAIL;
- } else {
- vm_pager_put_pages(pager, ms, pageout_count,
- ((sync || (object == kernel_object)) ? TRUE : FALSE),
- pageout_status);
- }
- }
- } else {
- for (i = 0; i < pageout_count; i++)
- pageout_status[i] = VM_PAGER_FAIL;
+ for (i = page_base; i < (page_base + pageout_count); i++) {
+ mc[i]->flags |= PG_BUSY;
+ vm_page_protect(mc[i], VM_PROT_READ);
}
+ object->paging_in_progress += pageout_count;
+
+ vm_pager_put_pages(object, &mc[page_base], pageout_count,
+ ((sync || (object == kernel_object)) ? TRUE : FALSE),
+ pageout_status);
for (i = 0; i < pageout_count; i++) {
+ vm_page_t mt = mc[page_base + i];
+
switch (pageout_status[i]) {
case VM_PAGER_OK:
++anyok;
@@ -300,8 +282,8 @@ vm_pageout_clean(m, sync)
* essentially lose the changes by pretending it
* worked.
*/
- pmap_clear_modify(VM_PAGE_TO_PHYS(ms[i]));
- ms[i]->dirty = 0;
+ pmap_clear_modify(VM_PAGE_TO_PHYS(mt));
+ mt->dirty = 0;
break;
case VM_PAGER_ERROR:
case VM_PAGER_FAIL:
@@ -310,8 +292,8 @@ vm_pageout_clean(m, sync)
* page so it doesn't clog the inactive list. (We
* will try paging out it again later).
*/
- if (ms[i]->flags & PG_INACTIVE)
- vm_page_activate(ms[i]);
+ if (mt->flags & PG_INACTIVE)
+ vm_page_activate(mt);
break;
case VM_PAGER_AGAIN:
break;
@@ -326,14 +308,14 @@ vm_pageout_clean(m, sync)
*/
if (pageout_status[i] != VM_PAGER_PEND) {
vm_object_pip_wakeup(object);
- if ((ms[i]->flags & (PG_REFERENCED|PG_WANTED)) ||
- pmap_is_referenced(VM_PAGE_TO_PHYS(ms[i]))) {
- pmap_clear_reference(VM_PAGE_TO_PHYS(ms[i]));
- ms[i]->flags &= ~PG_REFERENCED;
- if (ms[i]->flags & PG_INACTIVE)
- vm_page_activate(ms[i]);
+ if ((mt->flags & (PG_REFERENCED|PG_WANTED)) ||
+ pmap_is_referenced(VM_PAGE_TO_PHYS(mt))) {
+ pmap_clear_reference(VM_PAGE_TO_PHYS(mt));
+ mt->flags &= ~PG_REFERENCED;
+ if (mt->flags & PG_INACTIVE)
+ vm_page_activate(mt);
}
- PAGE_WAKEUP(ms[i]);
+ PAGE_WAKEUP(mt);
}
}
return anyok;
@@ -345,7 +327,7 @@ vm_pageout_clean(m, sync)
* deactivate enough pages to satisfy the inactive target
* requirements or if vm_page_proc_limit is set, then
* deactivate all of the pages in the object and its
- * shadows.
+ * backing_objects.
*
* The object and map must be locked.
*/
@@ -364,16 +346,18 @@ vm_pageout_object_deactivate_pages(map, object, count, map_remove_only)
if (count == 0)
count = 1;
- if (object->pager && (object->pager->pg_type == PG_DEVICE))
+ if (object->type == OBJT_DEVICE)
return 0;
- if (object->shadow) {
- if (object->shadow->ref_count == 1)
- dcount += vm_pageout_object_deactivate_pages(map, object->shadow, count / 2 + 1, map_remove_only);
+ if (object->backing_object) {
+ if (object->backing_object->ref_count == 1)
+ dcount += vm_pageout_object_deactivate_pages(map,
+ object->backing_object, count / 2 + 1, map_remove_only);
else
- vm_pageout_object_deactivate_pages(map, object->shadow, count, 1);
+ vm_pageout_object_deactivate_pages(map,
+ object->backing_object, count, 1);
}
- if (object->paging_in_progress || !vm_object_lock_try(object))
+ if (object->paging_in_progress)
return dcount;
/*
@@ -384,7 +368,6 @@ vm_pageout_object_deactivate_pages(map, object, count, map_remove_only)
while (p && (rcount-- > 0)) {
next = p->listq.tqe_next;
cnt.v_pdpages++;
- vm_page_lock_queues();
if (p->wire_count != 0 ||
p->hold_count != 0 ||
p->busy != 0 ||
@@ -427,8 +410,6 @@ vm_pageout_object_deactivate_pages(map, object, count, map_remove_only)
++dcount;
if (count <= 0 &&
cnt.v_inactive_count > cnt.v_inactive_target) {
- vm_page_unlock_queues();
- vm_object_unlock(object);
return dcount;
}
}
@@ -447,10 +428,8 @@ vm_pageout_object_deactivate_pages(map, object, count, map_remove_only)
} else if ((p->flags & (PG_INACTIVE | PG_BUSY)) == PG_INACTIVE) {
vm_page_protect(p, VM_PROT_NONE);
}
- vm_page_unlock_queues();
p = next;
}
- vm_object_unlock(object);
return dcount;
}
@@ -505,7 +484,7 @@ vm_req_vmdaemon()
static int lastrun = 0;
if ((ticks > (lastrun + hz / 10)) || (ticks < lastrun)) {
- wakeup((caddr_t) &vm_daemon_needed);
+ wakeup(&vm_daemon_needed);
lastrun = ticks;
}
}
@@ -602,15 +581,14 @@ rescan1:
struct vnode *vp = NULL;
object = m->object;
- if ((object->flags & OBJ_DEAD) || !vm_object_lock_try(object)) {
+ if (object->flags & OBJ_DEAD) {
m = next;
continue;
}
- if (object->pager && object->pager->pg_type == PG_VNODE) {
- vp = ((vn_pager_t) object->pager->pg_data)->vnp_vp;
+ if (object->type == OBJT_VNODE) {
+ vp = object->handle;
if (VOP_ISLOCKED(vp) || vget(vp, 1)) {
- vm_object_unlock(object);
if (object->flags & OBJ_WRITEABLE)
++vnodes_skipped;
m = next;
@@ -629,8 +607,6 @@ rescan1:
if (vp)
vput(vp);
- vm_object_unlock(object);
-
if (!next) {
break;
}
@@ -744,7 +720,7 @@ rescan1:
(cnt.v_cache_count + cnt.v_free_count) < cnt.v_free_min) {
if (!vfs_update_wakeup) {
vfs_update_wakeup = 1;
- wakeup((caddr_t) &vfs_update_wakeup);
+ wakeup(&vfs_update_wakeup);
}
}
/*
@@ -804,7 +780,7 @@ rescan1:
bigproc->p_estcpu = 0;
bigproc->p_nice = PRIO_MIN;
resetpriority(bigproc);
- wakeup((caddr_t) &cnt.v_free_count);
+ wakeup(&cnt.v_free_count);
}
}
return force_wakeup;
@@ -853,7 +829,7 @@ vm_pageout()
vm_page_max_wired = cnt.v_free_count / 3;
- (void) swap_pager_alloc(0, 0, 0, 0);
+ swap_pager_swap_init();
/*
* The pageout daemon is never done, so loop forever.
*/
@@ -864,7 +840,7 @@ vm_pageout()
((cnt.v_free_count >= cnt.v_free_reserved) &&
(cnt.v_free_count + cnt.v_cache_count >= cnt.v_free_min))) {
vm_pages_needed = 0;
- tsleep((caddr_t) &vm_pages_needed, PVM, "psleep", 0);
+ tsleep(&vm_pages_needed, PVM, "psleep", 0);
}
vm_pages_needed = 0;
splx(s);
@@ -872,8 +848,8 @@ vm_pageout()
vm_pager_sync();
vm_pageout_scan();
vm_pager_sync();
- wakeup((caddr_t) &cnt.v_free_count);
- wakeup((caddr_t) kmem_map);
+ wakeup(&cnt.v_free_count);
+ wakeup(kmem_map);
}
}
@@ -884,8 +860,8 @@ vm_daemon()
struct proc *p;
while (TRUE) {
- tsleep((caddr_t) &vm_daemon_needed, PUSER, "psleep", 0);
- if( vm_pageout_req_swapout) {
+ tsleep(&vm_daemon_needed, PUSER, "psleep", 0);
+ if (vm_pageout_req_swapout) {
swapout_procs();
vm_pageout_req_swapout = 0;
}
@@ -934,27 +910,22 @@ vm_daemon()
(vm_map_entry_t) 0, &overage, vm_pageout_object_deactivate_pages);
}
}
- }
- /*
- * we remove cached objects that have no RSS...
- */
-restart:
- vm_object_cache_lock();
- object = vm_object_cached_list.tqh_first;
- while (object) {
- vm_object_cache_unlock();
/*
- * if there are no resident pages -- get rid of the object
+ * we remove cached objects that have no RSS...
*/
- if (object->resident_page_count == 0) {
- if (object != vm_object_lookup(object->pager))
- panic("vm_object_cache_trim: I'm sooo confused.");
- pager_cache(object, FALSE);
- goto restart;
+restart:
+ object = vm_object_cached_list.tqh_first;
+ while (object) {
+ /*
+ * if there are no resident pages -- get rid of the object
+ */
+ if (object->resident_page_count == 0) {
+ vm_object_reference(object);
+ pager_cache(object, FALSE);
+ goto restart;
+ }
+ object = object->cached_list.tqe_next;
}
- object = object->cached_list.tqe_next;
- vm_object_cache_lock();
}
- vm_object_cache_unlock();
}
diff --git a/sys/vm/vm_pageout.h b/sys/vm/vm_pageout.h
index d1da63c..b908497 100644
--- a/sys/vm/vm_pageout.h
+++ b/sys/vm/vm_pageout.h
@@ -61,7 +61,7 @@
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*
- * $Id: vm_pageout.h,v 1.11 1995/04/09 06:03:55 davidg Exp $
+ * $Id: vm_pageout.h,v 1.12 1995/05/30 08:16:20 rgrimes Exp $
*/
#ifndef _VM_VM_PAGEOUT_H_
@@ -77,7 +77,6 @@
extern int vm_page_max_wired;
extern int vm_pages_needed; /* should be some "event" structure */
-simple_lock_data_t vm_pages_needed_lock;
extern int vm_pageout_pages_needed;
#define VM_PAGEOUT_ASYNC 0
@@ -97,7 +96,7 @@ pagedaemon_wakeup()
{
if (!vm_pages_needed && curproc != pageproc) {
vm_pages_needed++;
- wakeup((caddr_t) &vm_pages_needed);
+ wakeup(&vm_pages_needed);
}
}
@@ -111,13 +110,13 @@ vm_wait()
s = splhigh();
if (curproc == pageproc) {
vm_pageout_pages_needed = 1;
- tsleep((caddr_t) &vm_pageout_pages_needed, PSWP, "vmwait", 0);
+ tsleep(&vm_pageout_pages_needed, PSWP, "vmwait", 0);
} else {
if (!vm_pages_needed) {
vm_pages_needed++;
- wakeup((caddr_t) &vm_pages_needed);
+ wakeup(&vm_pages_needed);
}
- tsleep((caddr_t) &cnt.v_free_count, PVM, "vmwait", 0);
+ tsleep(&cnt.v_free_count, PVM, "vmwait", 0);
}
splx(s);
}
diff --git a/sys/vm/vm_pager.c b/sys/vm/vm_pager.c
index f7f1976..b897c76 100644
--- a/sys/vm/vm_pager.c
+++ b/sys/vm/vm_pager.c
@@ -61,7 +61,7 @@
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*
- * $Id: vm_pager.c,v 1.14 1995/04/25 06:22:47 davidg Exp $
+ * $Id: vm_pager.c,v 1.15 1995/05/10 18:56:07 davidg Exp $
*/
/*
@@ -79,20 +79,21 @@
#include <vm/vm.h>
#include <vm/vm_page.h>
#include <vm/vm_kern.h>
+#include <vm/vm_pager.h>
+extern struct pagerops defaultpagerops;
extern struct pagerops swappagerops;
extern struct pagerops vnodepagerops;
extern struct pagerops devicepagerops;
struct pagerops *pagertab[] = {
- &swappagerops, /* PG_SWAP */
- &vnodepagerops, /* PG_VNODE */
- &devicepagerops, /* PG_DEV */
+ &defaultpagerops, /* OBJT_DEFAULT */
+ &swappagerops, /* OBJT_SWAP */
+ &vnodepagerops, /* OBJT_VNODE */
+ &devicepagerops, /* OBJT_DEVICE */
};
int npagers = sizeof(pagertab) / sizeof(pagertab[0]);
-struct pagerops *dfltpagerops = NULL; /* default pager */
-
/*
* Kernel address space for mapping pages.
* Used by pagers where KVAs are needed for IO.
@@ -119,10 +120,8 @@ vm_pager_init()
* Initialize known pagers
*/
for (pgops = pagertab; pgops < &pagertab[npagers]; pgops++)
- if (pgops)
+ if (pgops && ((*pgops)->pgo_init != NULL))
(*(*pgops)->pgo_init) ();
- if (dfltpagerops == NULL)
- panic("no default pager");
}
void
@@ -154,9 +153,9 @@ vm_pager_bufferinit()
* Size, protection and offset parameters are passed in for pagers that
* need to perform page-level validation (e.g. the device pager).
*/
-vm_pager_t
+vm_object_t
vm_pager_allocate(type, handle, size, prot, off)
- int type;
+ objtype_t type;
void *handle;
vm_size_t size;
vm_prot_t prot;
@@ -164,84 +163,49 @@ vm_pager_allocate(type, handle, size, prot, off)
{
struct pagerops *ops;
- ops = (type == PG_DFLT) ? dfltpagerops : pagertab[type];
+ ops = pagertab[type];
if (ops)
return ((*ops->pgo_alloc) (handle, size, prot, off));
return (NULL);
}
void
-vm_pager_deallocate(pager)
- vm_pager_t pager;
+vm_pager_deallocate(object)
+ vm_object_t object;
{
- if (pager == NULL)
- panic("vm_pager_deallocate: null pager");
-
- (*pager->pg_ops->pgo_dealloc) (pager);
+ (*pagertab[object->type]->pgo_dealloc) (object);
}
int
-vm_pager_get_pages(pager, m, count, reqpage, sync)
- vm_pager_t pager;
+vm_pager_get_pages(object, m, count, reqpage)
+ vm_object_t object;
vm_page_t *m;
int count;
int reqpage;
- boolean_t sync;
{
- int i;
-
- if (pager == NULL) {
- for (i = 0; i < count; i++) {
- if (i != reqpage) {
- PAGE_WAKEUP(m[i]);
- vm_page_free(m[i]);
- }
- }
- vm_page_zero_fill(m[reqpage]);
- return VM_PAGER_OK;
- }
- if (pager->pg_ops->pgo_getpages == 0) {
- for (i = 0; i < count; i++) {
- if (i != reqpage) {
- PAGE_WAKEUP(m[i]);
- vm_page_free(m[i]);
- }
- }
- return (VM_PAGER_GET(pager, m[reqpage], sync));
- } else {
- return (VM_PAGER_GET_MULTI(pager, m, count, reqpage, sync));
- }
+ return ((*pagertab[object->type]->pgo_getpages)(object, m, count, reqpage));
}
int
-vm_pager_put_pages(pager, m, count, sync, rtvals)
- vm_pager_t pager;
+vm_pager_put_pages(object, m, count, sync, rtvals)
+ vm_object_t object;
vm_page_t *m;
int count;
boolean_t sync;
int *rtvals;
{
- int i;
-
- if (pager->pg_ops->pgo_putpages)
- return (VM_PAGER_PUT_MULTI(pager, m, count, sync, rtvals));
- else {
- for (i = 0; i < count; i++) {
- rtvals[i] = VM_PAGER_PUT(pager, m[i], sync);
- }
- return rtvals[0];
- }
+ return ((*pagertab[object->type]->pgo_putpages)(object, m, count, sync, rtvals));
}
boolean_t
-vm_pager_has_page(pager, offset)
- vm_pager_t pager;
+vm_pager_has_page(object, offset, before, after)
+ vm_object_t object;
vm_offset_t offset;
+ int *before;
+ int *after;
{
- if (pager == NULL)
- panic("vm_pager_has_page: null pager");
- return ((*pager->pg_ops->pgo_haspage) (pager, offset));
+ return ((*pagertab[object->type]->pgo_haspage) (object, offset, before, after));
}
/*
@@ -254,23 +218,9 @@ vm_pager_sync()
struct pagerops **pgops;
for (pgops = pagertab; pgops < &pagertab[npagers]; pgops++)
- if (pgops)
- (*(*pgops)->pgo_putpage) (NULL, NULL, 0);
-}
-
-#if 0
-void
-vm_pager_cluster(pager, offset, loff, hoff)
- vm_pager_t pager;
- vm_offset_t offset;
- vm_offset_t *loff;
- vm_offset_t *hoff;
-{
- if (pager == NULL)
- panic("vm_pager_cluster: null pager");
- return ((*pager->pg_ops->pgo_cluster) (pager, offset, loff, hoff));
+ if (pgops && ((*pgops)->pgo_sync != NULL))
+ (*(*pgops)->pgo_sync) ();
}
-#endif
vm_offset_t
vm_pager_map_page(m)
@@ -303,16 +253,16 @@ vm_pager_atop(kva)
return (PHYS_TO_VM_PAGE(pa));
}
-vm_pager_t
-vm_pager_lookup(pglist, handle)
- register struct pagerlst *pglist;
- caddr_t handle;
+vm_object_t
+vm_pager_object_lookup(pg_list, handle)
+ register struct pagerlst *pg_list;
+ void *handle;
{
- register vm_pager_t pager;
+ register vm_object_t object;
- for (pager = pglist->tqh_first; pager; pager = pager->pg_list.tqe_next)
- if (pager->pg_handle == handle)
- return (pager);
+ for (object = pg_list->tqh_first; object != NULL; object = object->pager_object_list.tqe_next)
+ if (object->handle == handle)
+ return (object);
return (NULL);
}
@@ -328,14 +278,10 @@ pager_cache(object, should_cache)
if (object == NULL)
return (KERN_INVALID_ARGUMENT);
- vm_object_cache_lock();
- vm_object_lock(object);
if (should_cache)
object->flags |= OBJ_CANPERSIST;
else
object->flags &= ~OBJ_CANPERSIST;
- vm_object_unlock(object);
- vm_object_cache_unlock();
vm_object_deallocate(object);
@@ -355,7 +301,7 @@ getpbuf()
/* get a bp from the swap buffer header pool */
while ((bp = bswlist.tqh_first) == NULL) {
bswneeded = 1;
- tsleep((caddr_t) &bswneeded, PVM, "wswbuf", 0);
+ tsleep(&bswneeded, PVM, "wswbuf", 0);
}
TAILQ_REMOVE(&bswlist, bp, b_freelist);
splx(s);
@@ -416,13 +362,13 @@ relpbuf(bp)
pbrelvp(bp);
if (bp->b_flags & B_WANTED)
- wakeup((caddr_t) bp);
+ wakeup(bp);
TAILQ_INSERT_HEAD(&bswlist, bp, b_freelist);
if (bswneeded) {
bswneeded = 0;
- wakeup((caddr_t) &bswneeded);
+ wakeup(&bswneeded);
}
splx(s);
}
diff --git a/sys/vm/vm_pager.h b/sys/vm/vm_pager.h
index 1cab34a..a367f4b 100644
--- a/sys/vm/vm_pager.h
+++ b/sys/vm/vm_pager.h
@@ -1,4 +1,3 @@
-
/*
* Copyright (c) 1990 University of Utah.
* Copyright (c) 1991, 1993
@@ -37,56 +36,28 @@
* SUCH DAMAGE.
*
* @(#)vm_pager.h 8.4 (Berkeley) 1/12/94
- * $Id: vm_pager.h,v 1.6 1995/03/16 18:17:32 bde Exp $
+ * $Id: vm_pager.h,v 1.7 1995/05/10 18:56:08 davidg Exp $
*/
/*
* Pager routine interface definition.
- * For BSD we use a cleaner version of the internal pager interface.
*/
#ifndef _VM_PAGER_
#define _VM_PAGER_
-TAILQ_HEAD(pagerlst, pager_struct);
-
-struct pager_struct {
- TAILQ_ENTRY(pager_struct) pg_list; /* links for list management */
- void *pg_handle; /* ext. handle (vp, dev, fp) */
- int pg_type; /* type of pager */
- struct pagerops *pg_ops; /* pager operations */
- void *pg_data; /* private pager data */
-};
-
-/* pager types */
-#define PG_DFLT -1
-#define PG_SWAP 0
-#define PG_VNODE 1
-#define PG_DEVICE 2
-
-/* flags */
-#define PG_CLUSTERGET 1
-#define PG_CLUSTERPUT 2
+TAILQ_HEAD(pagerlst, vm_object);
struct pagerops {
void (*pgo_init) __P((void)); /* Initialize pager. */
- vm_pager_t(*pgo_alloc) __P((void *, vm_size_t, vm_prot_t, vm_offset_t)); /* Allocate pager. */
- void (*pgo_dealloc) __P((vm_pager_t)); /* Disassociate. */
- int (*pgo_getpage) __P((vm_pager_t, vm_page_t, boolean_t));
- int (*pgo_getpages) __P((vm_pager_t, vm_page_t *, int, int, boolean_t)); /* Get (read) page. */
- int (*pgo_putpage) __P((vm_pager_t, vm_page_t, boolean_t));
- int (*pgo_putpages) __P((vm_pager_t, vm_page_t *, int, boolean_t, int *)); /* Put (write) page. */
- boolean_t(*pgo_haspage) __P((vm_pager_t, vm_offset_t)); /* Does pager have page? */
+ vm_object_t (*pgo_alloc) __P((void *, vm_size_t, vm_prot_t, vm_offset_t)); /* Allocate pager. */
+ void (*pgo_dealloc) __P((vm_object_t)); /* Disassociate. */
+ int (*pgo_getpages) __P((vm_object_t, vm_page_t *, int, int)); /* Get (read) page. */
+ int (*pgo_putpages) __P((vm_object_t, vm_page_t *, int, boolean_t, int *)); /* Put (write) page. */
+ boolean_t (*pgo_haspage) __P((vm_object_t, vm_offset_t, int *, int *)); /* Does pager have page? */
+ void (*pgo_sync) __P((void));
};
-#define VM_PAGER_ALLOC(h, s, p, o) (*(pg)->pg_ops->pgo_alloc)(h, s, p, o)
-#define VM_PAGER_DEALLOC(pg) (*(pg)->pg_ops->pgo_dealloc)(pg)
-#define VM_PAGER_GET(pg, m, s) (*(pg)->pg_ops->pgo_getpage)(pg, m, s)
-#define VM_PAGER_GET_MULTI(pg, m, c, r, s) (*(pg)->pg_ops->pgo_getpages)(pg, m, c, r, s)
-#define VM_PAGER_PUT(pg, m, s) (*(pg)->pg_ops->pgo_putpage)(pg, m, s)
-#define VM_PAGER_PUT_MULTI(pg, m, c, s, rtval) (*(pg)->pg_ops->pgo_putpages)(pg, m, c, s, rtval)
-#define VM_PAGER_HASPAGE(pg, o) (*(pg)->pg_ops->pgo_haspage)(pg, o)
-
/*
* get/put return values
* OK operation was successful
@@ -104,41 +75,20 @@ struct pagerops {
#define VM_PAGER_AGAIN 5
#ifdef KERNEL
-extern struct pagerops *dfltpagerops;
-
-vm_pager_t vm_pager_allocate __P((int, void *, vm_size_t, vm_prot_t, vm_offset_t));
+vm_object_t vm_pager_allocate __P((objtype_t, void *, vm_size_t, vm_prot_t, vm_offset_t));
vm_page_t vm_pager_atop __P((vm_offset_t));
void vm_pager_bufferinit __P((void));
-void vm_pager_deallocate __P((vm_pager_t));
-int vm_pager_get_pages __P((vm_pager_t, vm_page_t *, int, int, boolean_t));
-boolean_t vm_pager_has_page __P((vm_pager_t, vm_offset_t));
+void vm_pager_deallocate __P((vm_object_t));
+int vm_pager_get_pages __P((vm_object_t, vm_page_t *, int, int));
+boolean_t vm_pager_has_page __P((vm_object_t, vm_offset_t, int *, int *));
void vm_pager_init __P((void));
-vm_pager_t vm_pager_lookup __P((struct pagerlst *, caddr_t));
+vm_object_t vm_pager_object_lookup __P((struct pagerlst *, void *));
vm_offset_t vm_pager_map_pages __P((vm_page_t *, int, boolean_t));
vm_offset_t vm_pager_map_page __P((vm_page_t));
-int vm_pager_put_pages __P((vm_pager_t, vm_page_t *, int, boolean_t, int *));
+int vm_pager_put_pages __P((vm_object_t, vm_page_t *, int, boolean_t, int *));
void vm_pager_sync __P((void));
void vm_pager_unmap_pages __P((vm_offset_t, int));
void vm_pager_unmap_page __P((vm_offset_t));
-
-/*
- * XXX compat with old interface
- */
-#define vm_pager_get(p, m, s) \
-({ \
- vm_page_t ml[1]; \
- ml[0] = (m); \
- vm_pager_get_pages(p, ml, 1, 0, s); \
-})
-
-#define vm_pager_put(p, m, s) \
-({ \
- int rtval; \
- vm_page_t ml[1]; \
- ml[0] = (m); \
- vm_pager_put_pages(p, ml, 1, s, &rtval); \
- rtval; \
-})
#endif
#endif /* _VM_PAGER_ */
diff --git a/sys/vm/vm_swap.c b/sys/vm/vm_swap.c
index 9b90074..6f63fae 100644
--- a/sys/vm/vm_swap.c
+++ b/sys/vm/vm_swap.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)vm_swap.c 8.5 (Berkeley) 2/17/94
- * $Id: vm_swap.c,v 1.20 1995/05/25 03:38:11 davidg Exp $
+ * $Id: vm_swap.c,v 1.21 1995/05/30 08:16:21 rgrimes Exp $
*/
#include <sys/param.h>
@@ -109,7 +109,7 @@ swstrategy(bp)
vp->v_numoutput--;
if ((vp->v_flag & VBWAIT) && vp->v_numoutput <= 0) {
vp->v_flag &= ~VBWAIT;
- wakeup((caddr_t) &vp->v_numoutput);
+ wakeup(&vp->v_numoutput);
}
}
sp->sw_vp->v_numoutput++;
diff --git a/sys/vm/vnode_pager.c b/sys/vm/vnode_pager.c
index c24d3e5..6e89635 100644
--- a/sys/vm/vnode_pager.c
+++ b/sys/vm/vnode_pager.c
@@ -2,7 +2,8 @@
* Copyright (c) 1990 University of Utah.
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
- * Copyright (c) 1993,1994 John S. Dyson
+ * Copyright (c) 1993, 1994 John S. Dyson
+ * Copyright (c) 1995, David Greenman
*
* This code is derived from software contributed to Berkeley by
* the Systems Programming Group of the University of Utah Computer
@@ -37,25 +38,17 @@
* SUCH DAMAGE.
*
* from: @(#)vnode_pager.c 7.5 (Berkeley) 4/20/91
- * $Id: vnode_pager.c,v 1.42 1995/07/06 11:48:48 davidg Exp $
+ * $Id: vnode_pager.c,v 1.43 1995/07/09 06:58:03 davidg Exp $
*/
/*
* Page to/from files (vnodes).
- *
- * TODO:
- * pageouts
- * fix credential use (uses current process credentials now)
*/
/*
- * 1) Supports multiple - block reads/writes
- * 2) Bypasses buffer cache for reads
- *
* TODO:
- * Implement getpage/putpage interface for filesystems. Should
+ * Implement VOP_GETPAGES/PUTPAGES interface for filesystems. Will
* greatly re-simplify the vnode_pager.
- *
*/
#include <sys/param.h>
@@ -66,64 +59,34 @@
#include <sys/vnode.h>
#include <sys/uio.h>
#include <sys/mount.h>
+#include <sys/buf.h>
#include <vm/vm.h>
#include <vm/vm_page.h>
+#include <vm/vm_pager.h>
#include <vm/vnode_pager.h>
-#include <sys/buf.h>
-#include <miscfs/specfs/specdev.h>
-
-int vnode_pager_putmulti();
-
-void vnode_pager_init();
-void vnode_pager_dealloc();
-int vnode_pager_getpage();
-int vnode_pager_getmulti();
-int vnode_pager_putpage();
-boolean_t vnode_pager_haspage();
-
struct pagerops vnodepagerops = {
- vnode_pager_init,
+ NULL,
vnode_pager_alloc,
vnode_pager_dealloc,
- vnode_pager_getpage,
- vnode_pager_getmulti,
- vnode_pager_putpage,
- vnode_pager_putmulti,
- vnode_pager_haspage
+ vnode_pager_getpages,
+ vnode_pager_putpages,
+ vnode_pager_haspage,
+ NULL
};
-
-
-static int vnode_pager_input(vn_pager_t vnp, vm_page_t * m, int count, int reqpage);
-static int vnode_pager_output(vn_pager_t vnp, vm_page_t * m, int count, int *rtvals);
-
-extern vm_map_t pager_map;
-
-struct pagerlst vnode_pager_list; /* list of managed vnodes */
-
-#define MAXBP (PAGE_SIZE/DEV_BSIZE);
-
-void
-vnode_pager_init()
-{
- TAILQ_INIT(&vnode_pager_list);
-}
-
/*
* Allocate (or lookup) pager for a vnode.
* Handle is a vnode pointer.
*/
-vm_pager_t
+vm_object_t
vnode_pager_alloc(handle, size, prot, offset)
void *handle;
vm_size_t size;
vm_prot_t prot;
vm_offset_t offset;
{
- register vm_pager_t pager;
- register vn_pager_t vnp;
vm_object_t object;
struct vnode *vp;
@@ -149,49 +112,31 @@ vnode_pager_alloc(handle, size, prot, offset)
* If the object is being terminated, wait for it to
* go away.
*/
- while (((object = vp->v_object) != NULL) && (object->flags & OBJ_DEAD))
+ while (((object = vp->v_object) != NULL) && (object->flags & OBJ_DEAD)) {
tsleep(object, PVM, "vadead", 0);
+ }
- pager = NULL;
- if (object != NULL)
- pager = object->pager;
- if (pager == NULL) {
-
- /*
- * Allocate pager structures
- */
- pager = (vm_pager_t) malloc(sizeof *pager, M_VMPAGER, M_WAITOK);
- vnp = (vn_pager_t) malloc(sizeof *vnp, M_VMPGDATA, M_WAITOK);
-
+ if (object == NULL) {
/*
* And an object of the appropriate size
*/
- object = vm_object_allocate(round_page(size));
+ object = vm_object_allocate(OBJT_VNODE, round_page(size));
object->flags = OBJ_CANPERSIST;
- vm_object_enter(object, pager);
- object->pager = pager;
/*
- * Hold a reference to the vnode and initialize pager data.
+ * Hold a reference to the vnode and initialize object data.
*/
VREF(vp);
- vnp->vnp_flags = 0;
- vnp->vnp_vp = vp;
- vnp->vnp_size = size;
-
- TAILQ_INSERT_TAIL(&vnode_pager_list, pager, pg_list);
- pager->pg_handle = handle;
- pager->pg_type = PG_VNODE;
- pager->pg_ops = &vnodepagerops;
- pager->pg_data = (caddr_t) vnp;
- vp->v_object = (caddr_t) object;
- } else {
+ object->un_pager.vnp.vnp_size = size;
+ object->handle = handle;
+ vp->v_object = object;
+ } else {
/*
- * vm_object_lookup() will remove the object from the cache if
- * found and also gain a reference to the object.
+ * vm_object_reference() will remove the object from the cache if
+ * found and gain a reference to the object.
*/
- (void) vm_object_lookup(pager);
+ vm_object_reference(object);
}
if (vp->v_type == VREG)
@@ -202,134 +147,97 @@ vnode_pager_alloc(handle, size, prot, offset)
vp->v_flag &= ~VOWANT;
wakeup(vp);
}
- return (pager);
+ return (object);
}
void
-vnode_pager_dealloc(pager)
- vm_pager_t pager;
-{
- register vn_pager_t vnp = (vn_pager_t) pager->pg_data;
- register struct vnode *vp;
+vnode_pager_dealloc(object)
vm_object_t object;
+{
+ register struct vnode *vp = object->handle;
- vp = vnp->vnp_vp;
- if (vp) {
- int s = splbio();
+ if (vp == NULL)
+ panic("vnode_pager_dealloc: pager already dealloced");
- object = vp->v_object;
- if (object) {
- while (object->paging_in_progress) {
- object->flags |= OBJ_PIPWNT;
- tsleep(object, PVM, "vnpdea", 0);
- }
+ if (object->paging_in_progress) {
+ int s = splbio();
+ while (object->paging_in_progress) {
+ object->flags |= OBJ_PIPWNT;
+ tsleep(object, PVM, "vnpdea", 0);
}
splx(s);
-
- vp->v_object = NULL;
- vp->v_flag &= ~(VTEXT | VVMIO);
- vp->v_flag |= VAGE;
- vrele(vp);
}
- TAILQ_REMOVE(&vnode_pager_list, pager, pg_list);
- free((caddr_t) vnp, M_VMPGDATA);
- free((caddr_t) pager, M_VMPAGER);
-}
-
-int
-vnode_pager_getmulti(pager, m, count, reqpage, sync)
- vm_pager_t pager;
- vm_page_t *m;
- int count;
- int reqpage;
- boolean_t sync;
-{
- return vnode_pager_input((vn_pager_t) pager->pg_data, m, count, reqpage);
-}
-
-int
-vnode_pager_getpage(pager, m, sync)
- vm_pager_t pager;
- vm_page_t m;
- boolean_t sync;
-{
+ object->handle = NULL;
- vm_page_t marray[1];
-
- if (pager == NULL)
- return FALSE;
- marray[0] = m;
-
- return vnode_pager_input((vn_pager_t) pager->pg_data, marray, 1, 0);
-}
-
-boolean_t
-vnode_pager_putpage(pager, m, sync)
- vm_pager_t pager;
- vm_page_t m;
- boolean_t sync;
-{
- vm_page_t marray[1];
- int rtvals[1];
-
- if (pager == NULL)
- return FALSE;
- marray[0] = m;
- vnode_pager_output((vn_pager_t) pager->pg_data, marray, 1, rtvals);
- return rtvals[0];
-}
-
-int
-vnode_pager_putmulti(pager, m, c, sync, rtvals)
- vm_pager_t pager;
- vm_page_t *m;
- int c;
- boolean_t sync;
- int *rtvals;
-{
- return vnode_pager_output((vn_pager_t) pager->pg_data, m, c, rtvals);
+ vp->v_object = NULL;
+ vp->v_flag &= ~(VTEXT | VVMIO);
+ vp->v_flag |= VAGE;
+ vrele(vp);
}
-
boolean_t
-vnode_pager_haspage(pager, offset)
- vm_pager_t pager;
+vnode_pager_haspage(object, offset, before, after)
+ vm_object_t object;
vm_offset_t offset;
+ int *before;
+ int *after;
{
- register vn_pager_t vnp = (vn_pager_t) pager->pg_data;
- register struct vnode *vp = vnp->vnp_vp;
+ struct vnode *vp = object->handle;
daddr_t bn;
- int err;
- daddr_t block;
+ int err, run;
+ daddr_t startblock, reqblock;
/*
* If filesystem no longer mounted or offset beyond end of file we do
* not have the page.
*/
- if ((vp->v_mount == NULL) || (offset >= vnp->vnp_size))
+ if ((vp->v_mount == NULL) || (offset >= object->un_pager.vnp.vnp_size))
return FALSE;
- block = offset / vp->v_mount->mnt_stat.f_iosize;
- if (incore(vp, block))
- return TRUE;
+ startblock = reqblock = offset / vp->v_mount->mnt_stat.f_iosize;
+ if (startblock > PFCLUSTER_BEHIND)
+ startblock -= PFCLUSTER_BEHIND;
+ else
+ startblock = 0;;
- /*
- * Read the index to find the disk block to read from. If there is no
- * block, report that we don't have this data.
- *
- * Assumes that the vnode has whole page or nothing.
- */
- err = VOP_BMAP(vp, block, (struct vnode **) 0, &bn, 0);
+ if (before != NULL) {
+ /*
+ * Loop looking for a contiguous chunk that includes the
+ * requested page.
+ */
+ while (TRUE) {
+ err = VOP_BMAP(vp, startblock, (struct vnode **) 0, &bn, &run);
+ if (err || bn == -1) {
+ if (startblock < reqblock) {
+ startblock++;
+ continue;
+ }
+ *before = 0;
+ if (after != NULL)
+ *after = 0;
+ return err ? TRUE : FALSE;
+ }
+ if ((startblock + run) < reqblock) {
+ startblock += run + 1;
+ continue;
+ }
+ *before = reqblock - startblock;
+ if (after != NULL)
+ *after = run;
+ return TRUE;
+ }
+ }
+
+ err = VOP_BMAP(vp, reqblock, (struct vnode **) 0, &bn, after);
if (err)
- return (TRUE);
+ return TRUE;
return ((long) bn < 0 ? FALSE : TRUE);
}
/*
* Lets the VM system know about a change in size for a file.
- * If this vnode is mapped into some address space (i.e. we have a pager
- * for it) we adjust our own internal size and flush any cached pages in
+ * We adjust our own internal size and flush any cached pages in
* the associated object that are affected by the size change.
*
* Note: this routine may be invoked as a result of a pager put
@@ -340,37 +248,24 @@ vnode_pager_setsize(vp, nsize)
struct vnode *vp;
u_long nsize;
{
- register vn_pager_t vnp;
- register vm_object_t object;
- vm_pager_t pager;
+ vm_object_t object = vp->v_object;
- /*
- * Not a mapped vnode
- */
- if (vp == NULL || vp->v_type != VREG || vp->v_object == NULL)
+ if (object == NULL)
return;
/*
* Hasn't changed size
*/
- object = vp->v_object;
- if (object == NULL)
- return;
- if ((pager = object->pager) == NULL)
- return;
- vnp = (vn_pager_t) pager->pg_data;
- if (nsize == vnp->vnp_size)
+ if (nsize == object->un_pager.vnp.vnp_size)
return;
/*
* File has shrunk. Toss any cached pages beyond the new EOF.
*/
- if (nsize < vnp->vnp_size) {
- if (round_page((vm_offset_t) nsize) < vnp->vnp_size) {
- vm_object_lock(object);
+ if (nsize < object->un_pager.vnp.vnp_size) {
+ if (round_page((vm_offset_t) nsize) < object->un_pager.vnp.vnp_size) {
vm_object_page_remove(object,
- round_page((vm_offset_t) nsize), vnp->vnp_size, FALSE);
- vm_object_unlock(object);
+ round_page((vm_offset_t) nsize), object->un_pager.vnp.vnp_size, FALSE);
}
/*
* this gets rid of garbage at the end of a page that is now
@@ -389,7 +284,7 @@ vnode_pager_setsize(vp, nsize)
}
}
}
- vnp->vnp_size = (vm_offset_t) nsize;
+ object->un_pager.vnp.vnp_size = (vm_offset_t) nsize;
object->size = round_page(nsize);
}
@@ -397,19 +292,26 @@ void
vnode_pager_umount(mp)
register struct mount *mp;
{
- register vm_pager_t pager, npager;
- struct vnode *vp;
+ struct vnode *vp, *nvp;
+
+loop:
+ for (vp = mp->mnt_vnodelist.lh_first; vp != NULL; vp = nvp) {
+ /*
+ * Vnode can be reclaimed by getnewvnode() while we
+ * traverse the list.
+ */
+ if (vp->v_mount != mp)
+ goto loop;
- for (pager = vnode_pager_list.tqh_first; pager != NULL; pager = npager) {
/*
* Save the next pointer now since uncaching may terminate the
- * object and render pager invalid
+ * object and render vnode invalid
*/
- npager = pager->pg_list.tqe_next;
- vp = ((vn_pager_t) pager->pg_data)->vnp_vp;
- if (mp == (struct mount *) 0 || vp->v_mount == mp) {
+ nvp = vp->v_mntvnodes.le_next;
+
+ if (vp->v_object != NULL) {
VOP_LOCK(vp);
- (void) vnode_pager_uncache(vp);
+ vnode_pager_uncache(vp);
VOP_UNLOCK(vp);
}
}
@@ -424,46 +326,24 @@ vnode_pager_umount(mp)
* destruction which may initiate paging activity which may necessitate
* re-locking the vnode.
*/
-boolean_t
+void
vnode_pager_uncache(vp)
- register struct vnode *vp;
+ struct vnode *vp;
{
- register vm_object_t object;
- boolean_t uncached;
- vm_pager_t pager;
+ vm_object_t object;
/*
* Not a mapped vnode
*/
object = vp->v_object;
if (object == NULL)
- return (TRUE);
-
- pager = object->pager;
- if (pager == NULL)
- return (TRUE);
-
-#ifdef DEBUG
- if (!VOP_ISLOCKED(vp)) {
- extern int (**nfsv2_vnodeop_p)();
+ return;
- if (vp->v_op != nfsv2_vnodeop_p)
- panic("vnode_pager_uncache: vnode not locked!");
- }
-#endif
- /*
- * Must use vm_object_lookup() as it actually removes the object from
- * the cache list.
- */
- object = vm_object_lookup(pager);
- if (object) {
- uncached = (object->ref_count <= 1);
- VOP_UNLOCK(vp);
- pager_cache(object, FALSE);
- VOP_LOCK(vp);
- } else
- uncached = TRUE;
- return (uncached);
+ vm_object_reference(object);
+ VOP_UNLOCK(vp);
+ pager_cache(object, FALSE);
+ VOP_LOCK(vp);
+ return;
}
@@ -523,15 +403,15 @@ vnode_pager_iodone(bp)
struct buf *bp;
{
bp->b_flags |= B_DONE;
- wakeup((caddr_t) bp);
+ wakeup(bp);
}
/*
* small block file system vnode pager input
*/
int
-vnode_pager_input_smlfs(vnp, m)
- vn_pager_t vnp;
+vnode_pager_input_smlfs(object, m)
+ vm_object_t object;
vm_page_t m;
{
int i;
@@ -540,11 +420,10 @@ vnode_pager_input_smlfs(vnp, m)
struct buf *bp;
vm_offset_t kva;
int fileaddr;
- int block;
vm_offset_t bsize;
int error = 0;
- vp = vnp->vnp_vp;
+ vp = object->handle;
bsize = vp->v_mount->mnt_stat.f_iosize;
@@ -602,7 +481,6 @@ vnode_pager_input_smlfs(vnp, m)
vm_page_set_clean(m, (i * bsize) & (PAGE_SIZE-1), bsize);
bzero((caddr_t) kva + i * bsize, bsize);
}
-nextblock:
}
vm_pager_unmap_page(kva);
pmap_clear_modify(VM_PAGE_TO_PHYS(m));
@@ -618,8 +496,8 @@ nextblock:
* old style vnode pager output routine
*/
int
-vnode_pager_input_old(vnp, m)
- vn_pager_t vnp;
+vnode_pager_input_old(object, m)
+ vm_object_t object;
vm_page_t m;
{
struct uio auio;
@@ -633,12 +511,12 @@ vnode_pager_input_old(vnp, m)
/*
* Return failure if beyond current EOF
*/
- if (m->offset >= vnp->vnp_size) {
+ if (m->offset >= object->un_pager.vnp.vnp_size) {
return VM_PAGER_BAD;
} else {
size = PAGE_SIZE;
- if (m->offset + size > vnp->vnp_size)
- size = vnp->vnp_size - m->offset;
+ if (m->offset + size > object->un_pager.vnp.vnp_size)
+ size = object->un_pager.vnp.vnp_size - m->offset;
/*
* Allocate a kernel virtual address and initialize so that
@@ -656,7 +534,7 @@ vnode_pager_input_old(vnp, m)
auio.uio_resid = size;
auio.uio_procp = (struct proc *) 0;
- error = VOP_READ(vnp->vnp_vp, &auio, 0, curproc->p_ucred);
+ error = VOP_READ(object->handle, &auio, 0, curproc->p_ucred);
if (!error) {
register int count = size - auio.uio_resid;
@@ -676,34 +554,22 @@ vnode_pager_input_old(vnp, m)
* generic vnode pager input routine
*/
int
-vnode_pager_input(vnp, m, count, reqpage)
- register vn_pager_t vnp;
+vnode_pager_getpages(object, m, count, reqpage)
+ vm_object_t object;
vm_page_t *m;
- int count, reqpage;
+ int count;
+ int reqpage;
{
- int i;
vm_offset_t kva, foff;
- int size;
- vm_object_t object;
+ int i, size, bsize, first, firstaddr;
struct vnode *dp, *vp;
- int bsize;
-
- int first, last;
- int firstaddr;
- int block, offset;
int runpg;
int runend;
-
struct buf *bp;
int s;
- int failflag;
-
int error = 0;
- object = m[reqpage]->object; /* all vm_page_t items are in same
- * object */
-
- vp = vnp->vnp_vp;
+ vp = object->handle;
bsize = vp->v_mount->mnt_stat.f_iosize;
/* get the UNDERLYING device for the file with VOP_BMAP() */
@@ -725,7 +591,7 @@ vnode_pager_input(vnp, m, count, reqpage)
}
cnt.v_vnodein++;
cnt.v_vnodepgsin++;
- return vnode_pager_input_old(vnp, m[reqpage]);
+ return vnode_pager_input_old(object, m[reqpage]);
/*
* if the blocksize is smaller than a page size, then use
@@ -742,7 +608,7 @@ vnode_pager_input(vnp, m, count, reqpage)
}
cnt.v_vnodein++;
cnt.v_vnodepgsin++;
- return vnode_pager_input_smlfs(vnp, m[reqpage]);
+ return vnode_pager_input_smlfs(object, m[reqpage]);
}
/*
* if ANY DEV_BSIZE blocks are valid on a large filesystem block
@@ -768,10 +634,9 @@ vnode_pager_input(vnp, m, count, reqpage)
for(first = 0, i = 0; i < count; i = runend) {
firstaddr = vnode_pager_addr(vp, m[i]->offset, &runpg);
if (firstaddr == -1) {
- if( i == reqpage && foff < vnp->vnp_size) {
- printf("vnode_pager_input: unexpected missing page: firstaddr: %d, foff: %d, vnp_size: %d\n",
- firstaddr, foff, vnp->vnp_size);
- panic("vnode_pager_input:...");
+ if (i == reqpage && foff < object->un_pager.vnp.vnp_size) {
+ panic("vnode_pager_putpages: unexpected missing page: firstaddr: %d, foff: %ld, vnp_size: %d",
+ firstaddr, foff, object->un_pager.vnp.vnp_size);
}
vnode_pager_freepage(m[i]);
runend = i + 1;
@@ -779,14 +644,14 @@ vnode_pager_input(vnp, m, count, reqpage)
continue;
}
runend = i + runpg;
- if( runend <= reqpage) {
+ if (runend <= reqpage) {
int j;
- for(j = i; j < runend; j++) {
+ for (j = i; j < runend; j++) {
vnode_pager_freepage(m[j]);
}
} else {
- if( runpg < (count - first)) {
- for(i=first + runpg; i < count; i++)
+ if (runpg < (count - first)) {
+ for (i = first + runpg; i < count; i++)
vnode_pager_freepage(m[i]);
count = first + runpg;
}
@@ -816,8 +681,8 @@ vnode_pager_input(vnp, m, count, reqpage)
* calculate the size of the transfer
*/
size = count * PAGE_SIZE;
- if ((foff + size) > vnp->vnp_size)
- size = vnp->vnp_size - foff;
+ if ((foff + size) > object->un_pager.vnp.vnp_size)
+ size = object->un_pager.vnp.vnp_size - foff;
/*
* round up physical size for real devices
@@ -875,7 +740,6 @@ vnode_pager_input(vnp, m, count, reqpage)
*/
relpbuf(bp);
-finishup:
for (i = 0; i < count; i++) {
pmap_clear_modify(VM_PAGE_TO_PHYS(m[i]));
m[i]->dirty = 0;
@@ -903,7 +767,7 @@ finishup:
}
}
if (error) {
- printf("vnode_pager_input: I/O read error\n");
+ printf("vnode_pager_getpages: I/O read error\n");
}
return (error ? VM_PAGER_ERROR : VM_PAGER_OK);
}
@@ -912,10 +776,11 @@ finishup:
* generic vnode pager output routine
*/
int
-vnode_pager_output(vnp, m, count, rtvals)
- vn_pager_t vnp;
+vnode_pager_putpages(object, m, count, sync, rtvals)
+ vm_object_t object;
vm_page_t *m;
int count;
+ boolean_t sync;
int *rtvals;
{
int i;
@@ -926,12 +791,12 @@ vnode_pager_output(vnp, m, count, rtvals)
struct iovec aiov;
int error;
- vp = vnp->vnp_vp;
+ vp = object->handle;;
for (i = 0; i < count; i++)
rtvals[i] = VM_PAGER_AGAIN;
if ((int) m[0]->offset < 0) {
- printf("vnode_pager_output: attempt to write meta-data!!! -- 0x%x(%x)\n", m[0]->offset, m[0]->dirty);
+ printf("vnode_pager_putpages: attempt to write meta-data!!! -- 0x%x(%x)\n", m[0]->offset, m[0]->dirty);
rtvals[0] = VM_PAGER_BAD;
return VM_PAGER_BAD;
}
@@ -939,9 +804,9 @@ vnode_pager_output(vnp, m, count, rtvals)
maxsize = count * PAGE_SIZE;
ncount = count;
- if (maxsize + m[0]->offset > vnp->vnp_size) {
- if (vnp->vnp_size > m[0]->offset)
- maxsize = vnp->vnp_size - m[0]->offset;
+ if (maxsize + m[0]->offset > object->un_pager.vnp.vnp_size) {
+ if (object->un_pager.vnp.vnp_size > m[0]->offset)
+ maxsize = object->un_pager.vnp.vnp_size - m[0]->offset;
else
maxsize = 0;
ncount = (maxsize + PAGE_SIZE - 1) / PAGE_SIZE;
@@ -950,8 +815,8 @@ vnode_pager_output(vnp, m, count, rtvals)
rtvals[i] = VM_PAGER_BAD;
}
if (ncount == 0) {
- printf("vnode_pager_output: write past end of file: %d, %d\n",
- m[0]->offset, vnp->vnp_size);
+ printf("vnode_pager_putpages: write past end of file: %d, %d\n",
+ m[0]->offset, object->un_pager.vnp.vnp_size);
return rtvals[0];
}
}
@@ -976,10 +841,10 @@ vnode_pager_output(vnp, m, count, rtvals)
cnt.v_vnodepgsout += ncount;
if (error) {
- printf("vnode_pager_output: I/O error %d\n", error);
+ printf("vnode_pager_putpages: I/O error %d\n", error);
}
if (auio.uio_resid) {
- printf("vnode_pager_output: residual I/O %d at %d\n", auio.uio_resid, m[0]->offset);
+ printf("vnode_pager_putpages: residual I/O %d at %d\n", auio.uio_resid, m[0]->offset);
}
for (i = 0; i < count; i++) {
m[i]->busy--;
@@ -987,28 +852,21 @@ vnode_pager_output(vnp, m, count, rtvals)
rtvals[i] = VM_PAGER_OK;
}
if ((m[i]->busy == 0) && (m[i]->flags & PG_WANTED))
- wakeup((caddr_t) m[i]);
+ wakeup(m[i]);
}
return rtvals[0];
}
struct vnode *
-vnode_pager_lock(vm_object_t object) {
-
- for(;object;object=object->shadow) {
- vn_pager_t vnp;
- if( !object->pager || (object->pager->pg_type != PG_VNODE))
+vnode_pager_lock(object)
+ vm_object_t object;
+{
+ for (; object != NULL; object = object->backing_object) {
+ if (object->type != OBJT_VNODE)
continue;
- vnp = (vn_pager_t) object->pager->pg_data;
- VOP_LOCK(vnp->vnp_vp);
- return vnp->vnp_vp;
+ VOP_LOCK(object->handle);
+ return object->handle;
}
- return (struct vnode *)NULL;
+ return NULL;
}
-
-void
-vnode_pager_unlock(struct vnode *vp) {
- VOP_UNLOCK(vp);
-}
-
diff --git a/sys/vm/vnode_pager.h b/sys/vm/vnode_pager.h
index 381af99..b766ac4 100644
--- a/sys/vm/vnode_pager.h
+++ b/sys/vm/vnode_pager.h
@@ -36,22 +36,19 @@
* SUCH DAMAGE.
*
* @(#)vnode_pager.h 8.1 (Berkeley) 6/11/93
- * $Id: vnode_pager.h,v 1.3 1994/08/02 07:55:43 davidg Exp $
+ * $Id: vnode_pager.h,v 1.4 1995/01/09 16:06:02 davidg Exp $
*/
#ifndef _VNODE_PAGER_
#define _VNODE_PAGER_ 1
-/*
- * VNODE pager private data.
- */
-struct vnpager {
- int vnp_flags; /* flags */
- struct vnode *vnp_vp; /* vnode */
- vm_size_t vnp_size; /* vnode current size */
-};
-typedef struct vnpager *vn_pager_t;
-
-#define VN_PAGER_NULL ((vn_pager_t)0)
+#ifdef KERNEL
+vm_object_t vnode_pager_alloc __P((void *, vm_size_t, vm_prot_t, vm_offset_t));
+void vnode_pager_dealloc __P((vm_object_t));
+int vnode_pager_getpages __P((vm_object_t, vm_page_t *, int, int));
+int vnode_pager_putpages __P((vm_object_t, vm_page_t *, int, boolean_t, int *));
+boolean_t vnode_pager_haspage __P((vm_object_t, vm_offset_t, int *, int *));
+struct vnode *vnode_pager_lock __P((vm_object_t));
+#endif
#endif /* _VNODE_PAGER_ */
OpenPOWER on IntegriCloud