From bfccb623628401de9eaba3f77a5630771ca7309e Mon Sep 17 00:00:00 2001 From: vangyzen Date: Fri, 2 Oct 2015 14:36:41 +0000 Subject: [PATCH] MFC r283924 Provide vnode in memory map info for files on tmpfs When providing memory map information to userland, populate the vnode pointer for tmpfs files. Set the memory mapping to appear as a vnode type, to match FreeBSD 9 behavior. This fixes the use of tmpfs files with the dtrace pid provider, procstat -v, procfs, linprocfs, pmc (pmcstat), and ptrace (PT_VM_ENTRY). Submitted by: Eric Badger (initial revision) Obtained from: Dell Inc. PR: 198431 git-svn-id: svn://svn.freebsd.org/base/stable/10@288499 ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f --- sys/compat/linprocfs/linprocfs.c | 12 ++++-------- sys/dev/hwpmc/hwpmc_mod.c | 6 +++--- sys/fs/procfs/procfs_map.c | 14 ++++++++++---- sys/kern/kern_proc.c | 20 ++++++++++++++++++-- sys/kern/sys_process.c | 2 +- sys/vm/vm_object.c | 12 ++++++++++++ sys/vm/vm_object.h | 1 + 7 files changed, 49 insertions(+), 18 deletions(-) diff --git a/sys/compat/linprocfs/linprocfs.c b/sys/compat/linprocfs/linprocfs.c index 714b864d7..47bb13b41 100644 --- a/sys/compat/linprocfs/linprocfs.c +++ b/sys/compat/linprocfs/linprocfs.c @@ -1042,20 +1042,16 @@ linprocfs_doprocmaps(PFS_FILL_ARGS) ino = 0; if (lobj) { off = IDX_TO_OFF(lobj->size); - if (lobj->type == OBJT_VNODE) { - vp = lobj->handle; - if (vp) - vref(vp); - } - else - vp = NULL; + vp = vm_object_vnode(lobj); + if (vp != NULL) + vref(vp); if (lobj != obj) VM_OBJECT_RUNLOCK(lobj); flags = obj->flags; ref_count = obj->ref_count; shadow_count = obj->shadow_count; VM_OBJECT_RUNLOCK(obj); - if (vp) { + if (vp != NULL) { vn_fullpath(td, vp, &name, &freename); vn_lock(vp, LK_SHARED | LK_RETRY); VOP_GETATTR(vp, &vat, td->td_ucred); diff --git a/sys/dev/hwpmc/hwpmc_mod.c b/sys/dev/hwpmc/hwpmc_mod.c index 9e369fed4..10f9304d3 100644 --- a/sys/dev/hwpmc/hwpmc_mod.c +++ b/sys/dev/hwpmc/hwpmc_mod.c @@ -1660,7 +1660,8 @@ pmc_log_process_mappings(struct pmc_owner *po, struct proc *p) continue; } - if (lobj->type != OBJT_VNODE || lobj->handle == NULL) { + vp = vm_object_vnode(lobj); + if (vp == NULL) { if (lobj != obj) VM_OBJECT_RUNLOCK(lobj); VM_OBJECT_RUNLOCK(obj); @@ -1672,7 +1673,7 @@ pmc_log_process_mappings(struct pmc_owner *po, struct proc *p) * vnode, so we don't emit redundant MAP-IN * directives. */ - if (entry->start == last_end && lobj->handle == last_vp) { + if (entry->start == last_end && vp == last_vp) { last_end = entry->end; if (lobj != obj) VM_OBJECT_RUNLOCK(lobj); @@ -1695,7 +1696,6 @@ pmc_log_process_mappings(struct pmc_owner *po, struct proc *p) last_timestamp = map->timestamp; vm_map_unlock_read(map); - vp = lobj->handle; vref(vp); if (lobj != obj) VM_OBJECT_RUNLOCK(lobj); diff --git a/sys/fs/procfs/procfs_map.c b/sys/fs/procfs/procfs_map.c index eae70229e..b00aac3ac 100644 --- a/sys/fs/procfs/procfs_map.c +++ b/sys/fs/procfs/procfs_map.c @@ -159,11 +159,11 @@ procfs_doprocmap(PFS_FILL_ARGS) freepath = NULL; fullpath = "-"; if (lobj) { + vp = NULL; switch (lobj->type) { default: case OBJT_DEFAULT: type = "default"; - vp = NULL; break; case OBJT_VNODE: type = "vnode"; @@ -171,13 +171,19 @@ procfs_doprocmap(PFS_FILL_ARGS) vref(vp); break; case OBJT_SWAP: - type = "swap"; - vp = NULL; + if ((lobj->flags & OBJ_TMPFS_NODE) != 0) { + type = "vnode"; + if ((lobj->flags & OBJ_TMPFS) != 0) { + vp = lobj->un_pager.swp.swp_tmpfs; + vref(vp); + } + } else { + type = "swap"; + } break; case OBJT_SG: case OBJT_DEVICE: type = "device"; - vp = NULL; break; } if (lobj != obj) diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c index 63ecf0ffe..a8580a5b2 100644 --- a/sys/kern/kern_proc.c +++ b/sys/kern/kern_proc.c @@ -2074,7 +2074,15 @@ sysctl_kern_proc_ovmmap(SYSCTL_HANDLER_ARGS) vref(vp); break; case OBJT_SWAP: - kve->kve_type = KVME_TYPE_SWAP; + if ((lobj->flags & OBJ_TMPFS_NODE) != 0) { + kve->kve_type = KVME_TYPE_VNODE; + if ((lobj->flags & OBJ_TMPFS) != 0) { + vp = lobj->un_pager.swp.swp_tmpfs; + vref(vp); + } + } else { + kve->kve_type = KVME_TYPE_SWAP; + } break; case OBJT_DEVICE: kve->kve_type = KVME_TYPE_DEVICE; @@ -2300,7 +2308,15 @@ kern_proc_vmmap_out(struct proc *p, struct sbuf *sb) vref(vp); break; case OBJT_SWAP: - kve->kve_type = KVME_TYPE_SWAP; + if ((lobj->flags & OBJ_TMPFS_NODE) != 0) { + kve->kve_type = KVME_TYPE_VNODE; + if ((lobj->flags & OBJ_TMPFS) != 0) { + vp = lobj->un_pager.swp.swp_tmpfs; + vref(vp); + } + } else { + kve->kve_type = KVME_TYPE_SWAP; + } break; case OBJT_DEVICE: kve->kve_type = KVME_TYPE_DEVICE; diff --git a/sys/kern/sys_process.c b/sys/kern/sys_process.c index 6ad4694dd..123dd104a 100644 --- a/sys/kern/sys_process.c +++ b/sys/kern/sys_process.c @@ -402,7 +402,7 @@ ptrace_vm_entry(struct thread *td, struct proc *p, struct ptrace_vm_entry *pve) lobj = tobj; pve->pve_offset += tobj->backing_object_offset; } - vp = (lobj->type == OBJT_VNODE) ? lobj->handle : NULL; + vp = vm_object_vnode(lobj); if (vp != NULL) vref(vp); if (lobj != obj) diff --git a/sys/vm/vm_object.c b/sys/vm/vm_object.c index 54741baf5..9d0871415 100644 --- a/sys/vm/vm_object.c +++ b/sys/vm/vm_object.c @@ -2270,6 +2270,18 @@ vm_object_unwire(vm_object_t object, vm_ooffset_t offset, vm_size_t length, } } +struct vnode * +vm_object_vnode(vm_object_t object) +{ + + VM_OBJECT_ASSERT_LOCKED(object); + if (object->type == OBJT_VNODE) + return (object->handle); + if (object->type == OBJT_SWAP && (object->flags & OBJ_TMPFS) != 0) + return (object->un_pager.swp.swp_tmpfs); + return (NULL); +} + static int sysctl_vm_object_list(SYSCTL_HANDLER_ARGS) { diff --git a/sys/vm/vm_object.h b/sys/vm/vm_object.h index 06111a124..ac8feaecf 100644 --- a/sys/vm/vm_object.h +++ b/sys/vm/vm_object.h @@ -297,6 +297,7 @@ boolean_t vm_object_sync(vm_object_t, vm_ooffset_t, vm_size_t, boolean_t, boolean_t); void vm_object_unwire(vm_object_t object, vm_ooffset_t offset, vm_size_t length, uint8_t queue); +struct vnode *vm_object_vnode(vm_object_t object); #endif /* _KERNEL */ #endif /* _VM_OBJECT_ */ -- 2.45.0