The branch main has been updated by cperciva:

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

commit 45cc8519f5900574826dfd22c851b136023d044e
Author:     Colin Percival <[email protected]>
AuthorDate: 2023-05-30 00:29:24 +0000
Commit:     Colin Percival <[email protected]>
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);
 }
 

Reply via email to