Commit d017f578 authored by Dmitriy Vyukov's avatar Dmitriy Vyukov

runtime: do not preempt race calls

In the crash stack trace race cgocall() calls endcgo(),
this means that m->racecall is wrong.
Indeed this can happen is a goroutine is rescheduled to another M
during race call.
Disable preemption for race calls.
Fixes #6155.

R=golang-dev, rsc, cshapiro
CC=golang-dev
https://golang.org/cl/12866045
parent 21ea5103
...@@ -34,17 +34,23 @@ extern byte enoptrbss[]; ...@@ -34,17 +34,23 @@ extern byte enoptrbss[];
static bool onstack(uintptr argp); static bool onstack(uintptr argp);
// We set m->racecall around all calls into race library to trigger fast path in cgocall.
// Also we increment m->locks to disable preemption and potential rescheduling
// to ensure that we reset m->racecall on the correct m.
uintptr uintptr
runtime·raceinit(void) runtime·raceinit(void)
{ {
uintptr racectx, start, size; uintptr racectx, start, size;
m->racecall = true; m->racecall = true;
m->locks++;
runtimerace·Initialize(&racectx); runtimerace·Initialize(&racectx);
// Round data segment to page boundaries, because it's used in mmap(). // Round data segment to page boundaries, because it's used in mmap().
start = (uintptr)noptrdata & ~(PageSize-1); start = (uintptr)noptrdata & ~(PageSize-1);
size = ROUND((uintptr)enoptrbss - start, PageSize); size = ROUND((uintptr)enoptrbss - start, PageSize);
runtimerace·MapShadow((void*)start, size); runtimerace·MapShadow((void*)start, size);
m->locks--;
m->racecall = false; m->racecall = false;
return racectx; return racectx;
} }
...@@ -53,7 +59,9 @@ void ...@@ -53,7 +59,9 @@ void
runtime·racefini(void) runtime·racefini(void)
{ {
m->racecall = true; m->racecall = true;
m->locks++;
runtimerace·Finalize(); runtimerace·Finalize();
m->locks--;
m->racecall = false; m->racecall = false;
} }
...@@ -61,7 +69,9 @@ void ...@@ -61,7 +69,9 @@ void
runtime·racemapshadow(void *addr, uintptr size) runtime·racemapshadow(void *addr, uintptr size)
{ {
m->racecall = true; m->racecall = true;
m->locks++;
runtimerace·MapShadow(addr, size); runtimerace·MapShadow(addr, size);
m->locks--;
m->racecall = false; m->racecall = false;
} }
...@@ -73,7 +83,9 @@ runtime·racewrite(uintptr addr) ...@@ -73,7 +83,9 @@ runtime·racewrite(uintptr addr)
{ {
if(!onstack(addr)) { if(!onstack(addr)) {
m->racecall = true; m->racecall = true;
m->locks++;
runtimerace·Write(g->racectx, (void*)addr, runtime·getcallerpc(&addr)); runtimerace·Write(g->racectx, (void*)addr, runtime·getcallerpc(&addr));
m->locks--;
m->racecall = false; m->racecall = false;
} }
} }
...@@ -84,7 +96,9 @@ runtime·racewriterange(uintptr addr, uintptr sz) ...@@ -84,7 +96,9 @@ runtime·racewriterange(uintptr addr, uintptr sz)
{ {
if(!onstack(addr)) { if(!onstack(addr)) {
m->racecall = true; m->racecall = true;
m->locks++;
runtimerace·WriteRange(g->racectx, (void*)addr, sz, runtime·getcallerpc(&addr)); runtimerace·WriteRange(g->racectx, (void*)addr, sz, runtime·getcallerpc(&addr));
m->locks--;
m->racecall = false; m->racecall = false;
} }
} }
...@@ -97,7 +111,9 @@ runtime·raceread(uintptr addr) ...@@ -97,7 +111,9 @@ runtime·raceread(uintptr addr)
{ {
if(!onstack(addr)) { if(!onstack(addr)) {
m->racecall = true; m->racecall = true;
m->locks++;
runtimerace·Read(g->racectx, (void*)addr, runtime·getcallerpc(&addr)); runtimerace·Read(g->racectx, (void*)addr, runtime·getcallerpc(&addr));
m->locks--;
m->racecall = false; m->racecall = false;
} }
} }
...@@ -108,7 +124,9 @@ runtime·racereadrange(uintptr addr, uintptr sz) ...@@ -108,7 +124,9 @@ runtime·racereadrange(uintptr addr, uintptr sz)
{ {
if(!onstack(addr)) { if(!onstack(addr)) {
m->racecall = true; m->racecall = true;
m->locks++;
runtimerace·ReadRange(g->racectx, (void*)addr, sz, runtime·getcallerpc(&addr)); runtimerace·ReadRange(g->racectx, (void*)addr, sz, runtime·getcallerpc(&addr));
m->locks--;
m->racecall = false; m->racecall = false;
} }
} }
...@@ -124,7 +142,9 @@ runtime·racefuncenter1(uintptr pc) ...@@ -124,7 +142,9 @@ runtime·racefuncenter1(uintptr pc)
runtime·callers(2, &pc, 1); runtime·callers(2, &pc, 1);
m->racecall = true; m->racecall = true;
m->locks++;
runtimerace·FuncEnter(g->racectx, (void*)pc); runtimerace·FuncEnter(g->racectx, (void*)pc);
m->locks--;
m->racecall = false; m->racecall = false;
} }
...@@ -134,7 +154,9 @@ void ...@@ -134,7 +154,9 @@ void
runtime·racefuncexit(void) runtime·racefuncexit(void)
{ {
m->racecall = true; m->racecall = true;
m->locks++;
runtimerace·FuncExit(g->racectx); runtimerace·FuncExit(g->racectx);
m->locks--;
m->racecall = false; m->racecall = false;
} }
...@@ -145,7 +167,9 @@ runtime·racemalloc(void *p, uintptr sz) ...@@ -145,7 +167,9 @@ runtime·racemalloc(void *p, uintptr sz)
if(m->curg == nil) if(m->curg == nil)
return; return;
m->racecall = true; m->racecall = true;
m->locks++;
runtimerace·Malloc(m->curg->racectx, p, sz, /* unused pc */ 0); runtimerace·Malloc(m->curg->racectx, p, sz, /* unused pc */ 0);
m->locks--;
m->racecall = false; m->racecall = false;
} }
...@@ -153,7 +177,9 @@ void ...@@ -153,7 +177,9 @@ void
runtime·racefree(void *p) runtime·racefree(void *p)
{ {
m->racecall = true; m->racecall = true;
m->locks++;
runtimerace·Free(p); runtimerace·Free(p);
m->locks--;
m->racecall = false; m->racecall = false;
} }
...@@ -163,7 +189,9 @@ runtime·racegostart(void *pc) ...@@ -163,7 +189,9 @@ runtime·racegostart(void *pc)
uintptr racectx; uintptr racectx;
m->racecall = true; m->racecall = true;
m->locks++;
runtimerace·GoStart(g->racectx, &racectx, pc); runtimerace·GoStart(g->racectx, &racectx, pc);
m->locks--;
m->racecall = false; m->racecall = false;
return racectx; return racectx;
} }
...@@ -172,7 +200,9 @@ void ...@@ -172,7 +200,9 @@ void
runtime·racegoend(void) runtime·racegoend(void)
{ {
m->racecall = true; m->racecall = true;
m->locks++;
runtimerace·GoEnd(g->racectx); runtimerace·GoEnd(g->racectx);
m->locks--;
m->racecall = false; m->racecall = false;
} }
...@@ -183,6 +213,7 @@ memoryaccess(void *addr, uintptr callpc, uintptr pc, bool write) ...@@ -183,6 +213,7 @@ memoryaccess(void *addr, uintptr callpc, uintptr pc, bool write)
if(!onstack((uintptr)addr)) { if(!onstack((uintptr)addr)) {
m->racecall = true; m->racecall = true;
m->locks++;
racectx = g->racectx; racectx = g->racectx;
if(callpc) { if(callpc) {
if(callpc == (uintptr)runtime·lessstack) if(callpc == (uintptr)runtime·lessstack)
...@@ -195,6 +226,7 @@ memoryaccess(void *addr, uintptr callpc, uintptr pc, bool write) ...@@ -195,6 +226,7 @@ memoryaccess(void *addr, uintptr callpc, uintptr pc, bool write)
runtimerace·Read(racectx, addr, (void*)pc); runtimerace·Read(racectx, addr, (void*)pc);
if(callpc) if(callpc)
runtimerace·FuncExit(racectx); runtimerace·FuncExit(racectx);
m->locks--;
m->racecall = false; m->racecall = false;
} }
} }
...@@ -218,6 +250,7 @@ rangeaccess(void *addr, uintptr size, uintptr callpc, uintptr pc, bool write) ...@@ -218,6 +250,7 @@ rangeaccess(void *addr, uintptr size, uintptr callpc, uintptr pc, bool write)
if(!onstack((uintptr)addr)) { if(!onstack((uintptr)addr)) {
m->racecall = true; m->racecall = true;
m->locks++;
racectx = g->racectx; racectx = g->racectx;
if(callpc) { if(callpc) {
if(callpc == (uintptr)runtime·lessstack) if(callpc == (uintptr)runtime·lessstack)
...@@ -230,6 +263,7 @@ rangeaccess(void *addr, uintptr size, uintptr callpc, uintptr pc, bool write) ...@@ -230,6 +263,7 @@ rangeaccess(void *addr, uintptr size, uintptr callpc, uintptr pc, bool write)
runtimerace·ReadRange(racectx, addr, size, (void*)pc); runtimerace·ReadRange(racectx, addr, size, (void*)pc);
if(callpc) if(callpc)
runtimerace·FuncExit(racectx); runtimerace·FuncExit(racectx);
m->locks--;
m->racecall = false; m->racecall = false;
} }
} }
...@@ -258,7 +292,9 @@ runtime·raceacquireg(G *gp, void *addr) ...@@ -258,7 +292,9 @@ runtime·raceacquireg(G *gp, void *addr)
if(g->raceignore) if(g->raceignore)
return; return;
m->racecall = true; m->racecall = true;
m->locks++;
runtimerace·Acquire(gp->racectx, addr); runtimerace·Acquire(gp->racectx, addr);
m->locks--;
m->racecall = false; m->racecall = false;
} }
...@@ -274,7 +310,9 @@ runtime·racereleaseg(G *gp, void *addr) ...@@ -274,7 +310,9 @@ runtime·racereleaseg(G *gp, void *addr)
if(g->raceignore) if(g->raceignore)
return; return;
m->racecall = true; m->racecall = true;
m->locks++;
runtimerace·Release(gp->racectx, addr); runtimerace·Release(gp->racectx, addr);
m->locks--;
m->racecall = false; m->racecall = false;
} }
...@@ -290,7 +328,9 @@ runtime·racereleasemergeg(G *gp, void *addr) ...@@ -290,7 +328,9 @@ runtime·racereleasemergeg(G *gp, void *addr)
if(g->raceignore) if(g->raceignore)
return; return;
m->racecall = true; m->racecall = true;
m->locks++;
runtimerace·ReleaseMerge(gp->racectx, addr); runtimerace·ReleaseMerge(gp->racectx, addr);
m->locks--;
m->racecall = false; m->racecall = false;
} }
...@@ -298,7 +338,9 @@ void ...@@ -298,7 +338,9 @@ void
runtime·racefingo(void) runtime·racefingo(void)
{ {
m->racecall = true; m->racecall = true;
m->locks++;
runtimerace·FinalizerGoroutine(g->racectx); runtimerace·FinalizerGoroutine(g->racectx);
m->locks--;
m->racecall = false; m->racecall = false;
} }
......
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