git: 45cc8519f590 - main - tslog: Annotate parts of SYSINIT cpu
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
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);
}