From owner-dev-commits-src-all@freebsd.org Mon Apr 19 18:32:24 2021 Return-Path: Delivered-To: dev-commits-src-all@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id D0CCD5FAF23; Mon, 19 Apr 2021 18:32:24 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4FPFm848xwz4j5f; Mon, 19 Apr 2021 18:32:24 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 67CAE2421C; Mon, 19 Apr 2021 18:32:24 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 13JIWOSJ046100; Mon, 19 Apr 2021 18:32:24 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 13JIWOh2046099; Mon, 19 Apr 2021 18:32:24 GMT (envelope-from git) Date: Mon, 19 Apr 2021 18:32:24 GMT Message-Id: <202104191832.13JIWOh2046099@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Konstantin Belousov Subject: git: ecfbddf0cde3 - main - sysctl vm.objects: report backing object and swap use MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: kib X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: ecfbddf0cde3d4151217e3eb2d7c5388a423d397 Auto-Submitted: auto-generated X-BeenThere: dev-commits-src-all@freebsd.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Commit messages for all branches of the src repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 19 Apr 2021 18:32:24 -0000 The branch main has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=ecfbddf0cde3d4151217e3eb2d7c5388a423d397 commit ecfbddf0cde3d4151217e3eb2d7c5388a423d397 Author: Konstantin Belousov AuthorDate: 2021-04-15 09:27:02 +0000 Commit: Konstantin Belousov CommitDate: 2021-04-19 18:32:01 +0000 sysctl vm.objects: report backing object and swap use For anonymous objects, provide a handle kvo_me naming the object, and report the handle of the backing object. This allows userspace to deconstruct the shadow chain. Right now the handle is the address of the object in KVA, but this is not guaranteed. For the same anonymous objects, report the swap space used for actually swapped out pages, in kvo_swapped field. I do not believe that it is useful to report full 64bit counter there, so only uint32_t value is returned, clamped to the max. For kinfo_vmentry, report anonymous object handle backing the entry, so that the shadow chain for the specific mapping can be deconstructed. Reviewed by: markj Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D29771 --- sys/kern/kern_proc.c | 3 +++ sys/sys/user.h | 20 ++++++++++++++++---- sys/vm/swap_pager.c | 23 +++++++++++++++++++++++ sys/vm/swap_pager.h | 1 + sys/vm/vm_object.c | 13 ++++++++++++- 5 files changed, 55 insertions(+), 5 deletions(-) diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c index 817cb9766bbf..33f168836370 100644 --- a/sys/kern/kern_proc.c +++ b/sys/kern/kern_proc.c @@ -2538,6 +2538,9 @@ kern_proc_vmmap_out(struct proc *p, struct sbuf *sb, ssize_t maxlen, int flags) 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 index f882e7dcd699..14471c91572f 100644 --- a/sys/sys/user.h +++ b/sys/sys/user.h @@ -529,12 +529,17 @@ struct kinfo_vmentry { 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 @@ struct kinfo_vmobject { 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.c b/sys/vm/swap_pager.c index 3789a0217252..888df04741b4 100644 --- a/sys/vm/swap_pager.c +++ b/sys/vm/swap_pager.c @@ -1763,6 +1763,29 @@ swp_pager_force_dirty(vm_page_t m) 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/swap_pager.h b/sys/vm/swap_pager.h index 80dca93fbf85..59ca2cc2cfdb 100644 --- a/sys/vm/swap_pager.h +++ b/sys/vm/swap_pager.h @@ -81,6 +81,7 @@ void swap_pager_swap_init(void); 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/vm_object.c b/sys/vm/vm_object.c index 35ea9cc45fae..1f5194464b69 100644 --- a/sys/vm/vm_object.c +++ b/sys/vm/vm_object.c @@ -73,6 +73,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -2524,6 +2525,7 @@ sysctl_vm_object_list(SYSCTL_HANDLER_ARGS) 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 @@ sysctl_vm_object_list(SYSCTL_HANDLER_ARGS) 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);