runtime: add page tracer

This change adds a new GODEBUG flag called pagetrace that writes a
low-overhead trace of how pages of memory are managed by the Go runtime.

The page tracer is kept behind a GOEXPERIMENT flag due to a potential
security risk for setuid binaries.

Change-Id: I6f4a2447d02693c25214400846a5d2832ad6e5c0
Reviewed-on: https://go-review.googlesource.com/c/go/+/444157
Reviewed-by: Austin Clements <austin@google.com>
Reviewed-by: David Chase <drchase@google.com>
Run-TryBot: Michael Knyszek <mknyszek@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
This commit is contained in:
Michael Knyszek 2022-10-19 14:51:15 -04:00
parent 0613418c98
commit e4435cb844
51 changed files with 636 additions and 29 deletions

View file

@ -1306,6 +1306,7 @@ HaveSpan:
// There are a few very limited cirumstances where we won't have a P here.
// It's OK to simply skip scavenging in these cases. Something else will notice
// and pick up the tab.
var now int64
if pp != nil && bytesToScavenge > 0 {
// Measure how long we spent scavenging and add that measurement to the assist
// time so we can track it for the GC CPU limiter.
@ -1321,7 +1322,7 @@ HaveSpan:
})
// Finish up accounting.
now := nanotime()
now = nanotime()
if track {
pp.limiterEvent.stop(limiterEventScavengeAssist, now)
}
@ -1360,6 +1361,7 @@ HaveSpan:
}
memstats.heapStats.release()
pageTraceAlloc(pp, now, base, npages)
return s
}
@ -1535,6 +1537,8 @@ func (h *mheap) grow(npage uintptr) (uintptr, bool) {
// Free the span back into the heap.
func (h *mheap) freeSpan(s *mspan) {
systemstack(func() {
pageTraceFree(getg().m.p.ptr(), 0, s.base(), s.npages)
lock(&h.lock)
if msanenabled {
// Tell msan that this entire span is no longer in use.
@ -1565,6 +1569,8 @@ func (h *mheap) freeSpan(s *mspan) {
//
//go:systemstack
func (h *mheap) freeManual(s *mspan, typ spanAllocType) {
pageTraceFree(getg().m.p.ptr(), 0, s.base(), s.npages)
s.needzero = 1
lock(&h.lock)
h.freeSpanLocked(s, typ)