git: 2404380aac7e - main - tslog: Optionally instrument pmap_zero_page

From: Colin Percival <cperciva_at_FreeBSD.org>
Date: Sun, 04 Jun 2023 17:17:58 UTC
The branch main has been updated by cperciva:

URL: https://cgit.FreeBSD.org/src/commit/?id=2404380aac7eaf8019aa0939224bbce2d561d01f

commit 2404380aac7eaf8019aa0939224bbce2d561d01f
Author:     Colin Percival <cperciva@FreeBSD.org>
AuthorDate: 2023-05-29 23:03:14 +0000
Commit:     Colin Percival <cperciva@FreeBSD.org>
CommitDate: 2023-06-04 17:16:31 +0000

    tslog: Optionally instrument pmap_zero_page
    
    Booting an amd64 kernel on Firecracker with 1 CPU and 128 MB of RAM,
    pmap_zero_page is responsible for 4.6 ms of the 25.0 ms of boot time.
    This is not in fact time spent zeroing pages though; almost all of
    that time is spent in a first-touch penalty, presumably due to the
    host Linux kernel faulting in backing pages one by one.
    
    There's probably a way to improve that by teaching Firecracker to
    fault in all the VM's pages from the start rather than having them
    faulted in one at a time, but that's outside of FreeBSD's control.
    
    This commit adds a TSLOG_PAGEZERO option which enables TSLOG on the
    amd64 pmap_zero_page function; it's a separate option (turned off
    by default even if TSLOG is enabled) since zeroing pages happens
    enough that it can easily fill the TSLOG buffer and prevent other
    timing information from being recorded.
    
    Sponsored by:   https://www.patreon.com/cperciva
    Differential Revision:  https://reviews.freebsd.org/D40326
---
 sys/amd64/amd64/pmap.c | 9 ++++++++-
 sys/conf/NOTES         | 3 +++
 sys/conf/options       | 1 +
 3 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c
index 889311d598d6..657ba67cd619 100644
--- a/sys/amd64/amd64/pmap.c
+++ b/sys/amd64/amd64/pmap.c
@@ -8155,9 +8155,16 @@ pmap_vmspace_copy(pmap_t dst_pmap, pmap_t src_pmap)
 void
 pmap_zero_page(vm_page_t m)
 {
-	vm_offset_t va = PHYS_TO_DMAP(VM_PAGE_TO_PHYS(m));
+	vm_offset_t va;
 
+#ifdef TSLOG_PAGEZERO
+	TSENTER();
+#endif
+	va = PHYS_TO_DMAP(VM_PAGE_TO_PHYS(m));
 	pagezero((void *)va);
+#ifdef TSLOG_PAGEZERO
+	TSEXIT();
+#endif
 }
 
 /*
diff --git a/sys/conf/NOTES b/sys/conf/NOTES
index 8725d11a5434..23ec7b5c45c9 100644
--- a/sys/conf/NOTES
+++ b/sys/conf/NOTES
@@ -615,6 +615,9 @@ options 	NUM_CORE_FILES=5
 # before it is possible to use more sophisticated tools like DTrace.
 # The TSLOGSIZE option controls the size of the (preallocated, fixed
 # length) buffer used for storing these events (default: 262144 records).
+# The TSLOG_PAGEZERO option enables TSLOG of pmap_zero_page; this must be
+# enabled separately since it typically generates too many records to be
+# useful.
 #
 # For security reasons the TSLOG option should not be enabled on systems
 # used in production.
diff --git a/sys/conf/options b/sys/conf/options
index a8b441e320cb..7a34fa0f7333 100644
--- a/sys/conf/options
+++ b/sys/conf/options
@@ -67,6 +67,7 @@ SYSCTL_DEBUG	opt_sysctl.h
 TEXTDUMP_PREFERRED	opt_ddb.h
 TEXTDUMP_VERBOSE	opt_ddb.h
 TSLOG	opt_global.h
+TSLOG_PAGEZERO	opt_global.h
 TSLOGSIZE	opt_global.h
 
 # Miscellaneous options.