Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F131792515
D30168.id88863.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
23 KB
Referenced Files
None
Subscribers
None
D30168.id88863.diff
View Options
diff --git a/sys/fs/procfs/procfs_map.c b/sys/fs/procfs/procfs_map.c
--- a/sys/fs/procfs/procfs_map.c
+++ b/sys/fs/procfs/procfs_map.c
@@ -166,6 +166,8 @@
vp = lobj->handle;
vref(vp);
break;
+#if 0
+/* XXXKIB */
case OBJT_SWAP_TMPFS:
type = "vnode";
if ((lobj->flags & OBJ_TMPFS) != 0) {
@@ -173,6 +175,7 @@
vref(vp);
}
break;
+#endif
case OBJT_SWAP:
type = "swap";
break;
diff --git a/sys/fs/tmpfs/tmpfs.h b/sys/fs/tmpfs/tmpfs.h
--- a/sys/fs/tmpfs/tmpfs.h
+++ b/sys/fs/tmpfs/tmpfs.h
@@ -45,6 +45,8 @@
MALLOC_DECLARE(M_TMPFSNAME);
#endif
+#define OBJ_TMPFS OBJ_PAGERPRIV /* has tmpfs vnode allocated */
+
/*
* Internal representation of a tmpfs directory entry.
*/
@@ -514,9 +516,11 @@
size_t tmpfs_mem_avail(void);
size_t tmpfs_pages_used(struct tmpfs_mount *tmp);
-void tmpfs_subr_init(void);
+int tmpfs_subr_init(void);
void tmpfs_subr_uninit(void);
+extern int tmpfs_pager_type;
+
/*
* Macros/functions to convert from generic data structures to tmpfs
* specific ones.
diff --git a/sys/fs/tmpfs/tmpfs_subr.c b/sys/fs/tmpfs/tmpfs_subr.c
--- a/sys/fs/tmpfs/tmpfs_subr.c
+++ b/sys/fs/tmpfs/tmpfs_subr.c
@@ -54,6 +54,7 @@
#include <sys/smr.h>
#include <sys/stat.h>
#include <sys/sysctl.h>
+#include <sys/user.h>
#include <sys/vnode.h>
#include <sys/vmmeter.h>
@@ -79,6 +80,61 @@
static uma_zone_t tmpfs_node_pool;
VFS_SMR_DECLARE;
+int tmpfs_pager_type = -1;
+
+static vm_object_t
+tmpfs_pager_alloc(void *handle, vm_ooffset_t size, vm_prot_t prot,
+ vm_ooffset_t offset, struct ucred *cred)
+{
+ vm_object_t object;
+
+ MPASS(handle == NULL);
+ MPASS(offset == 0);
+ object = vm_object_allocate_dyn(tmpfs_pager_type, size,
+ OBJ_COLORED | OBJ_SWAP);
+ if (!swap_pager_init_object(object, NULL, NULL, size, 0)) {
+ vm_object_deallocate(object);
+ object = NULL;
+ }
+ return (object);
+}
+
+static void
+tmpfs_pager_getvp(vm_object_t object, struct vnode **vpp, bool *vp_heldp)
+{
+ struct vnode *vp;
+
+ /*
+ * Tmpfs VREG node, which was reclaimed, has tmpfs_pager_type
+ * type, but not OBJ_TMPFS flag. In this case there is no
+ * v_writecount to adjust.
+ */
+ if (vp_heldp != NULL)
+ VM_OBJECT_RLOCK(object);
+ else
+ VM_OBJECT_ASSERT_LOCKED(object);
+ if ((object->flags & OBJ_TMPFS) != 0) {
+ vp = object->un_pager.swp.swp_tmpfs;
+ if (vp != NULL) {
+ *vpp = vp;
+ if (vp_heldp != NULL) {
+ vhold(vp);
+ *vp_heldp = true;
+ }
+ }
+ }
+ if (vp_heldp != NULL)
+ VM_OBJECT_RUNLOCK(object);
+}
+
+struct pagerops tmpfs_pager_ops = {
+ .pgo_kvme_type = KVME_TYPE_VNODE,
+ .pgo_alloc = tmpfs_pager_alloc,
+ .pgo_set_writeable_dirty = vm_object_set_writeable_dirty_,
+ .pgo_mightbedirty = vm_object_mightbedirty_,
+ .pgo_getvp = tmpfs_pager_getvp,
+};
+
static int
tmpfs_node_ctor(void *mem, int size, void *arg, int flags)
{
@@ -126,18 +182,26 @@
mtx_destroy(&node->tn_interlock);
}
-void
+int
tmpfs_subr_init(void)
{
+ tmpfs_pager_type = vm_pager_alloc_dyn_type(&tmpfs_pager_ops,
+ OBJT_SWAP);
+ if (tmpfs_pager_type == -1)
+ return (EINVAL);
tmpfs_node_pool = uma_zcreate("TMPFS node",
sizeof(struct tmpfs_node), tmpfs_node_ctor, tmpfs_node_dtor,
tmpfs_node_init, tmpfs_node_fini, UMA_ALIGN_PTR, 0);
VFS_SMR_ZONE_SET(tmpfs_node_pool);
+ return (0);
}
void
tmpfs_subr_uninit(void)
{
+ if (tmpfs_pager_type != -1)
+ vm_pager_free_dyn_type(tmpfs_pager_type);
+ tmpfs_pager_type = -1;
uma_zdestroy(tmpfs_node_pool);
}
@@ -364,7 +428,7 @@
case VREG:
obj = nnode->tn_reg.tn_aobj =
- vm_pager_allocate(OBJT_SWAP_TMPFS, NULL, 0,
+ vm_pager_allocate(tmpfs_pager_type, NULL, 0,
VM_PROT_DEFAULT, 0,
NULL /* XXXKIB - tmpfs needs swap reservation */);
/* OBJ_TMPFS is set together with the setting of vp->v_object */
@@ -1588,7 +1652,7 @@
if (vp->v_type != VREG)
return;
obj = vp->v_object;
- KASSERT(obj->type == OBJT_SWAP_TMPFS &&
+ KASSERT(obj->type == tmpfs_pager_type &&
(obj->flags & (OBJ_SWAP | OBJ_TMPFS)) ==
(OBJ_SWAP | OBJ_TMPFS), ("non-tmpfs obj"));
/* unlocked read */
diff --git a/sys/fs/tmpfs/tmpfs_vfsops.c b/sys/fs/tmpfs/tmpfs_vfsops.c
--- a/sys/fs/tmpfs/tmpfs_vfsops.c
+++ b/sys/fs/tmpfs/tmpfs_vfsops.c
@@ -103,8 +103,8 @@
* Handle updates of time from writes to mmaped regions, if allowed.
* Use MNT_VNODE_FOREACH_ALL instead of MNT_VNODE_FOREACH_LAZY, since
* unmap of the tmpfs-backed vnode does not call vinactive(), due to
- * vm object type is OBJT_SWAP. If lazy, only handle delayed update
- * of mtime due to the writes to mapped files.
+ * vm object type is basically OBJT_SWAP. If lazy, only handle
+ * delayed update of mtime due to the writes to mapped files.
*/
static void
tmpfs_update_mtime(struct mount *mp, bool lazy)
@@ -120,7 +120,7 @@
continue;
}
obj = vp->v_object;
- MPASS(obj->type == OBJT_SWAP_TMPFS);
+ MPASS(obj->type == tmpfs_pager_type);
MPASS((obj->flags & OBJ_TMPFS) != 0);
/*
@@ -225,7 +225,7 @@
(entry->max_protection & VM_PROT_WRITE) == 0)
continue;
object = entry->object.vm_object;
- if (object == NULL || object->type != OBJT_SWAP_TMPFS)
+ if (object == NULL || object->type != tmpfs_pager_type)
continue;
/*
* No need to dig into shadow chain, mapping
@@ -661,7 +661,11 @@
static int
tmpfs_init(struct vfsconf *conf)
{
- tmpfs_subr_init();
+ int res;
+
+ res = tmpfs_subr_init();
+ if (res != 0)
+ return (res);
memcpy(&tmpfs_fnops, &vnops, sizeof(struct fileops));
tmpfs_fnops.fo_close = tmpfs_fo_close;
return (0);
diff --git a/sys/fs/tmpfs/tmpfs_vnops.c b/sys/fs/tmpfs/tmpfs_vnops.c
--- a/sys/fs/tmpfs/tmpfs_vnops.c
+++ b/sys/fs/tmpfs/tmpfs_vnops.c
@@ -623,7 +623,7 @@
if (object == NULL)
goto out_smr;
- MPASS(object->type == OBJT_SWAP_TMPFS);
+ MPASS(object->type == tmpfs_pager_type);
MPASS((object->flags & (OBJ_ANON | OBJ_DEAD | OBJ_SWAP)) ==
OBJ_SWAP);
if (!VN_IS_DOOMED(vp)) {
diff --git a/sys/vm/default_pager.c b/sys/vm/default_pager.c
--- a/sys/vm/default_pager.c
+++ b/sys/vm/default_pager.c
@@ -40,6 +40,7 @@
#include <sys/proc.h>
#include <sys/resourcevar.h>
#include <sys/rwlock.h>
+#include <sys/user.h>
#include <vm/vm.h>
#include <vm/vm_object.h>
@@ -71,6 +72,7 @@
* object is converted to swap pager type.
*/
const struct pagerops defaultpagerops = {
+ .pgo_kvme_type = KVME_TYPE_DEFAULT,
.pgo_alloc = default_pager_alloc,
.pgo_dealloc = default_pager_dealloc,
.pgo_getpages = default_pager_getpages,
diff --git a/sys/vm/device_pager.c b/sys/vm/device_pager.c
--- a/sys/vm/device_pager.c
+++ b/sys/vm/device_pager.c
@@ -48,6 +48,7 @@
#include <sys/mman.h>
#include <sys/rwlock.h>
#include <sys/sx.h>
+#include <sys/user.h>
#include <sys/vmmeter.h>
#include <vm/vm.h>
@@ -75,6 +76,7 @@
static struct mtx dev_pager_mtx;
const struct pagerops devicepagerops = {
+ .pgo_kvme_type = KVME_TYPE_DEVICE,
.pgo_init = dev_pager_init,
.pgo_alloc = dev_pager_alloc,
.pgo_dealloc = dev_pager_dealloc,
@@ -84,6 +86,7 @@
};
const struct pagerops mgtdevicepagerops = {
+ .pgo_kvme_type = KVME_TYPE_MGTDEVICE,
.pgo_alloc = dev_pager_alloc,
.pgo_dealloc = dev_pager_dealloc,
.pgo_getpages = dev_pager_getpages,
diff --git a/sys/vm/phys_pager.c b/sys/vm/phys_pager.c
--- a/sys/vm/phys_pager.c
+++ b/sys/vm/phys_pager.c
@@ -38,6 +38,7 @@
#include <sys/mman.h>
#include <sys/rwlock.h>
#include <sys/sysctl.h>
+#include <sys/user.h>
#include <vm/vm.h>
#include <vm/vm_param.h>
@@ -299,6 +300,7 @@
}
const struct pagerops physpagerops = {
+ .pgo_kvme_type = KVME_TYPE_PHYS,
.pgo_init = phys_pager_init,
.pgo_alloc = phys_pager_alloc,
.pgo_dealloc = phys_pager_dealloc,
diff --git a/sys/vm/sg_pager.c b/sys/vm/sg_pager.c
--- a/sys/vm/sg_pager.c
+++ b/sys/vm/sg_pager.c
@@ -40,6 +40,7 @@
#include <sys/mutex.h>
#include <sys/rwlock.h>
#include <sys/sglist.h>
+#include <sys/user.h>
#include <sys/vmmeter.h>
#include <vm/vm.h>
@@ -60,6 +61,7 @@
int *);
const struct pagerops sgpagerops = {
+ .pgo_kvme_type = KVME_TYPE_SG,
.pgo_alloc = sg_pager_alloc,
.pgo_dealloc = sg_pager_dealloc,
.pgo_getpages = sg_pager_getpages,
diff --git a/sys/vm/swap_pager.h b/sys/vm/swap_pager.h
--- a/sys/vm/swap_pager.h
+++ b/sys/vm/swap_pager.h
@@ -82,6 +82,7 @@
void swap_pager_status(int *total, int *used);
u_long swap_pager_swapped_pages(vm_object_t object);
void swapoff_all(void);
-
+bool swap_pager_init_object(vm_object_t object, void *handle,
+ struct ucred *cred, vm_ooffset_t size, vm_ooffset_t offset);
#endif /* _KERNEL */
#endif /* _VM_SWAP_PAGER_H_ */
diff --git a/sys/vm/swap_pager.c b/sys/vm/swap_pager.c
--- a/sys/vm/swap_pager.c
+++ b/sys/vm/swap_pager.c
@@ -99,6 +99,7 @@
#include <sys/sysproto.h>
#include <sys/systm.h>
#include <sys/sx.h>
+#include <sys/user.h>
#include <sys/vmmeter.h>
#include <sys/vnode.h>
@@ -418,9 +419,6 @@
static vm_object_t
swap_pager_alloc(void *handle, vm_ooffset_t size,
vm_prot_t prot, vm_ooffset_t offset, struct ucred *);
-static vm_object_t
- swap_tmpfs_pager_alloc(void *handle, vm_ooffset_t size,
- vm_prot_t prot, vm_ooffset_t offset, struct ucred *);
static void swap_pager_dealloc(vm_object_t object);
static int swap_pager_getpages(vm_object_t, vm_page_t *, int, int *,
int *);
@@ -436,12 +434,11 @@
vm_offset_t start, vm_offset_t end);
static void swap_pager_release_writecount(vm_object_t object,
vm_offset_t start, vm_offset_t end);
-static void swap_tmpfs_pager_getvp(vm_object_t object, struct vnode **vpp,
- bool *vp_heldp);
static void swap_pager_freespace(vm_object_t object, vm_pindex_t start,
vm_size_t size);
const struct pagerops swappagerops = {
+ .pgo_kvme_type = KVME_TYPE_SWAP,
.pgo_init = swap_pager_init, /* early system initialization of pager */
.pgo_alloc = swap_pager_alloc, /* allocate an OBJT_SWAP object */
.pgo_dealloc = swap_pager_dealloc, /* deallocate an OBJT_SWAP object */
@@ -455,22 +452,6 @@
.pgo_freespace = swap_pager_freespace,
};
-const struct pagerops swaptmpfspagerops = {
- .pgo_alloc = swap_tmpfs_pager_alloc,
- .pgo_dealloc = swap_pager_dealloc,
- .pgo_getpages = swap_pager_getpages,
- .pgo_getpages_async = swap_pager_getpages_async,
- .pgo_putpages = swap_pager_putpages,
- .pgo_haspage = swap_pager_haspage,
- .pgo_pageunswapped = swap_pager_unswapped,
- .pgo_update_writecount = swap_pager_update_writecount,
- .pgo_release_writecount = swap_pager_release_writecount,
- .pgo_set_writeable_dirty = vm_object_set_writeable_dirty_,
- .pgo_mightbedirty = vm_object_mightbedirty_,
- .pgo_getvp = swap_tmpfs_pager_getvp,
- .pgo_freespace = swap_pager_freespace,
-};
-
/*
* swap_*() routines are externally accessible. swp_*() routines are
* internal.
@@ -678,18 +659,31 @@
"reduce kern.maxswzone.\n");
}
-static vm_object_t
-swap_pager_alloc_init(objtype_t otype, void *handle, struct ucred *cred,
+bool
+swap_pager_init_object(vm_object_t object, void *handle, struct ucred *cred,
vm_ooffset_t size, vm_ooffset_t offset)
{
- vm_object_t object;
-
if (cred != NULL) {
if (!swap_reserve_by_cred(size, cred))
- return (NULL);
+ return (false);
crhold(cred);
}
+ object->un_pager.swp.writemappings = 0;
+ object->handle = handle;
+ if (cred != NULL) {
+ object->cred = cred;
+ object->charge = size;
+ }
+ return (true);
+}
+
+static vm_object_t
+swap_pager_alloc_init(objtype_t otype, void *handle, struct ucred *cred,
+ vm_ooffset_t size, vm_ooffset_t offset)
+{
+ vm_object_t object;
+
/*
* The un_pager.swp.swp_blks trie is initialized by
* vm_object_allocate() to ensure the correct order of
@@ -698,11 +692,9 @@
object = vm_object_allocate(otype, OFF_TO_IDX(offset +
PAGE_MASK + size));
- object->un_pager.swp.writemappings = 0;
- object->handle = handle;
- if (cred != NULL) {
- object->cred = cred;
- object->charge = size;
+ if (!swap_pager_init_object(object, handle, cred, size, offset)) {
+ vm_object_deallocate(object);
+ return (NULL);
}
return (object);
}
@@ -749,18 +741,6 @@
return (object);
}
-static vm_object_t
-swap_tmpfs_pager_alloc(void *handle, vm_ooffset_t size, vm_prot_t prot,
- vm_ooffset_t offset, struct ucred *cred)
-{
- vm_object_t object;
-
- MPASS(handle == NULL);
- object = swap_pager_alloc_init(OBJT_SWAP_TMPFS, handle, cred,
- size, offset);
- return (object);
-}
-
/*
* SWAP_PAGER_DEALLOC() - remove swap metadata from object
*
@@ -3161,31 +3141,3 @@
object->un_pager.swp.writemappings -= (vm_ooffset_t)end - start;
VM_OBJECT_WUNLOCK(object);
}
-
-static void
-swap_tmpfs_pager_getvp(vm_object_t object, struct vnode **vpp, bool *vp_heldp)
-{
- struct vnode *vp;
-
- /*
- * Tmpfs VREG node, which was reclaimed, has OBJT_SWAP_TMPFS
- * type, but not OBJ_TMPFS flag. In this case there is no
- * v_writecount to adjust.
- */
- if (vp_heldp != NULL)
- VM_OBJECT_RLOCK(object);
- else
- VM_OBJECT_ASSERT_LOCKED(object);
- if ((object->flags & OBJ_TMPFS) != 0) {
- vp = object->un_pager.swp.swp_tmpfs;
- if (vp != NULL) {
- *vpp = vp;
- if (vp_heldp != NULL) {
- vhold(vp);
- *vp_heldp = true;
- }
- }
- }
- if (vp_heldp != NULL)
- VM_OBJECT_RUNLOCK(object);
-}
diff --git a/sys/vm/vm.h b/sys/vm/vm.h
--- a/sys/vm/vm.h
+++ b/sys/vm/vm.h
@@ -97,7 +97,7 @@
OBJT_DEAD,
OBJT_SG,
OBJT_MGTDEVICE,
- OBJT_SWAP_TMPFS,
+ OBJT_FIRST_DYN,
};
typedef u_char objtype_t;
diff --git a/sys/vm/vm_object.h b/sys/vm/vm_object.h
--- a/sys/vm/vm_object.h
+++ b/sys/vm/vm_object.h
@@ -207,7 +207,7 @@
#define OBJ_COLORED 0x1000 /* pg_color is defined */
#define OBJ_ONEMAPPING 0x2000 /* One USE (a single, non-forked) mapping flag */
#define OBJ_SHADOWLIST 0x4000 /* Object is on the shadow list. */
-#define OBJ_TMPFS 0x8000 /* has tmpfs vnode allocated */
+#define OBJ_PAGERPRIV 0x8000 /* Pager private */
/*
* Helpers to perform conversion between vm_object page indexes and offsets.
@@ -356,6 +356,7 @@
vm_object_t vm_object_allocate (objtype_t, vm_pindex_t);
vm_object_t vm_object_allocate_anon(vm_pindex_t, vm_object_t, struct ucred *,
vm_size_t);
+vm_object_t vm_object_allocate_dyn(objtype_t, vm_pindex_t, u_short);
boolean_t vm_object_coalesce(vm_object_t, vm_ooffset_t, vm_size_t, vm_size_t,
boolean_t);
void vm_object_collapse (vm_object_t);
diff --git a/sys/vm/vm_object.c b/sys/vm/vm_object.c
--- a/sys/vm/vm_object.c
+++ b/sys/vm/vm_object.c
@@ -330,24 +330,12 @@
{
VM_OBJECT_ASSERT_WLOCKED(object);
- switch (object->type) {
- case OBJT_DEFAULT:
- case OBJT_DEVICE:
- case OBJT_MGTDEVICE:
- case OBJT_PHYS:
- case OBJT_SG:
- case OBJT_SWAP:
- case OBJT_SWAP_TMPFS:
- case OBJT_VNODE:
- if (!TAILQ_EMPTY(&object->memq))
- return (KERN_FAILURE);
- break;
- case OBJT_DEAD:
+
+ if (object->type == OBJT_DEAD)
return (KERN_INVALID_ARGUMENT);
- default:
- panic("vm_object_set_memattr: object %p is of undefined type",
- object);
- }
+ if (!TAILQ_EMPTY(&object->memq))
+ return (KERN_FAILURE);
+
object->memattr = memattr;
return (KERN_SUCCESS);
}
@@ -425,7 +413,6 @@
flags = OBJ_COLORED;
break;
case OBJT_SWAP:
- case OBJT_SWAP_TMPFS:
flags = OBJ_COLORED | OBJ_SWAP;
break;
case OBJT_DEVICE:
@@ -442,7 +429,8 @@
flags = 0;
break;
default:
- panic("vm_object_allocate: type %d is undefined", type);
+ panic("vm_object_allocate: type %d is undefined or dynamic",
+ type);
}
object = (vm_object_t)uma_zalloc(obj_zone, M_WAITOK);
_vm_object_allocate(type, size, flags, object, NULL);
@@ -450,6 +438,18 @@
return (object);
}
+vm_object_t
+vm_object_allocate_dyn(objtype_t dyntype, vm_pindex_t size, u_short flags)
+{
+ vm_object_t object;
+
+ MPASS(dyntype >= OBJT_FIRST_DYN /* && dyntype < nitems(pagertab) */);
+ object = (vm_object_t)uma_zalloc(obj_zone, M_WAITOK);
+ _vm_object_allocate(dyntype, size, flags, object, NULL);
+
+ return (object);
+}
+
/*
* vm_object_allocate_anon:
*
@@ -681,7 +681,8 @@
umtx_shm_object_terminated(object);
temp = object->backing_object;
if (temp != NULL) {
- KASSERT(object->type != OBJT_SWAP_TMPFS,
+ KASSERT(object->type == OBJT_DEFAULT ||
+ object->type == OBJT_SWAP,
("shadowed tmpfs v_object 2 %p", object));
vm_object_backing_remove(object);
}
@@ -962,7 +963,7 @@
#endif
KASSERT(object->cred == NULL || object->type == OBJT_DEFAULT ||
- object->type == OBJT_SWAP || object->type == OBJT_SWAP_TMPFS,
+ (object->flags & OBJ_SWAP) != 0,
("%s: non-swap obj %p has cred", __func__, object));
/*
@@ -2469,41 +2470,6 @@
(void)blockcount_sleep(&obj->busy, NULL, wmesg, PVM);
}
-/*
- * Return the kvme type of the given object.
- * If vpp is not NULL, set it to the object's vm_object_vnode() or NULL.
- */
-int
-vm_object_kvme_type(vm_object_t object, struct vnode **vpp)
-{
-
- VM_OBJECT_ASSERT_LOCKED(object);
- if (vpp != NULL)
- *vpp = vm_object_vnode(object);
- switch (object->type) {
- case OBJT_DEFAULT:
- return (KVME_TYPE_DEFAULT);
- case OBJT_VNODE:
- return (KVME_TYPE_VNODE);
- case OBJT_SWAP:
- return (KVME_TYPE_SWAP);
- case OBJT_SWAP_TMPFS:
- return (KVME_TYPE_VNODE);
- case OBJT_DEVICE:
- return (KVME_TYPE_DEVICE);
- case OBJT_PHYS:
- return (KVME_TYPE_PHYS);
- case OBJT_DEAD:
- return (KVME_TYPE_DEAD);
- case OBJT_SG:
- return (KVME_TYPE_SG);
- case OBJT_MGTDEVICE:
- return (KVME_TYPE_MGTDEVICE);
- default:
- return (KVME_TYPE_UNKNOWN);
- }
-}
-
static int
sysctl_vm_object_list(SYSCTL_HANDLER_ARGS)
{
diff --git a/sys/vm/vm_pageout.c b/sys/vm/vm_pageout.c
--- a/sys/vm/vm_pageout.c
+++ b/sys/vm/vm_pageout.c
@@ -1887,15 +1887,9 @@
if ((entry->eflags & MAP_ENTRY_NEEDS_COPY) != 0 &&
obj->ref_count != 1)
continue;
- switch (obj->type) {
- case OBJT_DEFAULT:
- case OBJT_SWAP:
- case OBJT_SWAP_TMPFS:
- case OBJT_PHYS:
- case OBJT_VNODE:
+ if (obj->type == OBJT_DEFAULT || obj->type == OBJT_PHYS ||
+ obj->type == OBJT_VNODE || (obj->flags & OBJ_SWAP) != 0)
res += obj->resident_page_count;
- break;
- }
}
return (res);
}
diff --git a/sys/vm/vm_pager.h b/sys/vm/vm_pager.h
--- a/sys/vm/vm_pager.h
+++ b/sys/vm/vm_pager.h
@@ -71,6 +71,7 @@
vm_size_t size);
struct pagerops {
+ int pgo_kvme_type;
pgo_init_t *pgo_init; /* Initialize pager. */
pgo_alloc_t *pgo_alloc; /* Allocate pager. */
pgo_dealloc_t *pgo_dealloc; /* Disassociate. */
@@ -248,6 +249,9 @@
method(object, start, size);
}
+int vm_pager_alloc_dyn_type(struct pagerops *ops, int base_type);
+void vm_pager_free_dyn_type(objtype_t type);
+
struct cdev_pager_ops {
int (*cdev_pg_fault)(vm_object_t vm_obj, vm_ooffset_t offset,
int prot, vm_page_t *mres);
diff --git a/sys/vm/vm_pager.c b/sys/vm/vm_pager.c
--- a/sys/vm/vm_pager.c
+++ b/sys/vm/vm_pager.c
@@ -79,6 +79,7 @@
#include <sys/ucred.h>
#include <sys/malloc.h>
#include <sys/rwlock.h>
+#include <sys/user.h>
#include <vm/vm.h>
#include <vm/vm_param.h>
@@ -155,6 +156,7 @@
}
static const struct pagerops deadpagerops = {
+ .pgo_kvme_type = KVME_TYPE_DEAD,
.pgo_alloc = dead_pager_alloc,
.pgo_dealloc = dead_pager_dealloc,
.pgo_getpages = dead_pager_getpages,
@@ -163,7 +165,7 @@
.pgo_getvp = dead_pager_getvp,
};
-const struct pagerops *pagertab[] __read_mostly = {
+const struct pagerops *pagertab[16] __read_mostly = {
[OBJT_DEFAULT] = &defaultpagerops,
[OBJT_SWAP] = &swappagerops,
[OBJT_VNODE] = &vnodepagerops,
@@ -172,20 +174,25 @@
[OBJT_DEAD] = &deadpagerops,
[OBJT_SG] = &sgpagerops,
[OBJT_MGTDEVICE] = &mgtdevicepagerops,
- [OBJT_SWAP_TMPFS] = &swaptmpfspagerops,
};
+static struct mtx pagertab_lock;
void
vm_pager_init(void)
{
const struct pagerops **pgops;
+ int i;
+
+ mtx_init(&pagertab_lock, "dynpag", NULL, MTX_DEF);
/*
* Initialize known pagers
*/
- for (pgops = pagertab; pgops < &pagertab[nitems(pagertab)]; pgops++)
+ for (i = 0; i < OBJT_FIRST_DYN; i++) {
+ pgops = &pagertab[i];
if ((*pgops)->pgo_init != NULL)
(*(*pgops)->pgo_init)();
+ }
}
static int nswbuf_max;
@@ -243,15 +250,9 @@
vm_pager_allocate(objtype_t type, void *handle, vm_ooffset_t size,
vm_prot_t prot, vm_ooffset_t off, struct ucred *cred)
{
- vm_object_t ret;
- const struct pagerops *ops;
+ MPASS(type < nitems(pagertab));
- ops = pagertab[type];
- if (ops)
- ret = (*ops->pgo_alloc)(handle, size, prot, off, cred);
- else
- ret = NULL;
- return (ret);
+ return ((*pagertab[type]->pgo_alloc)(handle, size, prot, off, cred));
}
/*
@@ -262,6 +263,7 @@
{
VM_OBJECT_ASSERT_WLOCKED(object);
+ MPASS(object->type < nitems(pagertab));
(*pagertab[object->type]->pgo_dealloc) (object);
}
@@ -313,6 +315,7 @@
#endif
int r;
+ MPASS(object->type < nitems(pagertab));
vm_pager_assert_in(object, m, count);
r = (*pagertab[object->type]->pgo_getpages)(object, m, count, rbehind,
@@ -346,6 +349,7 @@
int *rbehind, int *rahead, pgo_getpages_iodone_t iodone, void *arg)
{
+ MPASS(object->type < nitems(pagertab));
vm_pager_assert_in(object, m, count);
return ((*pagertab[object->type]->pgo_getpages_async)(object, m,
@@ -383,6 +387,60 @@
return (object);
}
+int
+vm_pager_alloc_dyn_type(struct pagerops *ops, int base_type)
+{
+ int res;
+
+ mtx_lock(&pagertab_lock);
+ MPASS(base_type == -1 ||
+ (base_type >= OBJT_DEFAULT && base_type < nitems(pagertab)));
+ for (res = OBJT_FIRST_DYN; res < nitems(pagertab); res++) {
+ if (pagertab[res] == NULL)
+ break;
+ }
+ if (res == nitems(pagertab)) {
+ mtx_unlock(&pagertab_lock);
+ return (-1);
+ }
+ if (base_type != -1) {
+ MPASS(pagertab[base_type] != NULL);
+#define FIX(n) \
+ if (ops->pgo_##n == NULL) \
+ ops->pgo_##n = pagertab[base_type]->pgo_##n
+ FIX(init);
+ FIX(alloc);
+ FIX(dealloc);
+ FIX(getpages);
+ FIX(getpages_async);
+ FIX(putpages);
+ FIX(haspage);
+ FIX(populate);
+ FIX(pageunswapped);
+ FIX(update_writecount);
+ FIX(release_writecount);
+ FIX(set_writeable_dirty);
+ FIX(mightbedirty);
+ FIX(getvp);
+ FIX(freespace);
+#undef FIX
+ }
+ pagertab[res] = ops; /* XXXKIB should be rel, but acq is too much */
+ mtx_unlock(&pagertab_lock);
+ return (res);
+}
+
+void
+vm_pager_free_dyn_type(objtype_t type)
+{
+ MPASS(type >= OBJT_FIRST_DYN && type < nitems(pagertab));
+
+ mtx_lock(&pagertab_lock);
+ MPASS(pagertab[type] != NULL);
+ pagertab[type] = NULL;
+ mtx_unlock(&pagertab_lock);
+}
+
static int
pbuf_ctor(void *mem, int size, void *arg, int flags)
{
@@ -515,6 +573,8 @@
{
pgo_set_writeable_dirty_t *method;
+ MPASS(object->type < nitems(pagertab));
+
method = pagertab[object->type]->pgo_set_writeable_dirty;
if (method != NULL)
method(object);
@@ -525,8 +585,25 @@
{
pgo_mightbedirty_t *method;
+ MPASS(object->type < nitems(pagertab));
+
method = pagertab[object->type]->pgo_mightbedirty;
if (method == NULL)
return (false);
return (method(object));
}
+
+/*
+ * Return the kvme type of the given object.
+ * If vpp is not NULL, set it to the object's vm_object_vnode() or NULL.
+ */
+int
+vm_object_kvme_type(vm_object_t object, struct vnode **vpp)
+{
+ VM_OBJECT_ASSERT_LOCKED(object);
+ MPASS(object->type < nitems(pagertab));
+
+ if (vpp != NULL)
+ *vpp = vm_object_vnode(object);
+ return (pagertab[object->type]->pgo_kvme_type);
+}
diff --git a/sys/vm/vnode_pager.c b/sys/vm/vnode_pager.c
--- a/sys/vm/vnode_pager.c
+++ b/sys/vm/vnode_pager.c
@@ -74,6 +74,7 @@
#include <sys/rwlock.h>
#include <sys/sf_buf.h>
#include <sys/domainset.h>
+#include <sys/user.h>
#include <machine/atomic.h>
@@ -108,6 +109,7 @@
static void vnode_pager_getvp(vm_object_t, struct vnode **, bool *);
const struct pagerops vnodepagerops = {
+ .pgo_kvme_type = KVME_TYPE_VNODE,
.pgo_alloc = vnode_pager_alloc,
.pgo_dealloc = vnode_pager_dealloc,
.pgo_getpages = vnode_pager_getpages,
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Oct 12, 5:08 AM (55 s ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
23609734
Default Alt Text
D30168.id88863.diff (23 KB)
Attached To
Mode
D30168: Add KPI to dynamically register pager type
Attached
Detach File
Event Timeline
Log In to Comment