From: Michael Anthony Knyszek Date: Tue, 28 Apr 2020 16:40:38 +0000 (+0000) Subject: runtime: flush mcaches to mcentral before reading memstats X-Git-Tag: go1.15beta1~327 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=0ddde4ada2b1aa61310db06b20c936160d3e4567;p=gostls13.git runtime: flush mcaches to mcentral before reading memstats Currently mcaches are flushed to mcentral after a bunch of memstats have already been read. This is not safe (in the sense that it doesn't ensure consisent memstats) since memstats may in general change when mcentral data structures are manipulated. Note that prior to the new mcentral implementation this was not a problem because mcentral operations happened to never modify certain memstats. As of the new mcentral implementation, we might for example persistentalloc when uncaching a span, which would change memstats. This can cause a skew between the value of sys (which currently is calculated before mcaches are flushed) and the value of gc_sys and other_sys. Fix this by moving mcache flushing to the very top of updatememstats. Also leave a comment explaining that this must be done first, in general, because mcentrals make no guarantee that they will not influence memstats (and doing so would be unnecessarily restrictive). Fixes #38712. Change-Id: I15bacb313c54a46e380a945a71bb75db67169c1b Reviewed-on: https://go-review.googlesource.com/c/go/+/230498 Run-TryBot: Michael Knyszek Reviewed-by: Russ Cox --- diff --git a/src/runtime/mstats.go b/src/runtime/mstats.go index f40bccad17..ba508729c5 100644 --- a/src/runtime/mstats.go +++ b/src/runtime/mstats.go @@ -513,6 +513,12 @@ func readGCStats_m(pauses *[]uint64) { //go:nowritebarrier func updatememstats() { + // Flush mcaches to mcentral before doing anything else. + // + // Flushing to the mcentral may in general cause stats to + // change as mcentral data structures are manipulated. + systemstack(flushallmcaches) + memstats.mcache_inuse = uint64(mheap_.cachealloc.inuse) memstats.mspan_inuse = uint64(mheap_.spanalloc.inuse) memstats.sys = memstats.heap_sys + memstats.stacks_sys + memstats.mspan_sys + @@ -537,9 +543,6 @@ func updatememstats() { memstats.by_size[i].nfree = 0 } - // Flush mcache's to mcentral. - systemstack(flushallmcaches) - // Aggregate local stats. cachestats()