aboutsummaryrefslogtreecommitdiff
path: root/src/pkg/runtime
diff options
context:
space:
mode:
authorDmitriy Vyukov <dvyukov@google.com>2013-03-12 17:21:44 +0400
committerDmitriy Vyukov <dvyukov@google.com>2013-03-12 17:21:44 +0400
commit6ee739d7e9473d772a371e6f774a424bfcbbb0fc (patch)
tree439135a79edbd1e0072cba8857be10e02f0d7fa0 /src/pkg/runtime
parent7f070af515b40fd1e7f1576b2327779df56fb782 (diff)
downloadgo-6ee739d7e9473d772a371e6f774a424bfcbbb0fc.tar.xz
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
Diffstat (limited to 'src/pkg/runtime')
-rw-r--r--src/pkg/runtime/mheap.c3
-rw-r--r--src/pkg/runtime/proc.c11
-rw-r--r--src/pkg/runtime/runtime.h5
3 files changed, 10 insertions, 9 deletions
diff --git a/src/pkg/runtime/mheap.c b/src/pkg/runtime/mheap.c
index f45149d63f..177f406596 100644
--- a/src/pkg/runtime/mheap.c
+++ b/src/pkg/runtime/mheap.c
@@ -409,6 +409,9 @@ runtime·MHeap_Scavenger(void)
bool trace;
Note note, *notep;
+ g->issystem = true;
+ g->isbackground = true;
+
// If we go two minutes without a garbage collection, force one to run.
forcegc = 2*60*1e9;
// If a span goes unused for 5 minutes after a garbage collection,
diff --git a/src/pkg/runtime/proc.c b/src/pkg/runtime/proc.c
index 8429826974..fff270c4fb 100644
--- a/src/pkg/runtime/proc.c
+++ b/src/pkg/runtime/proc.c
@@ -71,8 +71,6 @@ M* runtime·extram;
int8* runtime·goos;
int32 runtime·ncpu;
static int32 newprocs;
-// Keep trace of scavenger's goroutine for deadlock detection.
-static G *scvg;
void runtime·mstart(void);
static void runqput(P*, G*);
@@ -174,8 +172,7 @@ runtime·main(void)
runtime·lockOSThread();
if(m != &runtime·m0)
runtime·throw("runtime·main not on m0");
- scvg = runtime·newproc1(&scavenger, nil, 0, 0, runtime·main);
- scvg->issystem = true;
+ runtime·newproc1(&scavenger, nil, 0, 0, runtime·main);
main·init();
runtime·unlockOSThread();
@@ -1265,7 +1262,7 @@ void
p = releasep();
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);
runtime·gosave(&g->sched); // re-save for traceback
}
@@ -1297,7 +1294,7 @@ runtime·exitsyscall(void)
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);
// Try to get any other idle P.
m->p = nil;
@@ -1899,7 +1896,7 @@ checkdead(void)
}
grunning = 0;
for(gp = runtime·allg; gp; gp = gp->alllink) {
- if(gp == scvg)
+ if(gp->isbackground)
continue;
s = gp->status;
if(s == Gwaiting)
diff --git a/src/pkg/runtime/runtime.h b/src/pkg/runtime/runtime.h
index d9afd5b796..b0276072fd 100644
--- a/src/pkg/runtime/runtime.h
+++ b/src/pkg/runtime/runtime.h
@@ -235,8 +235,9 @@ struct G
int8* waitreason; // if status==Gwaiting
G* schedlink;
bool ispanic;
- bool issystem;
- int8 raceignore; // ignore race detection events
+ bool issystem; // do not output in stack dump
+ bool isbackground; // ignore in deadlock detector
+ int8 raceignore; // ignore race detection events
M* m; // for debuggers, but offset not hard-coded
M* lockedm;
int32 sig;