mirror of
https://github.com/golang/go
synced 2024-11-19 09:54:49 -07:00
runtime: don't lock mheap on user goroutine
This is bad for 2 reasons: 1. if the code under lock ever grows stack, it will deadlock as stack growing acquires mheap lock. 2. It currently deadlocks with SetCPUProfileRate: scavenger locks mheap, receives prof signal and tries to lock prof lock; meanwhile SetCPUProfileRate locks prof lock and tries to grow stack (presumably in runtime.unlock->futexwakeup). Boom. Let's assume that it Fixes #8407. LGTM=rsc R=golang-codereviews, rsc CC=golang-codereviews, khr https://golang.org/cl/112640043
This commit is contained in:
parent
0603fbb01c
commit
e91704af27
@ -642,7 +642,6 @@ static FuncVal forcegchelperv = {(void(*)(void))forcegchelper};
|
||||
void
|
||||
runtime·MHeap_Scavenger(void)
|
||||
{
|
||||
MHeap *h;
|
||||
uint64 tick, forcegc, limit;
|
||||
int64 unixnow;
|
||||
int32 k;
|
||||
@ -662,15 +661,12 @@ runtime·MHeap_Scavenger(void)
|
||||
else
|
||||
tick = limit/2;
|
||||
|
||||
h = &runtime·mheap;
|
||||
for(k=0;; k++) {
|
||||
runtime·noteclear(¬e);
|
||||
runtime·notetsleepg(¬e, tick);
|
||||
|
||||
runtime·lock(h);
|
||||
unixnow = runtime·unixnanotime();
|
||||
if(unixnow - mstats.last_gc > forcegc) {
|
||||
runtime·unlock(h);
|
||||
// The scavenger can not block other goroutines,
|
||||
// otherwise deadlock detector can fire spuriously.
|
||||
// GC blocks other goroutines via the runtime·worldsema.
|
||||
@ -680,13 +676,13 @@ runtime·MHeap_Scavenger(void)
|
||||
runtime·notetsleepg(¬e, -1);
|
||||
if(runtime·debug.gctrace > 0)
|
||||
runtime·printf("scvg%d: GC forced\n", k);
|
||||
runtime·lock(h);
|
||||
}
|
||||
runtime·unlock(h);
|
||||
g->m->locks++; // ensure that we are on the same m while filling arguments
|
||||
g->m->scalararg[0] = k;
|
||||
g->m->scalararg[1] = runtime·nanotime();
|
||||
g->m->scalararg[2] = limit;
|
||||
runtime·mcall(scavenge_m);
|
||||
g->m->locks--;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user