git: 45cc8519f590 - main - tslog: Annotate parts of SYSINIT cpu

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

URL: https://cgit.FreeBSD.org/src/commit/?id=45cc8519f5900574826dfd22c851b136023d044e

commit 45cc8519f5900574826dfd22c851b136023d044e
Author:     Colin Percival <cperciva@FreeBSD.org>
AuthorDate: 2023-05-30 00:29:24 +0000
Commit:     Colin Percival <cperciva@FreeBSD.org>
CommitDate: 2023-06-04 17:16:35 +0000

    tslog: Annotate parts of SYSINIT cpu
    
    Booting an amd64 kernel on Firecracker with 1 CPU and 128 MB of RAM,
    SYSINIT cpu takes roughly 2770 us:
    * 2280 us in vm_ksubmap_init
      * 535 us in kmem_malloc
        * 450 us in pmap_zero_page
      * 1720 us in pmap_growkernel
        * 1620 us in pmap_zero_page
    * 80 us in bufinit
    * 480 us in cpu_setregs
      * 430 us in cpu_setregs calling load_cr0
    
    Much of this is hypervisor overhead: load_cr0 is slow because it traps
    to the hypervisor, and 99% of the time in pmap_zero_page is spent when
    we first touch the page, presumably due to the host Linux kernel
    faulting in backing pages one by one.
    
    Sponsored by:   https://www.patreon.com/cperciva
    Differential Revision:  https://reviews.freebsd.org/D40327
---
 sys/amd64/amd64/machdep.c |  4 ++++
 sys/amd64/amd64/pmap.c    |  7 ++++++-
 sys/kern/vfs_bio.c        |  2 ++
 sys/vm/vm_init.c          |  2 ++
 sys/vm/vm_kern.c          | 12 ++++++++++--
 5 files changed, 24 insertions(+), 3 deletions(-)

diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c
index dfd60777110f..fa3ffe84bfe1 100644
--- a/sys/amd64/amd64/machdep.c
+++ b/sys/amd64/amd64/machdep.c
@@ -326,13 +326,17 @@ cpu_setregs(void)
 {
 	register_t cr0;
 
+	TSENTER();
 	cr0 = rcr0();
 	/*
 	 * CR0_MP, CR0_NE and CR0_TS are also set by npx_probe() for the
 	 * BSP.  See the comments there about why we set them.
 	 */
 	cr0 |= CR0_MP | CR0_NE | CR0_TS | CR0_WP | CR0_AM;
+	TSENTER2("load_cr0");
 	load_cr0(cr0);
+	TSEXIT2("load_cr0");
+	TSEXIT();
 }
 
 /*
diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c
index 657ba67cd619..123811ed573f 100644
--- a/sys/amd64/amd64/pmap.c
+++ b/sys/amd64/amd64/pmap.c
@@ -5049,6 +5049,7 @@ pmap_growkernel(vm_offset_t addr)
 	pdp_entry_t *pdpe;
 	vm_offset_t end;
 
+	TSENTER();
 	mtx_assert(&kernel_map->system_mtx, MA_OWNED);
 
 	/*
@@ -5075,8 +5076,10 @@ pmap_growkernel(vm_offset_t addr)
 	 */
 	if (KERNBASE < addr) {
 		end = KERNBASE + nkpt * NBPDR;
-		if (end == 0)
+		if (end == 0) {
+			TSEXIT();
 			return;
+		}
 	} else {
 		end = kernel_vm_end;
 	}
@@ -5089,6 +5092,7 @@ pmap_growkernel(vm_offset_t addr)
 		 * The grown region is already mapped, so there is
 		 * nothing to do.
 		 */
+		TSEXIT();
 		return;
 	}
 
@@ -5136,6 +5140,7 @@ pmap_growkernel(vm_offset_t addr)
 		kernel_vm_end = end;
 	else
 		nkpt = howmany(end - KERNBASE, NBPDR);
+	TSEXIT();
 }
 
 /***************************************************
diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c
index a76ea26d8859..cf01d2a239ea 100644
--- a/sys/kern/vfs_bio.c
+++ b/sys/kern/vfs_bio.c
@@ -1201,6 +1201,7 @@ bufinit(void)
 	struct buf *bp;
 	int i;
 
+	TSENTER();
 	KASSERT(maxbcachebuf >= MAXBSIZE,
 	    ("maxbcachebuf (%d) must be >= MAXBSIZE (%d)\n", maxbcachebuf,
 	    MAXBSIZE));
@@ -1336,6 +1337,7 @@ bufinit(void)
 	buffreekvacnt = counter_u64_alloc(M_WAITOK);
 	bufdefragcnt = counter_u64_alloc(M_WAITOK);
 	bufkvaspace = counter_u64_alloc(M_WAITOK);
+	TSEXIT();
 }
 
 #ifdef INVARIANTS
diff --git a/sys/vm/vm_init.c b/sys/vm/vm_init.c
index c5a58c7a0ac7..86b1ade64cb6 100644
--- a/sys/vm/vm_init.c
+++ b/sys/vm/vm_init.c
@@ -156,6 +156,7 @@ vm_ksubmap_init(struct kva_md_info *kmi)
 	vm_offset_t minaddr;
 	vm_offset_t maxaddr;
 
+	TSENTER();
 	/*
 	 * Allocate space for system data structures.
 	 * The first available kernel virtual address is in "v".
@@ -252,4 +253,5 @@ again:
 	    exec_map_entries * exec_map_entry_size + 64 * PAGE_SIZE, false);
 	kmem_subinit(pipe_map, kernel_map, &minaddr, &maxaddr, maxpipekva,
 	    false);
+	TSEXIT();
 }
diff --git a/sys/vm/vm_kern.c b/sys/vm/vm_kern.c
index 10fe07cc86da..8b4e69dbebc2 100644
--- a/sys/vm/vm_kern.c
+++ b/sys/vm/vm_kern.c
@@ -451,8 +451,12 @@ kmem_malloc_domain(int domain, vm_size_t size, int flags)
 void *
 kmem_malloc(vm_size_t size, int flags)
 {
+	void * p;
 
-	return (kmem_malloc_domainset(DOMAINSET_RR(), size, flags));
+	TSENTER();
+	p = kmem_malloc_domainset(DOMAINSET_RR(), size, flags);
+	TSEXIT();
+	return (p);
 }
 
 void *
@@ -731,17 +735,21 @@ kva_import(void *unused, vmem_size_t size, int flags, vmem_addr_t *addrp)
 	vm_offset_t addr;
 	int result;
 
+	TSENTER();
 	KASSERT((size % KVA_QUANTUM) == 0,
 	    ("kva_import: Size %jd is not a multiple of %d",
 	    (intmax_t)size, (int)KVA_QUANTUM));
 	addr = vm_map_min(kernel_map);
 	result = vm_map_find(kernel_map, NULL, 0, &addr, size, 0,
 	    VMFS_SUPER_SPACE, VM_PROT_ALL, VM_PROT_ALL, MAP_NOFAULT);
-	if (result != KERN_SUCCESS)
+	if (result != KERN_SUCCESS) {
+		TSEXIT();
                 return (ENOMEM);
+	}
 
 	*addrp = addr;
 
+	TSEXIT();
 	return (0);
 }