Commit 6ee739d7 authored by Dmitriy Vyukov's avatar Dmitriy Vyukov

runtime: fix deadlock detector false negative

The issue was that scvg is assigned *after* the scavenger goroutine is started,
so when the scavenger calls entersyscall() the g==scvg check can fail.
Fixes #5025.

R=golang-dev, iant
CC=golang-dev
https://golang.org/cl/7629045
parent 7f070af5
...@@ -409,6 +409,9 @@ runtime·MHeap_Scavenger(void) ...@@ -409,6 +409,9 @@ runtime·MHeap_Scavenger(void)
bool trace; bool trace;
Note note, *notep; Note note, *notep;
g->issystem = true;
g->isbackground = true;
// If we go two minutes without a garbage collection, force one to run. // If we go two minutes without a garbage collection, force one to run.
forcegc = 2*60*1e9; forcegc = 2*60*1e9;
// If a span goes unused for 5 minutes after a garbage collection, // If a span goes unused for 5 minutes after a garbage collection,
......
...@@ -71,8 +71,6 @@ M* runtime·extram; ...@@ -71,8 +71,6 @@ M* runtime·extram;
int8* runtime·goos; int8* runtime·goos;
int32 runtime·ncpu; int32 runtime·ncpu;
static int32 newprocs; static int32 newprocs;
// Keep trace of scavenger's goroutine for deadlock detection.
static G *scvg;
void runtime·mstart(void); void runtime·mstart(void);
static void runqput(P*, G*); static void runqput(P*, G*);
...@@ -174,8 +172,7 @@ runtime·main(void) ...@@ -174,8 +172,7 @@ runtime·main(void)
runtime·lockOSThread(); runtime·lockOSThread();
if(m != &runtime·m0) if(m != &runtime·m0)
runtime·throw("runtime·main not on m0"); runtime·throw("runtime·main not on m0");
scvg = runtime·newproc1(&scavenger, nil, 0, 0, runtime·main); runtime·newproc1(&scavenger, nil, 0, 0, runtime·main);
scvg->issystem = true;
main·init(); main·init();
runtime·unlockOSThread(); runtime·unlockOSThread();
...@@ -1265,7 +1262,7 @@ void ...@@ -1265,7 +1262,7 @@ void
p = releasep(); p = releasep();
handoffp(p); handoffp(p);
if(g == scvg) // do not consider blocked scavenger for deadlock detection if(g->isbackground) // do not consider blocked scavenger for deadlock detection
inclocked(1); inclocked(1);
runtime·gosave(&g->sched); // re-save for traceback runtime·gosave(&g->sched); // re-save for traceback
} }
...@@ -1297,7 +1294,7 @@ runtime·exitsyscall(void) ...@@ -1297,7 +1294,7 @@ runtime·exitsyscall(void)
return; return;
} }
if(g == scvg) // do not consider blocked scavenger for deadlock detection if(g->isbackground) // do not consider blocked scavenger for deadlock detection
inclocked(-1); inclocked(-1);
// Try to get any other idle P. // Try to get any other idle P.
m->p = nil; m->p = nil;
...@@ -1899,7 +1896,7 @@ checkdead(void) ...@@ -1899,7 +1896,7 @@ checkdead(void)
} }
grunning = 0; grunning = 0;
for(gp = runtime·allg; gp; gp = gp->alllink) { for(gp = runtime·allg; gp; gp = gp->alllink) {
if(gp == scvg) if(gp->isbackground)
continue; continue;
s = gp->status; s = gp->status;
if(s == Gwaiting) if(s == Gwaiting)
......
...@@ -235,8 +235,9 @@ struct G ...@@ -235,8 +235,9 @@ struct G
int8* waitreason; // if status==Gwaiting int8* waitreason; // if status==Gwaiting
G* schedlink; G* schedlink;
bool ispanic; bool ispanic;
bool issystem; bool issystem; // do not output in stack dump
int8 raceignore; // ignore race detection events bool isbackground; // ignore in deadlock detector
int8 raceignore; // ignore race detection events
M* m; // for debuggers, but offset not hard-coded M* m; // for debuggers, but offset not hard-coded
M* lockedm; M* lockedm;
int32 sig; int32 sig;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment