diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c --- a/sys/kern/kern_proc.c +++ b/sys/kern/kern_proc.c @@ -2538,6 +2538,9 @@ bzero(kve, sizeof(*kve)); obj = entry->object.vm_object; if (obj != NULL) { + if ((obj->flags & OBJ_ANON) != 0) + kve->kve_obj = (uintptr_t)obj; + for (tobj = obj; tobj != NULL; tobj = tobj->backing_object) { VM_OBJECT_RLOCK(tobj); diff --git a/sys/sys/user.h b/sys/sys/user.h --- a/sys/sys/user.h +++ b/sys/sys/user.h @@ -529,12 +529,17 @@ uint32_t kve_vn_rdev_freebsd11; /* Device id if device. */ uint16_t kve_vn_mode; /* File mode. */ uint16_t kve_status; /* Status flags. */ - uint64_t kve_vn_fsid; /* dev_t of vnode location */ + union { + uint64_t _kve_vn_fsid; /* dev_t of vnode location */ + uint64_t _kve_obj; /* handle of anon obj */ + } kve_type_spec; uint64_t kve_vn_rdev; /* Device id if device. */ int _kve_ispare[8]; /* Space for more stuff. */ /* Truncated before copyout in sysctl */ char kve_path[PATH_MAX]; /* Path to VM obj, if any. */ }; +#define kve_vn_fsid kve_type_spec._kve_vn_fsid +#define kve_obj kve_type_spec._kve_obj /* * The "vm.objects" sysctl provides a list of all VM objects in the system @@ -552,11 +557,18 @@ uint64_t kvo_resident; /* Number of resident pages. */ uint64_t kvo_active; /* Number of active pages. */ uint64_t kvo_inactive; /* Number of inactive pages. */ - uint64_t kvo_vn_fsid; - uint64_t _kvo_qspare[7]; - uint32_t _kvo_ispare[8]; + union { + uint64_t _kvo_vn_fsid; + uint64_t _kvo_backing_obj; /* Handle for the backing obj */ + } kvo_type_spec; /* Type-specific union */ + uint64_t kvo_me; /* Uniq handle for anon obj */ + uint64_t _kvo_qspare[6]; + uint32_t kvo_swapped; /* Number of swapped pages */ + uint32_t _kvo_ispare[7]; char kvo_path[PATH_MAX]; /* Pathname, if any. */ }; +#define kvo_vn_fsid kvo_type_spec._kvo_vn_fsid +#define kvo_backing_obj kvo_type_spec._kvo_backing_obj /* * The KERN_PROC_KSTACK sysctl allows a process to dump the kernel stacks of 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 @@ -81,6 +81,7 @@ int swap_pager_nswapdev(void); int swap_pager_reserve(vm_object_t, vm_pindex_t, vm_size_t); void swap_pager_status(int *total, int *used); +u_long swap_pager_swapped_pages(vm_object_t object); void swapoff_all(void); #endif /* _KERNEL */ 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 @@ -1763,6 +1763,29 @@ vm_page_launder(m); } +u_long +swap_pager_swapped_pages(vm_object_t object) +{ + struct swblk *sb; + vm_pindex_t pi; + u_long res; + int i; + + VM_OBJECT_ASSERT_LOCKED(object); + if (object->type != OBJT_SWAP) + return (0); + + for (res = 0, pi = 0; (sb = SWAP_PCTRIE_LOOKUP_GE( + &object->un_pager.swp.swp_blks, pi)) != NULL; + pi = sb->p + SWAP_META_PAGES) { + for (i = 0; i < SWAP_META_PAGES; i++) { + if (sb->d[i] != SWAPBLK_NONE) + res++; + } + } + return (res); +} + /* * swap_pager_swapoff_object: * 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 @@ -73,6 +73,7 @@ #include #include #include +#include #include #include #include @@ -2524,6 +2525,7 @@ struct vattr va; vm_object_t obj; vm_page_t m; + u_long sp; int count, error; if (req->oldptr == NULL) { @@ -2590,8 +2592,17 @@ freepath = NULL; fullpath = ""; kvo->kvo_type = vm_object_kvme_type(obj, &vp); - if (vp != NULL) + if (vp != NULL) { vref(vp); + } else if ((obj->flags & OBJ_ANON) != 0) { + MPASS(kvo->kvo_type == KVME_TYPE_DEFAULT || + kvo->kvo_type == KVME_TYPE_SWAP); + kvo->kvo_me = (uintptr_t)obj; + /* tmpfs objs are reported as vnodes */ + kvo->kvo_backing_obj = (uintptr_t)obj->backing_object; + sp = swap_pager_swapped_pages(obj); + kvo->kvo_swapped = sp > UINT32_MAX ? UINT32_MAX : sp; + } VM_OBJECT_RUNLOCK(obj); if (vp != NULL) { vn_fullpath(vp, &fullpath, &freepath);