]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: fix deadlock detector false negative
authorDmitriy Vyukov <dvyukov@google.com>
Tue, 12 Mar 2013 13:21:44 +0000 (17:21 +0400)
committerDmitriy Vyukov <dvyukov@google.com>
Tue, 12 Mar 2013 13:21:44 +0000 (17:21 +0400)
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

src/pkg/runtime/mheap.c
src/pkg/runtime/proc.c
src/pkg/runtime/runtime.h

index f45149d63f1ebd567707909ac3c0970584445d76..177f406596827db2c03f9ff991af1f12ecddfcf7 100644 (file)
@@ -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,
index 8429826974c11331631c408931b50ff3c44add54..fff270c4fb49735db19b0a77c0d2e04201e35604 100644 (file)
@@ -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)
index d9afd5b7967e63204ec128747e1568cc15b17b4d..b0276072fdb48be237838f7733d836f6c4ead0f5 100644 (file)
@@ -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;