summaryrefslogtreecommitdiffstats
path: root/sys/vm/vm_object.c
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2013-04-28 19:38:59 +0000
committerkib <kib@FreeBSD.org>2013-04-28 19:38:59 +0000
commit2f2c1edec8b49b001f43df2df01de504dfd6ed3a (patch)
tree1a58748990918f89c2609e952ac76f14624b7411 /sys/vm/vm_object.c
parentd4d37d6d8889403ad1350f932cbb9421b9b6023d (diff)
downloadFreeBSD-src-2f2c1edec8b49b001f43df2df01de504dfd6ed3a.zip
FreeBSD-src-2f2c1edec8b49b001f43df2df01de504dfd6ed3a.tar.gz
Rework the handling of the tmpfs node backing swap object and tmpfs
vnode v_object to avoid double-buffering. Use the same object both as the backing store for tmpfs node and as the v_object. Besides reducing memory use up to 2x times for situation of mapping files from tmpfs, it also makes tmpfs read and write operations copy twice bytes less. VM subsystem was already slightly adapted to tolerate OBJT_SWAP object as v_object. Now the vm_object_deallocate() is modified to not reinstantiate OBJ_ONEMAPPING flag and help the VFS to correctly handle VV_TEXT flag on the last dereference of the tmpfs backing object. Reviewed by: alc Tested by: pho, bf MFC after: 1 month
Diffstat (limited to 'sys/vm/vm_object.c')
-rw-r--r--sys/vm/vm_object.c24
1 files changed, 23 insertions, 1 deletions
diff --git a/sys/vm/vm_object.c b/sys/vm/vm_object.c
index 1f7cb78..ce81ad5 100644
--- a/sys/vm/vm_object.c
+++ b/sys/vm/vm_object.c
@@ -505,6 +505,7 @@ void
vm_object_deallocate(vm_object_t object)
{
vm_object_t temp;
+ struct vnode *vp;
while (object != NULL) {
VM_OBJECT_WLOCK(object);
@@ -527,15 +528,36 @@ vm_object_deallocate(vm_object_t object)
VM_OBJECT_WUNLOCK(object);
return;
} else if (object->ref_count == 1) {
+ if (object->type == OBJT_SWAP &&
+ (object->flags & OBJ_TMPFS) != 0) {
+ vp = object->un_pager.swp.swp_tmpfs;
+ vhold(vp);
+ VM_OBJECT_WUNLOCK(object);
+ vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
+ vdrop(vp);
+ VM_OBJECT_WLOCK(object);
+ if (object->type == OBJT_DEAD) {
+ VM_OBJECT_WUNLOCK(object);
+ VOP_UNLOCK(vp, 0);
+ return;
+ } else if ((object->flags & OBJ_TMPFS) != 0) {
+ if (object->ref_count == 1)
+ VOP_UNSET_TEXT(vp);
+ VOP_UNLOCK(vp, 0);
+ }
+ }
if (object->shadow_count == 0 &&
object->handle == NULL &&
(object->type == OBJT_DEFAULT ||
- object->type == OBJT_SWAP)) {
+ (object->type == OBJT_SWAP &&
+ (object->flags & OBJ_TMPFS) == 0))) {
vm_object_set_flag(object, OBJ_ONEMAPPING);
} else if ((object->shadow_count == 1) &&
(object->handle == NULL) &&
(object->type == OBJT_DEFAULT ||
object->type == OBJT_SWAP)) {
+ KASSERT((object->flags & OBJ_TMPFS) == 0,
+ ("Shadowed tmpfs v_object"));
vm_object_t robject;
robject = LIST_FIRST(&object->shadow_head);
OpenPOWER on IntegriCloud