[Git][ghc/ghc][wip/tsan/fix-races] 18 commits: Fix thunk update ordering

Ben Gamari (@bgamari) gitlab at gitlab.haskell.org
Fri Dec 15 21:33:28 UTC 2023



Ben Gamari pushed to branch wip/tsan/fix-races at Glasgow Haskell Compiler / GHC


Commits:
14b1038e by Ben Gamari at 2023-12-15T16:16:14-05:00
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.

- - - - -
caad5ba0 by Ben Gamari at 2023-12-15T16:33:20-05:00
rts: Fix data race in threadPaused

This only affects an assertion in the debug RTS and only needs relaxed
ordering.

- - - - -
e2cb4c18 by Ben Gamari at 2023-12-15T16:33:20-05:00
cmm: Introduce MO_RelaxedRead

In hand-written Cmm it can sometimes be necessary to atomically load
from memory deep within an expression (e.g. see the `CHECK_GC` macro).
This MachOp provides a convenient way to do so without breaking the
expression into multiple statements.

- - - - -
5b631155 by Ben Gamari at 2023-12-15T16:33:20-05:00
codeGen: Use relaxed accesses in ticky bumping

- - - - -
94a3885d by Ben Gamari at 2023-12-15T16:33:20-05:00
rts: Fix data race in Interpreter's preemption check

- - - - -
f40022d4 by Ben Gamari at 2023-12-15T16:33:20-05:00
rts: Fix data race in threadStatus#

- - - - -
7f3680a0 by Ben Gamari at 2023-12-15T16:33:20-05:00
base: use atomic write when updating timer manager

- - - - -
3ef7d2b1 by Ben Gamari at 2023-12-15T16:33:21-05:00
Use relaxed atomics to manipulate TSO status fields

- - - - -
9db191b5 by Ben Gamari at 2023-12-15T16:33:21-05:00
rts: Add necessary barriers when manipulating TSO owner

- - - - -
2e248f95 by Ben Gamari at 2023-12-15T16:33:21-05:00
rts: Use `switch` to branch on why_blocked

This is a semantics-preserving refactoring.

- - - - -
df15432e by Ben Gamari at 2023-12-15T16:33:21-05:00
rts: Fix synchronization on thread blocking state

- - - - -
ea3f34cb by Ben Gamari at 2023-12-15T16:33:21-05:00
rts: Use relaxed ordering on dirty/clean info tables updates

When changing the dirty/clean state of a mutable object we needn't have
any particular ordering.

- - - - -
69047711 by Ben Gamari at 2023-12-15T16:33:21-05:00
codeGen: Use relaxed-read in closureInfoPtr

- - - - -
32a4b9a7 by Ben Gamari at 2023-12-15T16:33:21-05:00
STM: Use acquire loads when possible

Full sequential consistency is not needed here.

- - - - -
61a246c9 by Ben Gamari at 2023-12-15T16:33:21-05:00
rts/Messages: Fix data race

- - - - -
1a4e7aef by Ben Gamari at 2023-12-15T16:33:21-05:00
rts/Prof: Fix data race

- - - - -
f1f501f3 by Ben Gamari at 2023-12-15T16:33:21-05:00
rts: Use fence rather than redundant load

Previously we would use an atomic load to ensure acquire ordering.
However, we now have `ACQUIRE_FENCE_ON`, which allows us to express this
more directly.

- - - - -
bf2b3041 by Ben Gamari at 2023-12-15T16:33:21-05:00
rts: Fix data races in profiling timer

- - - - -


30 changed files:

- compiler/GHC/Cmm/Expr.hs
- compiler/GHC/Cmm/Info.hs
- compiler/GHC/Cmm/MachOp.hs
- compiler/GHC/Cmm/Parser.y
- compiler/GHC/Cmm/ThreadSanitizer.hs
- compiler/GHC/CmmToAsm/AArch64/CodeGen.hs
- compiler/GHC/CmmToAsm/PPC/CodeGen.hs
- compiler/GHC/CmmToAsm/Wasm/FromCmm.hs
- compiler/GHC/CmmToAsm/X86/CodeGen.hs
- compiler/GHC/CmmToC.hs
- compiler/GHC/CmmToLlvm/CodeGen.hs
- compiler/GHC/StgToCmm/Bind.hs
- compiler/GHC/StgToCmm/Ticky.hs
- compiler/GHC/StgToCmm/Utils.hs
- libraries/base/src/GHC/Event/Thread.hs
- rts/Apply.cmm
- rts/Compact.cmm
- rts/Exception.cmm
- rts/Heap.c
- rts/HeapStackCheck.cmm
- rts/Interpreter.c
- rts/Messages.c
- rts/PrimOps.cmm
- rts/Proftimer.c
- rts/RaiseAsync.c
- rts/STM.c
- rts/Schedule.c
- rts/StableName.c
- rts/StgMiscClosures.cmm
- rts/StgStartup.cmm


The diff was not included because it is too large.


View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a5d0321143668d95bd74549c541bcddb32dcbc13...bf2b3041accc5df3f3c5a980a1f8e4e10a34a2e1

-- 
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/a5d0321143668d95bd74549c541bcddb32dcbc13...bf2b3041accc5df3f3c5a980a1f8e4e10a34a2e1
You're receiving this email because of your account on gitlab.haskell.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/ghc-commits/attachments/20231215/2bc58ae0/attachment.html>


More information about the ghc-commits mailing list