Skip to content

Commit

Permalink
runtime: fix data race in stackalloc
Browse files Browse the repository at this point in the history
Stack shrinking happens during mark phase,
and it assumes that it owns stackcache in mcache.
Stack cache flushing also happens during mark phase,
and it accesses stackcache's w/o any synchronization.
This leads to stackcache corruption:
http://goperfd.appspot.com/log/309af5571dfd7e1817259b9c9cf9bcf9b2c27610

LGTM=khr
R=khr
CC=golang-codereviews, rsc
https://golang.org/cl/126870043
  • Loading branch information
dvyukov committed Aug 8, 2014
1 parent a83bbc9 commit d6d7170
Showing 1 changed file with 5 additions and 3 deletions.
8 changes: 5 additions & 3 deletions src/pkg/runtime/stack.c
Expand Up @@ -223,9 +223,11 @@ runtime·stackalloc(G *gp, uint32 n)
n2 >>= 1;
}
c = g->m->mcache;
if(c == nil) {
// This can happen in the guts of exitsyscall or
if(c == nil || g->m->gcing || g->m->helpgc) {
// c == nil can happen in the guts of exitsyscall or
// procresize. Just get a stack from the global pool.
// Also don't touch stackcache during gc
// as it's flushed concurrently.
runtime·lock(&stackpoolmu);
x = poolalloc(order);
runtime·unlock(&stackpoolmu);
Expand Down Expand Up @@ -285,7 +287,7 @@ runtime·stackfree(G *gp, void *v, Stktop *top)
}
x = (MLink*)v;
c = g->m->mcache;
if(c == nil) {
if(c == nil || g->m->gcing || g->m->helpgc) {
runtime·lock(&stackpoolmu);
poolfree(x, order);
runtime·unlock(&stackpoolmu);
Expand Down

0 comments on commit d6d7170

Please sign in to comment.