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
This commit is contained in:
Colin Percival 2023-05-29 17:29:24 -07:00
parent 2404380aac
commit 45cc8519f5
5 changed files with 24 additions and 3 deletions

View File

@ -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();
}
/*

View File

@ -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();
}
/***************************************************

View File

@ -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

View File

@ -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 @@ vm_ksubmap_init(struct kva_md_info *kmi)
exec_map_entries * exec_map_entry_size + 64 * PAGE_SIZE, false);
kmem_subinit(pipe_map, kernel_map, &minaddr, &maxaddr, maxpipekva,
false);
TSEXIT();
}

View File

@ -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);
}