Fix thunk update ordering
Previously we attempted to ensure soundness of concurrent thunk update by synchronizing on the access of the thunk's info table pointer field. This was believed to be sufficient since the indirectee (which may expose a closure allocated by another core) would not be examined until the info table pointer update is complete. However, it turns out that this can result in data races in the presence of multiple threads racing a update a single thunk. For instance, consider this interleaving under the old scheme: Thread A Thread B --------- --------- t=0 Enter t 1 Push update frame 2 Begin evaluation 4 Pause thread 5 t.indirectee=tso 6 Release t.info=BLACKHOLE 7 ... (e.g. GC) 8 Resume thread 9 Finish evaluation 10 Relaxed t.indirectee=x 11 Load t.info 12 Acquire fence 13 Inspect t.indirectee 14 Release t.info=BLACKHOLE Here Thread A enters thunk `t` but is soon paused, resulting in `t` being lazily blackholed at t=6. Then, at t=10 Thread A finishes evaluation and updates `t.indirectee` with a relaxed store. Meanwhile, Thread B enters the blackhole. Under the old scheme this would introduce an acquire-fence but this would only synchronize with Thread A at t=6. Consequently, the result of the evaluation, `x`, is not visible to Thread B, introducing a data race. We fix this by treating the `indirectee` field as we do all other mutable fields. This means we must always access this field with acquire-loads and release-stores. See #23185.
parent
8106e695
Pipeline #87729 canceled
Stage: tool-lint
Stage: quick-build
Stage: full-build
Stage: packaging
Stage: testing
Showing
- compiler/GHC/StgToCmm/Bind.hs 12 additions, 4 deletionscompiler/GHC/StgToCmm/Bind.hs
- rts/Apply.cmm 2 additions, 2 deletionsrts/Apply.cmm
- rts/Compact.cmm 1 addition, 1 deletionrts/Compact.cmm
- rts/Heap.c 1 addition, 1 deletionrts/Heap.c
- rts/Interpreter.c 1 addition, 1 deletionrts/Interpreter.c
- rts/Messages.c 1 addition, 4 deletionsrts/Messages.c
- rts/PrimOps.cmm 5 additions, 5 deletionsrts/PrimOps.cmm
- rts/StableName.c 2 additions, 2 deletionsrts/StableName.c
- rts/StgMiscClosures.cmm 17 additions, 14 deletionsrts/StgMiscClosures.cmm
- rts/ThreadPaused.c 1 addition, 1 deletionrts/ThreadPaused.c
- rts/Threads.c 3 additions, 3 deletionsrts/Threads.c
- rts/Updates.cmm 1 addition, 1 deletionrts/Updates.cmm
- rts/Updates.h 62 additions, 2 deletionsrts/Updates.h
- rts/include/Cmm.h 18 additions, 5 deletionsrts/include/Cmm.h
- rts/include/rts/TSANUtils.h 2 additions, 0 deletionsrts/include/rts/TSANUtils.h
- rts/include/stg/SMP.h 154 additions, 56 deletionsrts/include/stg/SMP.h
- rts/sm/Evac.c 1 addition, 1 deletionrts/sm/Evac.c
- rts/sm/NonMovingMark.c 4 additions, 3 deletionsrts/sm/NonMovingMark.c
- rts/sm/Storage.c 0 additions, 2 deletionsrts/sm/Storage.c
- utils/genapply/Main.hs 5 additions, 1 deletionutils/genapply/Main.hs
Loading
Please register or sign in to comment