From 9eded54fa3e7c3d1bc593f83e5c448b908299d0e Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Tue, 11 Nov 2014 16:54:50 -0500 Subject: [PATCH] [dev.garbage] runtime: concurrent mark fixes Add missing write barrier when initializing state for newly created goroutine. Add write barrier for same slot when preempting a goroutine. Disable write barrier during goroutine death, because dopanic does pointer writes. With concurrent mark enabled (not in this CL), all.bash passed once. The second time, TestGoexitCrash-2 failed. LGTM=rlh R=rlh CC=golang-codereviews https://golang.org/cl/167610043 --- src/runtime/mgc0.c | 3 +-- src/runtime/mgc0.go | 2 +- src/runtime/runtime.h | 2 ++ src/runtime/stack.c | 8 ++++++++ src/runtime/sys_x86.c | 1 + 5 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/runtime/mgc0.c b/src/runtime/mgc0.c index 8d87107c744..3c4d1afa56c 100644 --- a/src/runtime/mgc0.c +++ b/src/runtime/mgc0.c @@ -1094,8 +1094,7 @@ shade(byte *b) void runtime·gcmarkwb_m() { - byte **slot, *ptr; - slot = (byte**)g->m->scalararg[0]; + byte *ptr; ptr = (byte*)g->m->scalararg[1]; switch(runtime·gcphase) { diff --git a/src/runtime/mgc0.go b/src/runtime/mgc0.go index 760d2a54537..dc4eec51969 100644 --- a/src/runtime/mgc0.go +++ b/src/runtime/mgc0.go @@ -109,7 +109,7 @@ func writebarrierptr_nostore(dst *uintptr, src uintptr) { } mp := acquirem() - if mp.inwb { + if mp.inwb || mp.dying > 0 { releasem(mp) return } diff --git a/src/runtime/runtime.h b/src/runtime/runtime.h index a4186f4505f..fec224390c9 100644 --- a/src/runtime/runtime.h +++ b/src/runtime/runtime.h @@ -1121,6 +1121,8 @@ void runtime·osyield(void); void runtime·lockOSThread(void); void runtime·unlockOSThread(void); +void runtime·writebarrierptr_nostore(void*, void*); + bool runtime·showframe(Func*, G*); void runtime·printcreatedby(G*); diff --git a/src/runtime/stack.c b/src/runtime/stack.c index fb23cc1c3b8..a4947a53b3e 100644 --- a/src/runtime/stack.c +++ b/src/runtime/stack.c @@ -706,6 +706,14 @@ runtime·newstack(void) runtime·printf("runtime: split stack overflow: %p < %p\n", sp, gp->stack.lo); runtime·throw("runtime: split stack overflow"); } + + if(gp->sched.ctxt != nil) { + // morestack wrote sched.ctxt on its way in here, + // without a write barrier. Run the write barrier now. + // It is not possible to be preempted between then + // and now, so it's okay. + runtime·writebarrierptr_nostore(&gp->sched.ctxt, gp->sched.ctxt); + } if(gp->stackguard0 == (uintptr)StackPreempt) { if(gp == g->m->g0) diff --git a/src/runtime/sys_x86.c b/src/runtime/sys_x86.c index a450b3e5844..edbe47ff454 100644 --- a/src/runtime/sys_x86.c +++ b/src/runtime/sys_x86.c @@ -20,6 +20,7 @@ runtime·gostartcall(Gobuf *gobuf, void (*fn)(void), void *ctxt) gobuf->sp = (uintptr)sp; gobuf->pc = (uintptr)fn; gobuf->ctxt = ctxt; + runtime·writebarrierptr_nostore(&gobuf->ctxt, ctxt); } // Called to rewind context saved during morestack back to beginning of function.