mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
runtime: ensure mheap lock stack growth invariant is maintained
Currently there's an invariant in the runtime wherein the heap lock
can only be acquired on the system stack, otherwise a self-deadlock
could occur if the stack grows while the lock is held.
This invariant is upheld and documented in a number of situations (e.g.
allocManual, freeManual) but there are other places where the invariant
is either not maintained at all which risks self-deadlock (e.g.
setGCPercent, gcResetMarkState, allocmcache) or is maintained but
undocumented (e.g. gcSweep, readGCStats_m).
This change adds go:systemstack to any function that acquires the heap
lock or adds a systemstack(func() { ... }) around the critical section,
where appropriate. It also documents the invariant on (*mheap).lock
directly and updates repetitive documentation to refer to that comment.
Fixes #32105.
Change-Id: I702b1290709c118b837389c78efde25c51a2cafb
Reviewed-on: https://go-review.googlesource.com/c/go/+/177857
Run-TryBot: Michael Knyszek <mknyszek@google.com>
Reviewed-by: Austin Clements <austin@google.com>
This commit is contained in:
parent
db3255536c
commit
7ed7669c0d
5 changed files with 64 additions and 35 deletions
|
|
@ -83,10 +83,13 @@ type stackfreelist struct {
|
|||
var emptymspan mspan
|
||||
|
||||
func allocmcache() *mcache {
|
||||
lock(&mheap_.lock)
|
||||
c := (*mcache)(mheap_.cachealloc.alloc())
|
||||
c.flushGen = mheap_.sweepgen
|
||||
unlock(&mheap_.lock)
|
||||
var c *mcache
|
||||
systemstack(func() {
|
||||
lock(&mheap_.lock)
|
||||
c = (*mcache)(mheap_.cachealloc.alloc())
|
||||
c.flushGen = mheap_.sweepgen
|
||||
unlock(&mheap_.lock)
|
||||
})
|
||||
for i := range c.alloc {
|
||||
c.alloc[i] = &emptymspan
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue